【问题标题】:Pass environment variables to an Angular2 app?将环境变量传递给 Angular2 应用程序?
【发布时间】:2016-07-31 10:36:50
【问题描述】:

我需要将后端 url 传递给我的 Angular2 应用程序,因为生产服务器和开发服务器托管在不同的位置。

我知道我可以将这些内容存储在外部 config.json 中并在启动时加载。但是,在应用启动之前,这似乎是对服务器的不必要的额外调用。

另外,我现在要做的是创建一个全局变量,我根据 build 将其注入 gulp。我的应用不是需要可重用的库我不认为我应该遇到 unexpected 全局名称冲突。但这不是一个好习惯。

我想知道是否有第三种更好的解决方案?

【问题讨论】:

  • IMO,你过度优化了。为了实现一个易于理解的模式(例如从配置文件中加载此类内容),我每次都会采用一个“不必要的”获取。
  • 你可能是对的,尤其是当 Angular 2 投入生产并且生产构建和缩小开始工作得很好时。谢谢。
  • 如果使用 angular-cli,这里描述的简单解决方案:stackoverflow.com/questions/40424199/…
  • 如果您必须构建一次并多次部署相同的构建工件,请参阅stackoverflow.com/a/43980985/2540679

标签: angular environment


【解决方案1】:

环境.ts

如何使用

您在 Angular2+ 中有一个内置系统。
您处理的每个环境都有 environement.ts 文件(您可以根据需要定义)。
每当您需要访问它们时,您都可以像这样导入它

import { environment } from '../environments/environment.ts'

在代码中你可以访问你的变量

environement.varName

如何配置自定义环境.ts

在您的 angular.json 文件中,您可以根据需要创建任意数量的环境,这里是一个示例

"build": 
{ "configurations": 
{ 
"production": { "fileReplacements": [ { "replace": "src/environments/environment.ts", "with": "src/environments/environment.prod.ts" } ], }, 

"qa": { "fileReplacements": [ { "replace": "src/environments/environment.ts", "with": "src/environments/environment.qa.ts" } ] }, 

"staging": { "fileReplacements": [ { "replace": "src/environments/environment.ts", "with": "src/environments/environment.staging.ts" } ] } } }

在构建您的应用程序时,您需要提及您构建的环境的名称。 这里的敌人示例我为 qa 环境构建了一个。

ng build --configuration qa

完成后,您的 dist 输出文件夹应该包含带有 qa 配置的构建输出

