Skip to content

How to pass environment variables?

Fabio Yamada edited this page Jul 19, 2016 · 7 revisions

It is good practice to keep app`s config out of our source code. Some motivation can be found in the 12 Factor App

Since we have webpack config files, why not use them to set our app`s config parameters that will be used in our Angular2 code as well?

Two main webpack config files can be used for this goal:

  • angular2-webpack-starter/config/webpack.prod.js
  • angular2-webpack-starter/config/webpack.dev.js

In those files the is a section Webpack Constants that can be used to declare the env`s constants. In this example we will declare process.env.API_URL (and the short form API_URL) to be used inside ou Angular2 app code. To follow the convention in place, we will add this cons declaration to METADATA as well.

Thus our webpack.dev.js will look like:

angular2-webpack-starter/config/webpack.dev.js

/**
 * Webpack Constants
 */
const ENV = process.env.ENV = process.env.NODE_ENV = 'development';
const API_URL = process.env.API_URL = 'localhost';
const HMR = helpers.hasProcessFlag('hot');
const METADATA = webpackMerge(commonConfig.metadata, {
  host: 'localhost',
  API_URL: API_URL,
  port: 8080,
  ENV: ENV,
  HMR: HMR
});

Bottom in the plugin section, add the new entry in the list:

plugins: [

    /**
     * Plugin: DefinePlugin
     * Description: Define free variables.
     * Useful for having development builds with debug logging or adding global constants.
     *
     * Environment helpers
     *
     * See: https://webpack.github.io/docs/list-of-plugins.html#defineplugin
     */
    // NOTE: when adding more properties, make sure you include them in custom-typings.d.ts
    new DefinePlugin({
      'ENV': JSON.stringify(METADATA.ENV),
      'API_URL': JSON.stringify(METADATA.API_URL),
      'HMR': METADATA.HMR,
      'process.env': {
        'ENV': JSON.stringify(METADATA.ENV),
        'NODE_ENV': JSON.stringify(METADATA.ENV),
        'HMR': METADATA.HMR,
        'API_URL' : JSON.stringify(METADATA.API_URL),
      }
    }),
  ],

If you want to access the variable only in the form of process.env.API_URL inside Argular2 app, this would be enough. If you want to use the shorter form API_URL, just follow the NOTE and go edit the custom-typings.d.ts in angular2-webpack-starter/src

angular2-webpack-starter/src/custom-typings.d.ts snippet


// Extra variables that live on Global that will be replaced by webpack DefinePlugin
declare var ENV: string;
declare var HMR: boolean;
declare var API_URL: string;

interface GlobalEnvironment {
  ENV;
  HMR;
  API_URL;
}

In a service provider inside your app, just use your new global variable coming from your webpack config file:


@Injectable()
export class DaoService {
    
    private _service1Url = 'http://' + process.env.API_URL + ':3000/api/service1';  // URL to web api
    private _service2Url = 'http://' + API_URL + ':3000/api/service2';  // URL to web api
    constructor (private http: Http) {}
...

Follow similar steps to update your webpack.prod.js file and use the production ip or domain name.

This wiki was originally created by Roy Bao as a response to the issue 386.