Custom environment variables that is declared once and is available globally can increase the efficiency. Create React App (CRA) provides such a mechanism with react-scripts@0.2.3
and higher.
Some of the commonly used scenario for environment variables:
CRA provides a way to to declare environment variables. Generally it's done using .env
files. One can create several environment variable files like .env.staging
, .env.production
.
The environment variable should be declared in a special way. It has to be named by using a special prefix REACT_APP_
.
These environment variables will be defined for us on process.env
.
REACT_APP_API_BASE_URL = https://mysite.stage.com/myappname/
The above variable can be accessed anywhere using process.env.REACT_APP_API_BASE_URL
Apart from custom environment variable, by default,
NODE_ENV
variable is defined for us. It is a built-in environment available which is equal todevelopment
onnpm start
,production
onnpm run build
and so on.
Microsoft has integrated CRA as a React SPA template for .net core web applications. A .net core 5 (also 3.2) web app with React can be created by both cli (dotnet new react app-name
) or using Visual Studio.
npm ...
commandsMicrosoft has integrated CRA as a React SPA template in a way that user should not be bothered to use npm commands. A user can just use traditional way of compiling and running any web app in Visual Studio.
However, this has also created some complexity. By default, there is only two configuration i.e., Debug and Production. npm run start for the development and npm run build for the production. What happens if you have a different set of environment variables for the staging but wants to have a build or production output?
At least on Visual Studio 2019, I could not find a straight forward solution. However, good thing is that it can be done.
npm command for the development and production is defined in project file .csproj file.
<Target Name="PublishStagingRunWebpack" AfterTargets="ComputeFilesToPublish" Condition=" '$(Configuration)' == 'Staging' ">
<!-- As part of publishing, ensure the JS resources are freshly built in production mode -->
<Exec WorkingDirectory="$(SpaRoot)" Command="npm install" />
<Exec WorkingDirectory="$(SpaRoot)" Command="npm run staging" />
<!-- Include the newly-built files in the publish output -->
<ItemGroup>
<None Include="appsettings.Staging.json" CopyToOutputDirectory="Always" CopyToPublishDirectory="Always" />
<None Include="appsettings.json" CopyToOutputDirectory="Never" CopyToPublishDirectory="Never" />
<DistFiles Include="$(SpaRoot)build\**" />
<ResolvedFileToPublish Include="@(DistFiles->'%(FullPath)')" Exclude="@(ResolvedFileToPublish)">
<RelativePath>%(DistFiles.Identity)</RelativePath>
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
<ExcludeFromSingleFile>true</ExcludeFromSingleFile>
</ResolvedFileToPublish>
</ItemGroup>
</Target>
Target Name="PublishStagingRunWebpack" AfterTargets="ComputeFilesToPublish" Condition=" '$(Configuration)' == 'Staging' ">
Here we compare with our newly created Staging configuration.
5.2 <Exec WorkingDirectory="$(SpaRoot)" Command="npm run staging" />
Yes, we need to add npm run staging
which basically gives us a build/production bundle. <Target Name="PublishRunWebpack" AfterTargets="ComputeFilesToPublish" Condition=" '$(Configuration)' == 'Release' ">
env-cmd
npm packagenpm i env-cmd --save
Go to package.json and add the following under "scripts"
property (where there is already start, build, test, etc):
"staging": "env-cmd -f .env.staging react-scripts build",
Basically, it instructs web-pack to read environment variables from .env.staging file and run a 'npm run build' command.
For default build, no need to use env-cmd as npm run build default environment file would be .env.production
Now, to publish a staging build, we just have to change our configuratin to Staging and just publish. It will use the specified environment variable file and specified commands from the package.json.
Read more about CRA custom environment variables.
Another .net core React SPA template