将环境变量传递给 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
我使用以下方法实现了这个:
- 为每个环境创建了
ts
个文件。
- 修改了
package.json
并在脚本部分为每个环境添加了一个新条目。
例如:-
"start:local": "copy \"config/config.local.ts\" \"constants/global.constants.ts\" && npm run start"
- 将
global.constants
导入您的应用程序。
- 您可以使用以下方式启动您的 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-node
和 dotenv
添加到您的依赖项中。
并且您可以轻松访问 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 配置的构建输出
我需要将后端 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
我使用以下方法实现了这个:
- 为每个环境创建了
ts
个文件。 - 修改了
package.json
并在脚本部分为每个环境添加了一个新条目。
例如:-
"start:local": "copy \"config/config.local.ts\" \"constants/global.constants.ts\" && npm run start"
- 将
global.constants
导入您的应用程序。 - 您可以使用以下方式启动您的 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-node
和 dotenv
添加到您的依赖项中。
并且您可以轻松访问 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 配置的构建输出