【讨论】:

    【解决方案2】:

    不仅是 URL,还有一些其他参数需要从环境变量中获取。

    必须在构建之前获取环境变量并写入environment.ts!由于在运行时访问文件系统、环境等方面存在一些 Javascript 限制。

    为此,首先您需要一个用于编写环境变量的模块,并且该模块必须在您的build 脚本中使用ts-node 执行:

    "scripts": {
      .....
      "config": "ts-node set-env.ts",
      "build": "npm run config && ng build",
      ....
    },
    

    还有你的set-env.ts 文件:

    var fs = require('fs');
    const targetPath = './src/environments/environment.ts';
    const colors = require('colors');
    require('dotenv').load();
    const envConfigFile = `export const environment = {
      ENV_VAR_1: '${process.env.var_1}',
      ENV_VAR_n: '${process.env.var_n}',
    };`;
    console.log(colors.magenta('The content of `environment.ts` will be: \n'));
    console.log(colors.grey(envConfigFile));
    fs.writeFile(targetPath, envConfigFile, function (err) {
      if (err) {
        throw console.error(err);
      } else {
        console.log(colors.magenta(`environment.ts file is created`));
      }
    });
    

    当然,您必须将 ts-nodedotenv 添加到您的依赖项中。

    您可以轻松访问 environemnt.ts 的变量,例如:

    import {environment} from '../environments/environment';
    ....
    var envVar1 = environment.ENV_VAR_1;
    

    Node 12^,Angular 10^,我没有用旧的 Node/Angular/Typescrip 版本检查这个

    【讨论】:

      【解决方案3】:

      在不同的环境中,location.host的值会有所不同。

      使用它作为 key 并从具有所有 URL 的相应 json 加载值。

      相关代码可能如下所示:

      let env = location.host;
      if (env === 'prod.example.com') {
        config = 'ProdConfig.json';
      } else if (env === 'test.example.com') {
        config = 'TestConfig.json';
      } else if (env === 'localhost') {
        config = 'DevConfig.json';
      }
      

      【讨论】:

      • 不是我的情况。假设我正在运行我的本地开发环境。我在本地有 API。但是一位同事没有在本地安装后端(数据库,所有设置,他不需要它) - 他会将后端 URL 指向我们的沙箱 API。这就是为什么我不想从应用程序本身解决这个问题,而是在构建时解决。
      【解决方案4】:

      只需将变量放在环境对象中即可。

      export const environment = {
        production: false,
        url: 'http://localhost:3000/api'
      };
      

      之后,您可以导入并使用它。 Angular Cli 会自动交换文件。

      import { environment } from '../environments/environment';
      

      附:变量在环境对象中可用。

      this.url = environment.url
      

      【讨论】:

      • 这在任何组件/服务/管道中都非常有效,但是如何从主 app.js 访问这些变量? console.log(process.env.anotherVariable) 未定义 ...
      • 当我尝试它时,我收到错误“找不到名称进程”
      • 无论如何,这里描述了一个更简单的 angular-cli 解决方案:stackoverflow.com/questions/40424199/…
      【解决方案5】:

      我已经使用以下方法实现了这一点:

      1. 为每个环境创建了ts 文件。
      2. 修改了package.json,并在脚本部分为每个环境添加了一个新条目。

      例如:-

      "start:local": "复制\"config/config.local.ts\" \"constants/global.constants.ts\" && npm run start"

      1. global.constants 导入您的应用。
      2. 您可以使用以下命令启动 HTTP 服务器:npm run start:local

      【讨论】:

      • 您是否有任何“devDependencies”来使该复制命令起作用?我收到一个错误,The system cannot find the file specified. 0 file(s) copied. 我认为这是一个路径问题,但在 Visual Studio Code 中,我可以 Ctrl+单击该文件,它确实存在。
      【解决方案6】:

      我认为这可能对您有用。 Passing asp.net server parameters to Angular 2 app

      这样你可以从 html 页面中注入任何值(可以从服务器获取值,比如当前环境变量)

      【讨论】:

        【解决方案7】:

        我也一直在为上述问题苦苦挣扎。尽管 Thierry 的回答非常好,但不知何故我觉得简单地拥有 env vars 太复杂了,所以我想我也表达了我的想法。

        1) 我首先创建了一个接口来描述我的环境变量app.settings.ts

        export interface IEnvVars {
            ENV: string;
            API_URL: string;
        }
        
        export class AppSettings {
            public static env_vars: IEnvVars;
        }
        

        2) I added the JavaScript fetch API type definitions to my .d.ts file.(如果您不介意 fetch 未解决,则不是绝对需要,但我确实介意,所以添加了类型)

        3) 所以现在在我的main.ts 中,我可以调用返回环境变量的端点:

        import {bootstrap}    from 'angular2/platform/browser';
        import {AppComponent} from './app.component';
        import {AppSettings,IEnvVars} from "./configs/app.settings";
        import {enableProdMode} from "angular2/core";
        
        fetch('/env-vars', {method: 'get'}).then((response) => {
            response.json().then((env_vars:IEnvVars) => {
                AppSettings.env_vars = env_vars;
                if (AppSettings.env_vars.ENV != 'development') enableProdMode();
                bootstrap(AppComponent);
            });
        });
        

        所以现在我可以通过以下方式在任何服务或组件中访问我的环境变量:

        import {AppSettings} from "../configs/app.settings";
        

        所以在一个方法等中,你可以这样:

        let customersURL = `${AppSettings.env_vars.API_URL}/customers`;
        

        请注意,您可能需要 polyfill 来获取 API,因为 Safari 和 IE 仍然不支持此功能。 (Link to polyfill exampel)

        【讨论】:

        • 谢谢,但问题是关于如何设置 /env-vars 端点。 (无法访问后端。)我现在将使用 gulp 构建步骤。
        • @Zlatko /env-vars 是一个包含您的设置的端点,或者可能只是一个位于您的项目中的纯 json 文件 /env-vars.json
        • 使用这种方法可能会遇到github.com/angular/angular-cli/issues/3540 的问题,因此您需要使用github.com/angular/angular-cli/issues/… 周围的工作,直到 angular-cle getitg 修复。
        【解决方案8】:

        我会看到两种方法来做到这一点:

        • 利用文件中的 JSON 配置。此文件将在提升应用程序之前加载:

          var app = platform(BROWSER_PROVIDERS)
             .application([BROWSER_APP_PROVIDERS, appProviders]);
          
          var http = app.injector.get(Http);
          http.get('config.json').subscribe((config) => {
            return app.bootstrap(AppComponent, [
              provide('config', { useValue: config })
            ]);
          }).toPromise();
          

          以下是描述全局方法的相应 plunkr:https://plnkr.co/edit/ooMNzEw2ptWrumwAX5zP?p=preview

        • 利用配置模块:

          export const CONFIG = {
            (...)
          };
          

          在引导应用程序时将被导入并包含在提供程序中:

            import {CONFIG} from './config';
          
            bootstrap(AppComponent, [
              provide('config', { useValue: CONFIG })
            ]);
          

        通过这两种方法,可以在打包应用程序时为每个环境定义配置。

        这个问题还可以为您提供有关如何打包 Angular2 应用程序的提示:

        【讨论】:

        • 嗯,第一个答案我已经描述过了。对于第三个,您将如何根据我正在构建的环境设置 CONFIG 变量?
        猜你喜欢
        • 1970-01-01
        • 2021-02-19
        • 1970-01-01
        • 2015-10-17
        • 2017-05-02
        • 2020-12-30
        • 2013-12-29
        • 2021-05-23
        相关资源
        最近更新 更多