5

I decided to use extended webpack configuration for angular-cli, so I ran command ng eject.

It looks like everything is working except environment file replacement, that is specified in angular-cli.json:

"environmentSource": "environments/environment.ts",
  "environments": {
    "dev": "environments/environment.ts",
    "prod": "environments/environment.prod.ts"
  }

Now there is not replacement at all and it always uses "environments/environment.ts" file.

Is there a way to make it work without significant changes for webpack config?

Also created an issue for angular-cli github project.

Stepan Suvorov
  • 25,118
  • 26
  • 108
  • 176

2 Answers2

7

Well.. I had to write my own solution

And inside webpack I changed config for AotPlugin plugin:

hostReplacementPaths: {
  'environments/environment.ts': environmentFiles[NODE_ENV]
}

and, of course, specified environmentFiles:

const environmentFiles = {
  'development': 'environments/environment.dev.ts',
  'staging': 'environments/environment.stag.ts',
  'production': 'environments/environment.prod.ts'
};
Stepan Suvorov
  • 25,118
  • 26
  • 108
  • 176
  • How do you start the enivornments now? Just webpack --config webpack.production.js ? Or do u need to set some env varialbes – Emre Öztürk Apr 12 '17 at 11:31
  • now you need to specify NODE_ENV yourself for each env – Stepan Suvorov Apr 12 '17 at 19:00
  • if the environment var is different to NODE_ENV I suggest to use this 'environments/environment.ts': environmentFiles[process.env.ENVIRONMENT] – skuarch Aug 10 '17 at 17:25
  • It is not working for me, I make use of `environment.production` to register my service-worker via the angular module, but it does not register the SW. – Machado Jan 31 '18 at 17:33
4

Update 5/24/2017

I discovered that I was getting an error during the watch mode of npm start because of environment file swapping similar to this issue with angular-cli

any recompile during npm start would generate this error

ERROR in ./src/environments/environment
Module build failed: Error: ENOENT: no such file or directory, open 'C:\dev\(...)\src\environments\environment'
 @ ./src/main.ts 4:0-57
 @ multi (webpack)-dev-server/client?http://localhost:4200 ./src/main.ts

I was able to bypass the environment swapping for 'local' builds by updating the AotPlugin as follows.

new AotPlugin({
  "mainPath": "main.ts",
  "hostReplacementPaths": isLocal? {} : {
    "./environments/environment": `${envFile}`
  },
  "exclude": [],
  "tsConfigPath": "src\\tsconfig.app.json",
  "skipCodeGeneration": !isAot
})

original posting

Posting this here for anyone else struggling with getting this to work.

I used a variation of the technique by Stepan, but no host paths would be replaced. I am on windows so I tried forward slash, backslash, escaped slash etc.

It wasn't until I matched my actual import statement that the hostReplacementPath actually did the replacement.

In my main.ts file I have this import statement

import { environment } from './environments/environment';

It finally worked when I used that exact path in my webpack.config.js file as seen below. (note I also used string interpolation on the environment string value.

const environmentFiles = {
  'dev': 'environments/environment.dev.ts',
  'stage': 'environments/environment.stage.ts',
  'prod': 'environments/environment.prod.ts'
};

module.exports = function(env) {
  const isAot = env.aot || false;
  const isZip = env.zip || false;

  const isLocal = env.target === 'local';
  const envFile = environmentFiles[env.target];

// ... code omitted for brevity

new AotPlugin({
  "mainPath": "main.ts",
  "hostReplacementPaths": {
    "./environments/environment": `${envFile}`
  },
  "exclude": [],
  "tsConfigPath": "src\\tsconfig.app.json",
  "skipCodeGeneration": !isAot
})

Finally, for completeness, here is my actual npm script

"build-prod-aot": "rimraf dist && webpack --env.target=prod --env.zip --env.aot --colors",
Brandon Culley
  • 5,219
  • 1
  • 28
  • 28