如何在Azure托管的React应用中使用环境变量

时间:2018-07-12 19:42:21

标签: reactjs azure azure-devops

我对React还是很陌生,并且通常也探索Azure。 我有一个ERP背景,但这个背景确实包括使用诸如VSTS和CI / CD之类的工具。 我非常依赖使用VSTS中的“库”来指定每个环境的变量,然后在部署时指定它们。

但是!我一直在互联网上阅读和使用设置,但是据我所知,我只能将参数“嵌入” NPM生成的实际代码中。这基本上意味着我需要为每个环境创建一个单独的构建,这是我不习惯的。我一直很坚强(并告诉其他人),您要交付生产的产品应该与预生产,登台或...上的产品完全相同。真的没有其他方法可以使用环境变量吗?我当时在考虑使用Azure App Service中的“应用程序设置”,但是我什至无法使它们在控制台中弹出。 VSTS中的库也没有找到如何在我的部署中使用它们,因为只有一步之遥。

阅读https://github.com/facebook/create-react-app/blob/master/packages/react-scripts/template/README.md#adding-custom-environment-variables上的文档也不会让我感到不舒服,也无法将.env文件放入源代码管理中。我什至尝试了推杆的方法 {process.env.NODE_ENV} 在我的代码中,但是在Azure中,它只是显示为“开发”,而我什至不执行npm运行build(应该是生产版本)...

所以,我在这里迷路了!如何在React应用程序中使用Azure App Service中指定的环境变量?

谢谢!

9 个答案:

答案 0 :(得分:3)

好的选择

我也遇到了这个问题,您可以通过对环境使用不同的构建脚本来自定义使用哪些环境变量。 找到了此CRA文档 https://create-react-app.dev/docs/deployment/#customizing-environment-variables-for-arbitrary-build-environments

您还可以在YAML中设置变量。 https://docs.microsoft.com/en-us/azure/devops/pipelines/process/variables?view=azure-devops&tabs=yaml%2Cbatch#set-variables-in-pipeline

但是,如果我需要一个单独的版本怎么办?

如果您针对不同的环境(开发,登台,生产)使用单个构建和发布阶段,那么我还没有解决这个问题。由于一切都已构建,React具有您在构建时提供的任何env变量。我考虑过的替代方案:

  1. 将React构建与.NET构建分开,以便您可以像每次部署一样执行
  2. 定义所有env变量并附加例如REACT_APP_SOME_KEY_,然后基于子域选择特定的env,例如https://dev.yoursite.com https://yoursite.com,但是此选项似乎不规范。
  3. 可能是React需要针对每个环境构建的限制。接受您需要单独的版本。

答案 1 :(得分:2)

直接添加尊者来构建管道变量。这将添加到Azure环境变量,应用程序可以使用它 enter image description here

答案 2 :(得分:2)

所有提议的解决方案都太复杂了,因为其他人已经在打包和构建过程中解决了这个问题。

要将其部署到 azure,必须完成两件事。首先删除排除 .env* 文件的 .ignore 规则。注意:假设你没有把秘密放在这里! 无论如何,.env 文件中的大部分配置在身份验证流程中都是在线可见的。那么,为什么要对 git 中的这个文件感到恐慌呢?特别是在私人 Git 中,我看不到那些 .env 文件有任何问题。

所以,我有 .env.dev 和 .env.prod ... 这包含例如

REACT_APP_AUTH_URL=https://auth.myid4.info
REACT_APP_ISSUER=https://auth.myid4.info
REACT_APP_IDENTITY_CLIENT_ID=myclientid
REACT_APP_REDIRECT_URL=https://myapp.info/signin-oidc
REACT_APP_AUDIENCE=
REACT_APP_SCOPE=openid profile email roles mysuperapi
REACT_APP_SILENT_REDIRECT_URL=https://myapp.info/silent-renew
REACT_APP_LOGOFF_REDIRECT_URL=https://myapp.info/logout
API_URL=/

必须做到以下几点。 npm i --save-dev env-cmd

现在,像这样在 package.json 中修改。您可能还有其他一些,但本质上,只需为您的环境添加正确的 .env

env-cmd -f .env.prod

所以在我的情况下在 package.json

"start": "env-cmd -f .env.dev rimraf ./build && react-scripts start",
"build": "env-cmd -f .env.prod react-scripts build"

现在,我将 React JS 部署到 azure。我使用,仅供参考,.NET Core Spa 功能。

答案 3 :(得分:0)

这并不是您要寻找的,但这也许是您解决问题的另一种方法(它在构建步骤中将process-env.x替换为实际值):

https://github.com/babel/minify/tree/master/packages/babel-plugin-transform-inline-environment-variables

答案 4 :(得分:0)

