将环境变量传递给 Angular2 应用程序?

Pass environment variables to an Angular2 app?

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

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

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

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

我会看到两种方法:

  • 利用文件中的 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 应用程序的提示:

  • How do I actually deploy an Angular 2 + Typescript + systemjs app?

我也为上述问题苦苦挣扎了一段时间。尽管 Thierry 的回答非常好,但我觉得简单地使用环境变量太复杂了,所以我想我也提出了我的想法。

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 中,我可以调用 returns 环境变量的端点:

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)

我想这可能对你有用。

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

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

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

之后就可以导入使用了。 Angular CLI 会自动交换文件。

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

P.S。变量在环境对象中可用。

this.url = environment.url

我使用以下方法实现了这个:

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

例如:-

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

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

在不同的环境下location.host的值会不同

将其用作 并从具有所有 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';
}

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

必须在build之前获取并写入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;

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

Environment.ts

如何使用

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

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

并在代码中访问变量

environement.varName

如何配置自定义 environement.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 配置的构建输出