Injecting environment variables into the build?

I’m working on a front end and back end at the same time. One thing I’d like to do is not have to remember to change the hardwired URL of the backend api when I go from dev to beta to production. In previous projects, where I had more direct control over the build tooling, I’d put an injector (usually using gulp-inject) so that I could stick some compile-time environment variables into index.html before any scripts got parsed. A bit hacky, but not terrible.

Is there any “normal” way to do this in current ionic? I’d like to basically say, “build for dev” and swap some magic strings out for localhost, and then “build for beta” and “build for production” and call it a day.

4 Likes

->

Build Management

Environment Variables

I followed these steps to add support for environment variables.

Update package.json:

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

Updated tsconfig.json in compilerOptions:

"baseUrl": "./src",
"paths": {
  "@app/env": [
    "environments/environment"
  ]
}

Created config/optimization.config.js:

var path = require('path');
var useDefaultConfig = require('@ionic/app-scripts/config/optimization.config.js');

module.exports = function () {
  useDefaultConfig.resolve.alias = {
    "@app/env": path.resolve('./src/environments/environment' + (process.env.IONIC_ENV === 'prod' ? '' : '.' + process.env.IONIC_ENV) + '.ts')
  };

  return useDefaultConfig;
};

Created config/webpack.config.js:

var path = require('path');
var useDefaultConfig = require('@ionic/app-scripts/config/webpack.config.js');

module.exports = function () {
  useDefaultConfig.resolve.alias = {
    "@app/env": path.resolve('./src/environments/environment' + (process.env.IONIC_ENV === 'prod' ? '' : '.' + process.env.IONIC_ENV) + '.ts')
  };

  return useDefaultConfig;
};

Created src/environments/environment.ts that will be used for the Production environment:

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

Created src/environments/environment.dev.ts that will be used for the Development environment:

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

For any other configuration, just add another file src/environments/environment.[ENV].ts (which will use the CLI’s build flags).

Import your environment variables:

import { ENV } from '@app/env'

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

# Environment Variables
**/environment.*
!**/environment.model.ts

Unit Testing and End-to-End (E2E) Testing

Updated tsconfig.ng-cli.json in compilerOptions:

"paths": {
  "@app/env": [
    "environments/environment"
  ]
}

Jasmine

The Jasmine test framework provides everything needed to write basic tests.

Karma

The Karma test runner is ideal for writing and running unit tests while
developing an application. It can be an integral part of the project’s development and continuous integration processes.

Run:

npm test

Protractor

Use protractor to write and run end-to-end (e2e) tests. End-to-end tests explore the application as users experience it.
In e2e testing, one process runs the real application and a second process runs protractor tests that simulate user
behavior and assert that the application respond in the browser as expected.

Run:

ionic serve [--platform=ios]

Then (in a second terminal session):

npm e2e

Test Coverage

Run:

npm test-coverage

In the ./coverage folder open index.html.

Simple Logging Service

->

4 Likes

(removing my comment as I posted in the issue tracker https://github.com/gshigeto/ionic-environment-variables/issues/26)

Thanks for the article.
Cheers,

I’m trying to do exactly the same but when i run “ionic build” I get an error:

[C:\Users\Salva\Projects\Emasphere\mobile\emamobile\node_modules\@app\env]
 @ ./src/pages/home/home.ts 18:0-31
 @ ./src/app/app.module.ts
 @ ./src/app/main.ts
    at new BuildError (C:\Users\Salva\Projects\Emasphere\mobile\emamobile\node_modules\@ionic\app-scripts\dist\util\errors.js:16:28)
    at callback (C:\Users\Salva\Projects\Emasphere\mobile\emamobile\node_modules\@ionic\app-scripts\dist\webpack.js:121:28)
    at emitRecords.err (C:\Users\Salva\Projects\Emasphere\mobile\emamobile\node_modules\webpack\lib\Compiler.js:269:13)
    at Compiler.emitRecords (C:\Users\Salva\Projects\Emasphere\mobile\emamobile\node_modules\webpack\lib\Compiler.js:375:38)
    at emitAssets.err (C:\Users\Salva\Projects\Emasphere\mobile\emamobile\node_modules\webpack\lib\Compiler.js:262:10)
    at applyPluginsAsyncSeries1.err (C:\Users\Salva\Projects\Emasphere\mobile\emamobile\node_modules\webpack\lib\Compiler.js:368:12)
    at next (C:\Users\Salva\Projects\Emasphere\mobile\emamobile\node_modules\tapable\lib\Tapable.js:218:11)
    at Compiler.compiler.plugin (C:\Users\Salva\Projects\Emasphere\mobile\emamobile\node_modules\webpack\lib\performance\SizeLimitsPlugin.js:99:4)
    at Compiler.applyPluginsAsyncSeries1 (C:\Users\Salva\Projects\Emasphere\mobile\emamobile\node_modules\tapable\lib\Tapable.js:222:13)
    at Compiler.afterEmit (C:\Users\Salva\Projects\Emasphere\mobile\emamobile\node_modules\webpack\lib\Compiler.js:365:9)

-> Can not find ‘@app/env’

Any clue ??

See: https://github.com/Robinyo/big-top#build-management

Thx…

I found my error…

the “config” part in package.json was misplaced … :frowning:

Thx again !

Would this work with Ionic 4?, I cant find an explanation for Ionic 4 :frowning:

Much easier than the stuff described in this thread.

@rapropos but what I’m trying to do is that on build time my app uses system enviroment variables that I’ve declared on enviroment.prod and enviroment. bc I cant push my credentials to the repo attached to my CI. I think that solution wont fit me.
Thanks

I’m not certain what you mean here, but if you’re talking about baking secrets into your Ionic app, emphatically do not do that. Anybody with a copy of the app binary has access to anything in there. Keep secrets on network servers under your control. Apologies if that’s not what you’re describing.