仅当您使用Azure DevOps时,此路由才适用。

  • Azure DevOps在管道中有一个名为“库”的部分。
  • 创建一个新的变量组并添加环境变量。
  • 将上次创建变量组与构建过程相关联。

还请记住以REACT_APP_开头的环境变量名称

答案 5 :(得分:0)

使用VSTS部署到Azure时,可以在构建管道中提供环境变量,该变量将自动将其包含在ReactJS项目中。 enter image description here

答案 6 :(得分:0)

现在到2019年底,我仍然面临着nodeJs和azure devops中的env变量的问题。

我没有找到解决方案,但是我使用了一种解决方法。我使用伪“ env var”。

我创建了"env.json"文件,其结构与项目根目录中的".env"文件相同。将此文件放入".gitignore"文件中。将此文件显式导入到需要使用env var的文件中。将其用作常规对象,而不是process.env。***

示例:

我们有一个“ .env”,我们需要替换:

REACT_APP_SOMW_KEY=KEY

项目本身的下一步是:

创建"env.json"

{"REACT_APP_SOMW_KEY":"KEY"}

将其添加到".gitignore"

如果使用打字稿,请将以下设置添加到tsconfig.json

 "resolveJsonModule": true,

process.env.REACT_APP_SOMW_KEY所在的文件中,将process.env.REACT_APP_SOMW_KEY更改为config.REACT_APP_SOMW_KEY,并在开始时将const config = require("../pathTo/env.json")添加为导入模块。

对于打字稿,您还可以创建界面以使其具有自动完成功能:

export interface IEnvConfig{
  REACT_APP_SOMW_KEY?: string;
}   
const config: IEnvConfig = require("../pathTo/env.json");

结果将是这样的:

const reactSomeKey = /*process.env.REACT_APP_SOMW_KEY*/ config.REACT_APP_SOMW_KEY;

Azure DevOps的后续步骤:

将密钥添加到天蓝色的"key vault""variables"

在构建项目步骤之前的CI管道中,您可以设置PowerShell任务,这将创建"env.json"文件。由于我们使用隐藏的".env"文件制作了git clone,因此与在本地创建“ .env”文件相同。 我将yml任务放在这里(最后,您可以看到2条调试命令,只是为了确保该文件已创建并存在于项目中):

- powershell: |
   New-Item -Path $(System.DefaultWorkingDirectory) -Name "env.json" -Force -Value @'
   {
   "REACT_APP_SOMW_KEY": "$(REACT_APP_SOMW_KEY)",
   }
   '@
   Get-Content -Path $(System.DefaultWorkingDirectory)\env.json
   Get-ChildItem -Path $(System.DefaultWorkingDirectory)
  displayName: 'Create "env.json" file'

结果:JSON对象键的流程几乎与".env"相同。您也可以在项目中同时拥有".env""env.json"

答案 7 :(得分:0)

我使用了YAML构建并将变量写入.env文件。我用来在reactjs中进行转换的软件包是dotenv版本8.2.0

这是我的YAML构建文件,其中添加了完成此任务的任务

variables:
- group: myvariablegroup

trigger:
  batch: true
  branches:
    include:
      - develop
      - release/*

pool:
  vmImage: 'ubuntu-latest'

stages:
- stage: dev 
  condition: eq(variables['build.sourceBranch'], 'refs/heads/develop')
  jobs:
  - job: DevelopmentDelpoyment
    steps:

    - task: CmdLine@2
      inputs:
        script: 'echo APP_WEB_API = $(myvariable-dev) > Web/.env' 
      displayName: 'Setting environment variables'


    - script: |
        cd Web
        npm install
        npm run build
      displayName: 'npm install and build'


- stage: prod 
  condition: eq(variables['build.sourceBranch'], 'refs/heads/master')
  jobs:
  - job: ProductionDelpoyment
    steps:

    - task: CmdLine@2
      inputs:
        script: 'echo APP_WEB_API = $(myvariable-prod) > Web/.env' 
      displayName: 'Setting environment variables'

    - script: |
        cd Web
        npm install
        npm run build
      displayName: 'npm install and build'

答案 8 :(得分:-2)

作为更新,它与我的原始方法有所不同,但是我经历了使用DotEnv并因此使用.env文件的方法,该文件将使用库变量在VSTS中即时生成,并且因此不要将它们存储在源代码管理中。

要使用DotEnv,我更新了webpack.config。 const Dotenv = require('dotenv-webpack');

module.exports = {
    ...
    plugins: [
        new Dotenv()
    ],

然后基本上,我创建了一个包含参数的.env文件

  

MD_API_URL = http://localhost:7623/api/

为了能够在我的TSX文件中使用它们,我只使用process.env;

static getCustomer(id) {
    return fetch(process.env.MD_API_URL + 'customers/' + id, { mode: 'cors' })
        .then(response => {
        return response.json();
    }).catch(error => {
        return error;
    });
}