Post

Per environment configuration in Aurelia

The objective is to have environment specific configurations embedded into application during build phase. Those usually endpoint for API, logging level, etc.

This is not specific to Aurelia, but can be applied to any JS client applications with gulp tasks in place

My idea is to be able do the following:

1
2
3
4
5
import * as config from 'environment';
...
// and then somewhere in code:
log.console(config.apiHostAddress);
...

and have a proper endpoint config.apiHostAddress depending on runtime environment.

Environments

At the root of application I created a folder called environments. The folder will contain a separate file per each environment: production.js, development.js, etc.

File’s structure is up to you, in my case they contain ES2015 constants:

1
2
export const debug = true;
export const apiHostAddress = "//localhost:57579";

What will control which file is loaded during build is environment variable, the value of which will match the file name:

1
2
SET APP_ENV=development #windows cmd
export APP_ENV=development #bash

Build

The task depends on the following additional (besides what already installed with Aurelia) package:

1
npm install gulp-rename --save-dev

Open /build/tasks/build.js and import the package:

1
const rename = require("gulp-rename");

Now let’s create a new task within this file:

1
2
3
4
5
6
7
gulp.task("build-environment", function () {
  return gulp
    .src("environments/" + (process.env.APP_ENV || "production") + ".js")
    .pipe(rename("environment.js"))
    .pipe(to5(assign({}, compilerOptions)))
    .pipe(gulp.dest(paths.output));
});

The task will:

  1. Take the correct source file, either based on APP_ENV environment variable or default from environments folder
  2. Rename it to environment.js
  3. Transpile
  4. Copy the output to destination folder

Finally add build-environment task into sequence:

1
2
3
4
5
6
7
gulp.task("build", function (callback) {
  return runSequence(
    "clean",
    ["build-system", "build-environment", "build-html", "build-css"],
    callback
  );
});

The final result is here.

Usage

The usage is pretty straight forward, just remember that the rebuild is required for each configuration change:

1
2
3
4
5
6
7
8
import * as config from 'environment';

export class ApiService {
...
  getClients() {
    return this._http.get(`${config.apiHostAddress}/clients/all`);
  }
}
Update

Someone wrote much robust solution for handling configurations in Aurelia. Aurelia plugin for app configurations.