It was a trending topic during long months on Ionic community. A lot of ways were explored and issues open to add it natively on Ionic framework. Finally the Ionic team decided to migrate to angular-cli on v4 and re-use the angular-cli native solution to manage environment variables.

So, we wanted to have environment variables work in Ionic v3 exactly like how they do in Angular CLI, whilst also supporting Karma and Protractor tests. more details

/!\ This post was updated on Aug 29, 2019

Update Notes: no more need to update webpack config scripts on Ionic v4

Find an issue? Drop a comment I'll fix it ASAP

Aliases vs relative paths

Aliases and environment variables are both handled by webpack. It’s why we introduce them together.

The main purpose of aliases is instead of using relative paths when importing like so:

import Utility from '../../utilities/utility';

thanks to webpack resolve.alias, you can use the alias:

import Utility from 'Utilities/utility';

Configuring TypeScript

Open your tsconfig.json and add something like the following snippet to your compilerOptions object (this is obviously just a part of my own configuration, so YMMV):

"moduleResolution": "node",
"baseUrl": "src",
"paths": {
  "@app/*": [ "app/*" ],
  "@assets/*": [ "assets/*" ],
  "@env": [ "environments/environment" ],
  "@pages/*": [ "pages/*" ],
  "@services/*": [ "services/*" ],
  "@tests/*": [ "./*" ],
  "@theme/*": [ "theme/*" ]
},

Here is what you need to know about it:

  • The moduleResolution defaults to classic but nowadays we can safely use node
  • the baseUrl is relative to the directory where your tsconfig.json resides
  • you can only use one asterisk in the paths (nothing like the somedir/**/* we sometimes use somewhere else)
  • you can even alias one single file, and not a directory (like I do in the api example)

Now you can rename your module paths in your imports using those aliases, run your build script and TypeScript won’t even blink.

Remember also to restart Visual Studio Code once you’ve finished with your tsconfig.json, or the Intellisence won’t find the modules.

Source: How to use module path aliases in Visual Studio Code, TypeScript

Custom Webpack configuration for Ionic

Ionic uses Webpack, and we can specify our own Webpack configuration file. But if we do, the next time we update @ionic/app-scripts Ionic might stop working because we are missing some new configuration detail.

Instead we keep the official configuration, and expand it.

Add the following block to your /package.json:

"config": {
    "ionic_webpack": "./config/webpack.config.js"
},

Create /config/webpack.config.js and paste this code in it:

const chalk = require("chalk");
const fs = require('fs');
const path = require('path');
const useDefaultConfig = require('@ionic/app-scripts/config/webpack.config.js');

const webpackConfig = process.env.IONIC_ENV || 'dev';
const env = require('minimist')(process.argv.slice(2)).env;

console.log(chalk.yellow.bgBlack('\nUsing ' + (!env ? 'DEFAULT' : env.toUpperCase()) + ' environment variables for ' + webpackConfig.toUpperCase() + ' build.\n'));

useDefaultConfig[env].resolve.alias = {
  "@app": path.resolve('./src/app/'),
  "@assets": path.resolve('./src/assets/'),
  "@env": path.resolve(environmentPath(env)),
  "@pages": path.resolve('./src/pages/'),
  "@services": path.resolve('./src/services/'),
  "@tests": path.resolve('./src/'),    
  "@theme": path.resolve('./src/theme/')
};

function environmentPath(env) {
  envFileName = 'environment' + (!env ? '' : '.' + env) + '.ts';

  let filePath = './src/environments/' + envFileName;

  console.log(chalk.yellow.bgBlack('Loading ' + filePath + '\n'));

  if (!fs.existsSync(filePath)) {
    console.log(chalk.red('\n' + filePath + ' does not exist!'));
  } else {
    return filePath;
  }
}

module.exports = function () {
  return useDefaultConfig;
};

Create default env config src/environments/environment.ts, and dev, prod config, resp. src/environments/environment.dev.ts and src/environments/environment.prod.ts:

export const ENV = {
  production: true,
  isDebugMode: false
};

Import your environment variables wherever you need:

import { ENV } from '@env'

Build with env argument

Now you can run your build providing an env argument to select environment variables:

$ ionic build --env=dev

And to build an app with prod options (improving performance):

$ ionic build --prod --env=dev

Note: Remember to ignore your environment files in your .gitignore

./src/environments/*
!./src/environments/environment.ts

Update webpack config for unit tests

If you use unit tests on your App you should also update your webpack config for test. I recommend the read of our meu-starter.ionic-v3 for more details on how to integrate env variables with unit and e2e tests.

Furthermore


Victor Dias

Sharing mobile Experiences

Follow me