2016-04-10 61 views
24

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

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

另外,我现在做的是我创建一个单一的全局变量,我注入取决于构建gulp。我的应用程序不是一个需要可重用的库我不相信我应该打到意外的全局名称冲突。但这不是一个好习惯。

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

+2

IMO,你过优化。为了实现一个很好理解的模式(比如从配置文件中加载这些东西),我会采取一次“不必要的”获取。 – drewmoore

+0

你可能是对的,特别是当Angular 2碰到产品时,生产版本和缩小版开始工作真的很好。谢谢。 – Zlatko

+0

如果使用angular-cli,这里描述的简单解决方案如下所示:http://stackoverflow.com/questions/40424199/angular-2-testing-process-env – rmcsharry

回答

11

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

  • 杠杆在文件中的JSON配置。该文件将boostrapping应用程序之前加载:

    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应用:

+3

那么,我已经描述了第一个答案。对于第三个,你将如何根据我正在构建的环境设置“CONFIG”变量? – Zlatko

6

我一直在与上述挣扎了一会儿了。尽管蒂埃里的回答非常好,但我以某种方式发现它对于简单的env变量来说太复杂了,所以我想我也提出了我的想法。

1)我首先创建一个接口描述我ENV瓦尔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.(不是绝对必要的,但我没有介意,所以加类型)

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`; 

请注意,您可能需要填充API作为Safari和IE仍不支持这一点。 (Link to polyfill exampel

+1

谢谢,但问题是关于如何设置/ env-vars端点。 (无需访问后端)我现在正在使用gulp构建步骤。 – Zlatko

+0

优秀的答案。 –

+0

@Zlatko'/ env-vars'是一个包含你的设置的端点,或者可能只是位于你的项目中的纯json文件'/ env-vars.json'。 – Kuncevic

13

只要把变量的环境对象中。

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

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

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

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

this.url = environment.url 
+0

这工作得很好,从任何组件/服务/管道,但 如何从主app.js访问这些变量? console.log(process.env.anotherVariable)未定义... – erwin

+0

当我尝试它我得到的错误'无法找到名称过程' – rmcsharry

+0

无论如何一个简单的解决方案与角-cli在这里描述:http:// stackoverflow。 com/questions/40424199/angular-2-testing-process-env – rmcsharry

1

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

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

为如: -

“开始:本地”: “拷贝\” 配置/ config.local.ts \” \ “常量/ global.constants.ts \” & & NPM运行开始”

  • 导入global.constants到您的应用。
  • 您可以使用启动HTTP服务器:npm run start:local
  • +0

    你有任何“devDependencies”使复制命令工作吗?我收到一个错误,“系统找不到指定的文件。 0 files(s)copied.'我认为这是一个路径问题,但在Visual Studio Code中,我被允许Ctrl +单击该文件,它确实存在。 – markreyes

    0

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

    将此项作为使用,并从相应的json加载具有所有URL的值。

    相关的代码看起来可能是这样:

    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'; 
    } 
    
    +0

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

    相关问题