2016-04-10 100 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

    相關問題