Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

angular-cli: environment file replacement is broken after switch to webpack (with `ng eject`)

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.

like image 455
Stepan Suvorov Avatar asked Feb 22 '17 09:02

Stepan Suvorov


2 Answers

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'
};
like image 182
Stepan Suvorov Avatar answered Nov 14 '22 14:11

Stepan Suvorov


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",
like image 4
Brandon Culley Avatar answered Nov 14 '22 15:11

Brandon Culley