qdouble / angular-webpack-starter

A complete Angular 6 and Webpack 4 starter seed with minimal and full featured branches. Full featured branch includes: Material Design 2 (Bootstrap 4 branch available as well), @ngrx, HMR, DLLs and optional use of Universal for server-side rendering - Supports AOT (offline) compilation, sync and lazy loading. Karma/Protractor for e2e/unit tests.
MIT License
884 stars 183 forks source link

[QUESTION] Environment variables #297

Closed NickvdMeij closed 7 years ago

NickvdMeij commented 7 years ago

Hi there,

First of all, what an amazing starter for Angular2, finally one that implements serverside-rendering so well!. Bravo!

The only thing left I'm struggling with before completely migrating my entire stack is how to set environment variables that will be accessible by the angular application when it's rendered in the browser (I'm using the AOT + Universal build). I saw that there are multiple files where global variables are defined, including:

But the thing I'm missing is a part documentation how they all link together and which needs to be changed. For the record, the Ubuntu machine the environments run on have the system variables defined and are able to be obtained by using the process.env variable in NodeJS.

Thanks in advance!

qdouble commented 7 years ago

The constants.js is where the main environmental variables are stored....both d.ts files are just typings files so it compile properly. The webpack file is just the main webpack config.

NickvdMeij commented 7 years ago

@qdouble oke after a few days trail-and-error, I narrowed it down to 1 specific error I'm still having, trying to get my own custom environment variables working.

So far, the environment variables on my docker container are correctly picked up by NodeJS using the process.env variable. Webpack is correctly picking them up in the constants.js file and I can print them out in the webpack.config.ts using console.log.

Here are the parts of the constants.js and webpack.config.ts parts that I changed:

constants.js

...

exports.MAKE_IT_ENVIRONMENT = process.env.MAKE_IT_ENVIRONMENT
exports.MAKE_IT_API_URL = process.env.MAKE_IT_API_URL
exports.MAKE_IT_CLIENT_SECRET = process.env.MAKE_IT_CLIENT_SECRET
exports.MAKE_IT_CLIENT_ID = process.env.MAKE_IT_CLIENT_ID

webpack.config.ts

...

import {
  DEV_PORT, PROD_PORT, UNIVERSAL_PORT, EXCLUDE_SOURCE_MAPS, HOST,
  USE_DEV_SERVER_PROXY, DEV_SERVER_PROXY_CONFIG, DEV_SERVER_WATCH_OPTIONS,
  DEV_SOURCE_MAPS, PROD_SOURCE_MAPS, STORE_DEV_TOOLS,
  MY_COPY_FOLDERS, MY_POLYFILL_DLLS, MY_VENDOR_DLLS, MY_CLIENT_PLUGINS, MY_CLIENT_PRODUCTION_PLUGINS,
  MY_CLIENT_RULES, SHOW_WEBPACK_BUNDLE_ANALYZER,
  MAKE_IT_ENVIRONMENT,
  MAKE_IT_API_URL,
  MAKE_IT_CLIENT_SECRET,
  MAKE_IT_CLIENT_ID
} from './constants';

...

const CONSTANTS = {
  AOT: AOT,
  DEV_SERVER: DEV_SERVER,
  ENV: PROD ? JSON.stringify('production') : JSON.stringify('development'),
  HMR: HMR,
  HOST: JSON.stringify(HOST),
  PORT: PORT,
  STORE_DEV_TOOLS: JSON.stringify(STORE_DEV_TOOLS),
  UNIVERSAL: UNIVERSAL || SERVER,
  MAKE_IT_ENVIRONMENT: MAKE_IT_ENVIRONMENT,
  MAKE_IT_API_URL: MAKE_IT_API_URL,
  MAKE_IT_CLIENT_SECRET: MAKE_IT_CLIENT_SECRET,
  MAKE_IT_CLIENT_ID: MAKE_IT_CLIENT_ID
};

...

However, I added the environment variables to the src/custom-typings.d.ts like so:

...

declare var MAKE_IT_ENVIRONMENT: any;
declare var MAKE_IT_API_URL: any;
declare var MAKE_IT_CLIENT_SECRET: any;
declare var MAKE_IT_CLIENT_ID: any;

interface SystemJS {
  import: (path?: string) => Promise<any>;
}

interface GlobalEnvironment {
  AOT;
  DEV_SERVER;
  ENV;
  HMR;
  HOST;
  PORT;
  STORE_DEV_TOOLS;
  SystemJS: SystemJS;
  System: SystemJS;
  UNIVERSAL;
  MAKE_IT_ENVIRONMENT: any;
  MAKE_IT_API_URL: any;
  MAKE_IT_CLIENT_SECRET: any;
  MAKE_IT_CLIENT_ID: any;
}
...

and ofcourse added them to the src/app/services/constants.ts like so:

export const MOBILE = (typeof window !== 'undefined') ? (window.screen.availWidth < 800) : true;
export const API_BASE_URL: string = `http://${HOST}:${PORT}`;

export const ENVIRONMENT: string = `${MAKE_IT_ENVIRONMENT}`;
export const API_URL: string = `${MAKE_IT_API_URL}`;
export const CLIENT_SECRET: string = `${MAKE_IT_CLIENT_SECRET}`;
export const CLIENT_ID: string = `${MAKE_IT_CLIENT_ID}`;

but I keep gettings errors like this one:

info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
yarn run v0.24.6
$ npm run build:universal:aot && npm run server:universal
npm info it worked if it ends with ok
npm info using npm@4.2.0
npm info using node@v7.8.0
npm info lifecycle angular-webpack2-starter@3.0.0~prebuild:universal:aot: angular-webpack2-starter@3.0.0
npm info lifecycle angular-webpack2-starter@3.0.0~build:universal:aot: angular-webpack2-starter@3.0.0

> angular-webpack2-starter@3.0.0 build:universal:aot /var/make-it.business/backend-application
> npm-run-all -p build:aot build:server:aot

npm info it worked if it ends with ok
npm info using npm@4.2.0
npm info using node@v7.8.0
npm info it worked if it ends with ok
npm info using npm@4.2.0
npm info using node@v7.8.0
npm info lifecycle angular-webpack2-starter@3.0.0~prebuild:aot: angular-webpack2-starter@3.0.0
npm info lifecycle angular-webpack2-starter@3.0.0~build:aot: angular-webpack2-starter@3.0.0

> angular-webpack2-starter@3.0.0 build:aot /var/make-it.business/backend-application
> npm run build:aot:prod

npm info lifecycle angular-webpack2-starter@3.0.0~prebuild:server:aot: angular-webpack2-starter@3.0.0
npm info lifecycle angular-webpack2-starter@3.0.0~build:server:aot: angular-webpack2-starter@3.0.0

> angular-webpack2-starter@3.0.0 build:server:aot /var/make-it.business/backend-application
> npm run build:server:aot:prod

npm info it worked if it ends with ok
npm info using npm@4.2.0
npm info using node@v7.8.0
npm info it worked if it ends with ok
npm info using npm@4.2.0
npm info using node@v7.8.0
npm info lifecycle angular-webpack2-starter@3.0.0~prebuild:aot:prod: angular-webpack2-starter@3.0.0
npm info lifecycle angular-webpack2-starter@3.0.0~build:aot:prod: angular-webpack2-starter@3.0.0

> angular-webpack2-starter@3.0.0 build:aot:prod /var/make-it.business/backend-application
> npm run clean:dist && npm run sass && webpack

npm info lifecycle angular-webpack2-starter@3.0.0~prebuild:server:aot:prod: angular-webpack2-starter@3.0.0
npm info lifecycle angular-webpack2-starter@3.0.0~build:server:aot:prod: angular-webpack2-starter@3.0.0

> angular-webpack2-starter@3.0.0 build:server:aot:prod /var/make-it.business/backend-application
> npm run sass && webpack

npm info it worked if it ends with ok
npm info using npm@4.2.0
npm info using node@v7.8.0
npm info it worked if it ends with ok
npm info using npm@4.2.0
npm info using node@v7.8.0
npm info lifecycle angular-webpack2-starter@3.0.0~preclean:dist: angular-webpack2-starter@3.0.0
npm info lifecycle angular-webpack2-starter@3.0.0~clean:dist: angular-webpack2-starter@3.0.0

> angular-webpack2-starter@3.0.0 clean:dist /var/make-it.business/backend-application
> npm run rimraf -- dist .awcache

npm info lifecycle angular-webpack2-starter@3.0.0~presass: angular-webpack2-starter@3.0.0
npm info lifecycle angular-webpack2-starter@3.0.0~sass: angular-webpack2-starter@3.0.0

> angular-webpack2-starter@3.0.0 sass /var/make-it.business/backend-application
> node-sass "src/app/styles.scss" "src/app/styles.css" --include-path node_modules --output-style compressed -q

npm info it worked if it ends with ok
npm info using npm@4.2.0
npm info using node@v7.8.0
npm info lifecycle angular-webpack2-starter@3.0.0~prerimraf: angular-webpack2-starter@3.0.0
npm info lifecycle angular-webpack2-starter@3.0.0~rimraf: angular-webpack2-starter@3.0.0

> angular-webpack2-starter@3.0.0 rimraf /var/make-it.business/backend-application
> rimraf "dist" ".awcache"

npm info lifecycle angular-webpack2-starter@3.0.0~postrimraf: angular-webpack2-starter@3.0.0
npm info ok
npm info lifecycle angular-webpack2-starter@3.0.0~postclean:dist: angular-webpack2-starter@3.0.0
npm info ok
npm info it worked if it ends with ok
npm info using npm@4.2.0
npm info using node@v7.8.0
npm info lifecycle angular-webpack2-starter@3.0.0~postsass: angular-webpack2-starter@3.0.0
npm info ok
npm info lifecycle angular-webpack2-starter@3.0.0~presass: angular-webpack2-starter@3.0.0
npm info lifecycle angular-webpack2-starter@3.0.0~sass: angular-webpack2-starter@3.0.0

> angular-webpack2-starter@3.0.0 sass /var/make-it.business/backend-application
> node-sass "src/app/styles.scss" "src/app/styles.css" --include-path node_modules --output-style compressed -q

npm info lifecycle angular-webpack2-starter@3.0.0~postsass: angular-webpack2-starter@3.0.0
npm info ok
PRODUCTION BUILD:  true
AOT:  true
PRODUCTION BUILD:  true
AOT:  true
BUILDING APP
13% building modules 27/56 modules 29 active ...application/src/app/reducers/index.ts 15% building modules 45/72 modules 27 active ...-application/src/app/app.component.ts{ SyntaxError: Unexpected token (1:5)
at Parser.pp$4.raise (/var/make-it.business/backend-application/node_modules/acorn/dist/acorn.js:2488:13)
at Parser.pp.unexpected (/var/make-it.business/backend-application/node_modules/acorn/dist/acorn.js:623:8)
at Parser.pp.expect (/var/make-it.business/backend-application/node_modules/acorn/dist/acorn.js:617:26)
at Parser.pp$3.parseParenAndDistinguishExpression (/var/make-it.business/backend-application/node_modules/acorn/dist/acorn.js:2043:38)
at Parser.pp$3.parseExprAtom (/var/make-it.business/backend-application/node_modules/acorn/dist/acorn.js:1978:41)
at Parser.parseExprAtom (/var/make-it.business/backend-application/node_modules/acorn-dynamic-import/lib/inject.js:58:31)
at Parser.pp$3.parseExprSubscripts (/var/make-it.business/backend-application/node_modules/acorn/dist/acorn.js:1872:19)
at Parser.pp$3.parseMaybeUnary (/var/make-it.business/backend-application/node_modules/acorn/dist/acorn.js:1849:17)
at Parser.pp$3.parseExprOps (/var/make-it.business/backend-application/node_modules/acorn/dist/acorn.js:1791:19)
at Parser.pp$3.parseMaybeConditional (/var/make-it.business/backend-application/node_modules/acorn/dist/acorn.js:1774:19)
at Parser.pp$3.parseMaybeAssign (/var/make-it.business/backend-application/node_modules/acorn/dist/acorn.js:1750:19)
at Parser.pp$3.parseExpression (/var/make-it.business/backend-application/node_modules/acorn/dist/acorn.js:1722:19)
at Parser.pp$1.parseStatement (/var/make-it.business/backend-application/node_modules/acorn/dist/acorn.js:777:45)
at Parser.parseStatement (/var/make-it.business/backend-application/node_modules/acorn-dynamic-import/lib/inject.js:45:31)
at Parser.pp$1.parseTopLevel (/var/make-it.business/backend-application/node_modules/acorn/dist/acorn.js:672:23)
at Parser.parse (/var/make-it.business/backend-application/node_modules/acorn/dist/acorn.js:529:15)
at Object.parse (/var/make-it.business/backend-application/node_modules/acorn/dist/acorn.js:3378:37)
at Parser.evaluate (/var/make-it.business/backend-application/node_modules/webpack/lib/Parser.js:1369:21)
at Parser.parser.plugin (/var/make-it.business/backend-application/node_modules/webpack/lib/DefinePlugin.js:80:27)
at Parser.applyPluginsBailResult1 (/var/make-it.business/backend-application/node_modules/tapable/lib/Tapable.js:120:27)
at Parser.<anonymous> (/var/make-it.business/backend-application/node_modules/webpack/lib/Parser.js:256:25)
at Parser.applyPluginsBailResult1 (/var/make-it.business/backend-application/node_modules/tapable/lib/Tapable.js:120:27)
at Parser.evaluateExpression (/var/make-it.business/backend-application/node_modules/webpack/lib/Parser.js:1212:24)
at Parser.<anonymous> (/var/make-it.business/backend-application/node_modules/webpack/lib/Parser.js:89:18)
at Parser.applyPluginsBailResult1 (/var/make-it.business/backend-application/node_modules/tapable/lib/Tapable.js:120:27)
at Parser.evaluateExpression (/var/make-it.business/backend-application/node_modules/webpack/lib/Parser.js:1212:24)
at Parser.getRenameIdentifier (/var/make-it.business/backend-application/node_modules/webpack/lib/Parser.js:414:23)
at declarators.forEach.declarator (/var/make-it.business/backend-application/node_modules/webpack/lib/Parser.js:823:56)
at Array.forEach (native)
at Parser.walkVariableDeclarators (/var/make-it.business/backend-application/node_modules/webpack/lib/Parser.js:819:15) pos: 5, lo 27 16% building modules 56/91 modules 35 active ...ication/src/app/services/constants.ts{ SyntaxError: Unexpected token (1:5)
at Parser.pp$4.raise (/var/make-it.business/backend-application/node_modules/acorn/dist/acorn.js:2488:13)
at Parser.pp.unexpected (/var/make-it.business/backend-application/node_modules/acorn/dist/acorn.js:623:8)
at Parser.pp.expect (/var/make-it.business/backend-application/node_modules/acorn/dist/acorn.js:617:26)
at Parser.pp$3.parseParenAndDistinguishExpression (/var/make-it.business/backend-application/node_modules/acorn/dist/acorn.js:2043:38)
at Parser.pp$3.parseExprAtom (/var/make-it.business/backend-application/node_modules/acorn/dist/acorn.js:1978:41)
at Parser.parseExprAtom (/var/make-it.business/backend-application/node_modules/acorn-dynamic-import/lib/inject.js:58:31)
at Parser.pp$3.parseExprSubscripts (/var/make-it.business/backend-application/node_modules/acorn/dist/acorn.js:1872:19)
at Parser.pp$3.parseMaybeUnary (/var/make-it.business/backend-application/node_modules/acorn/dist/acorn.js:1849:17)
at Parser.pp$3.parseExprOps (/var/make-it.business/backend-application/node_modules/acorn/dist/acorn.js:1791:19)
at Parser.pp$3.parseMaybeConditional (/var/make-it.business/backend-application/node_modules/acorn/dist/acorn.js:1774:19)
at Parser.pp$3.parseMaybeAssign (/var/make-it.business/backend-application/node_modules/acorn/dist/acorn.js:1750:19)
at Parser.pp$3.parseExpression (/var/make-it.business/backend-application/node_modules/acorn/dist/acorn.js:1722:19)
at Parser.pp$1.parseStatement (/var/make-it.business/backend-application/node_modules/acorn/dist/acorn.js:777:45)
at Parser.parseStatement (/var/make-it.business/backend-application/node_modules/acorn-dynamic-import/lib/inject.js:45:31)
at Parser.pp$1.parseTopLevel (/var/make-it.business/backend-application/node_modules/acorn/dist/acorn.js:672:23)
at Parser.parse (/var/make-it.business/backend-application/node_modules/acorn/dist/acorn.js:529:15)
at Object.parse (/var/make-it.business/backend-application/node_modules/acorn/dist/acorn.js:3378:37)
at Parser.evaluate (/var/make-it.business/backend-application/node_modules/webpack/lib/Parser.js:1369:21)
at Parser.parser.plugin (/var/make-it.business/backend-application/node_modules/webpack/lib/DefinePlugin.js:80:27)
at Parser.applyPluginsBailResult1 (/var/make-it.business/backend-application/node_modules/tapable/lib/Tapable.js:120:27)
at Parser.<anonymous> (/var/make-it.business/backend-application/node_modules/webpack/lib/Parser.js:256:25)
at Parser.applyPluginsBailResult1 (/var/make-it.business/backend-application/node_modules/tapable/lib/Tapable.js:120:27)
at Parser.evaluateExpression (/var/make-it.business/backend-application/node_modules/webpack/lib/Parser.js:1212:24)
at Parser.<anonymous> (/var/make-it.business/backend-application/node_modules/webpack/lib/Parser.js:89:18)
at Parser.applyPluginsBailResult1 (/var/make-it.business/backend-application/node_modules/tapable/lib/Tapable.js:120:27)
at Parser.evaluateExpression (/var/make-it.business/backend-application/node_modules/webpack/lib/Parser.js:1212:24)
at Parser.getRenameIdentifier (/var/make-it.business/backend-application/node_modules/webpack/lib/Parser.js:414:23)
at declarators.forEach.declarator (/var/make-it.business/backend-application/node_modules/webpack/lib/Parser.js:823:56)
at Array.forEach (native)
at Parser.walkVariableDeclarators (/var/make-it.busin 52% building mo  68% buiHash: 9173ad6aeebbb3b00be2les 23 active ...e5/lib/tokenizer/named_entity_data.js                                                          Version: webpack 2.6.0
Time: 39219ms
[./constants.js] ./constants.js 3.12 kB {0} [built]
[./node_modules/@angular/core/@angular/core.es5.js] ./~/@angular/core/@angular/core.es5.js 461 kB {0} [built]
[./node_modules/@angular/platform-browser/@angular/platform-browser.es5.js] ./~/@angular/platform-browser/@angular/platform-browser.es5.js 142 kB {0} [built]
[./node_modules/@ngrx/store/src/state.js] ./~/@ngrx/store/src/state.js 1.43 kB {0} [built]
[./node_modules/@nguniversal/express-engine/index.js] ./~/@nguniversal/express-engine/index.js 196 bytes {0} [built]
[./node_modules/compression/index.js] ./~/compression/index.js 5.76 kB {0} [built]
[./node_modules/express/index.js] ./~/express/index.js 224 bytes {0} [built]
[./node_modules/zone.js/dist/zone-node.js] ./~/zone.js/dist/zone-node.js 81.2 kB {0} [built]
[./src/ngfactory/app/server.app.module.ngfactory.ts] ./src/ngfactory/app/server.app.module.ngfactory.ts 50.4 kB {0} [built]
[./src/ngfactory/node_modules/@angular/material/typings/index.ngfactory.ts] ./src/ngfactory/~/@angular/material/typings/index.ngfactory.ts 572 kB {0} [built]
[./src/polyfills.server.ts] ./src/polyfills.server.ts 125 bytes {0} [built]
[./src/rxjs.imports.ts] ./src/rxjs.imports.ts 964 bytes {0} [built]
[./src/server.aot.ts] ./src/server.aot.ts 1.55 kB {0} [built]
[./src/server.routes.ts] ./src/server.routes.ts 240 bytes {0} [built]
[./src/server/app.ts] ./src/server/app.ts 222 bytes {0} [built]
+ 706 hidden modules

WARNING in ./~/express/lib/view.js
80:29-41 Critical dependency: the request of a dependency is an expression

ERROR in /var/make-it.business/backend-application/src/app/app.component.ts (5,10): Module '"/var/make-it.business/backend-application/src/app/services/constants"' has no exported member 'MOBILE'.
Child src/app/app.component.html:
[./src/app/app.component.html] ./src/app/app.component.html 452 bytes {0} [built]
Child src/app/features/store-devtools.component.html:
[./src/app/features/store-devtools.component.html] ./src/app/features/store-devtools.component.html 172 bytes {0} [built]
Child src/app/components/topnav/topnav.template.html:
+ 1 hidden modules
Child src/app/components/sidenav/sidenav.template.html:
+ 1 hidden modules
Child src/app/components/toasts/success/success-toast.template.html:
+ 1 hidden modules
Child src/app/components/toasts/failure/failure-toast.template.html:
+ 1 hidden modules
Child src/app/pages/home/home.template.html:
[./src/app/pages/home/home.template.html] ./src/app/pages/home/home.template.html 640 bytes {0} [built]
Child src/app/pages/quick-links/quick-links.template.html:
[./src/app/pages/quick-links/quick-links.template.html] ./src/app/pages/quick-links/quick-links.template.html 3.93 kB {0} [built]
Child src/app/pages/login/login.template.html:
[./src/app/pages/login/login.template.html] ./src/app/pages/login/login.template.html 1.62 kB {0} [built]
Child src/app/pages/user-settings/user-settings.template.html:
[./src/app/pages/user-settings/user-settings.template.html] ./src/app/pages/user-settings/user-settings.template.html 1.96 kB {0} [built]
Child src/app/pages/contact/contact.template.html:
[./src/app/pages/contact/contact.template.html] ./src/app/pages/contact/contact.template.html 11.3 kB {0} [built]
Child node_modules/flexboxgrid/dist/flexboxgrid.min.css:
[./node_modules/flexboxgrid/dist/flexboxgrid.min.css] ./~/flexboxgrid/dist/flexboxgrid.min.css 12.3 kB {0} [built]
Child src/app/components/topnav/topnav.style.scss:
[./node_modules/css-loader/lib/css-base.js] ./~/css-loader/lib/css-base.js 2.19 kB {0} [built]
+ 2 hidden modules
Child src/app/components/sidenav/sidenav.style.scss:
[./node_modules/css-loader/lib/css-base.js] ./~/css-loader/lib/css-base.js 2.19 kB {0} [built]
+ 2 hidden modules
Child src/app/app.component.scss:
[./node_modules/css-loader/index.js!./node_modules/sass-loader/lib/loader.js!./src/app/app.component.scss] ./~/css-loader!./~/sass-loader/lib/loader.js!./src/app/app.component.scss 3.94 kB {0} [built]
[./node_modules/css-loader/lib/css-base.js] ./~/css-loader/lib/css-base.js 2.19 kB {0} [built]
[./src/app/app.component.scss] ./src/app/app.component.scss 300 bytes {0} [built]
Child src/app/pages/user-settings/user-settings.style.scss:
[./node_modules/css-loader/index.js!./node_modules/sass-loader/lib/loader.js!./src/app/pages/user-settings/user-settings.style.scss] ./~/css-loader!./~/sass-loader/lib/loader.js!./src/app/pages/user-settings/user-settings.style.scss 4.36 kB {0} [built]
[./node_modules/css-loader/lib/css-base.js] ./~/css-loader/lib/css-base.js 2.19 kB {0} [built]
[./src/app/pages/user-settings/user-settings.style.scss] ./src/app/pages/user-settings/user-settings.style.scss 318 bytes {0} [built]
Child src/app/pages/home/home.style.scss:
[./node_modules/css-loader/index.js!./node_modules/sass-loader/lib/loader.js!./src/app/pages/home/home.style.scss] ./~/css-loader!./~/sass-loader/lib/loader.js!./src/app/pages/home/home.style.scss 3.93 kB {0} [built]
[./node_modules/css-loader/lib/css-base.js] ./~/css-loader/lib/css-base.js 2.19 kB {0} [built]
[./src/app/pages/home/home.style.scss] ./src/app/pages/home/home.style.scss 309 bytes {0} [built]
Child src/app/pages/quick-links/quick-links.style.scss:
[./node_modules/css-loader/index.js!./node_modules/sass-loader/lib/loader.js!./src/app/pages/quick-links/quick-links.style.scss] ./~/css-loader!./~/sass-loader/lib/loader.js!./src/app/pages/quick-links/quick-links.style.scss 4.26 kB {0} [built]
[./node_modules/css-loader/lib/css-base.js] ./~/css-loader/lib/css-base.js 2.19 kB {0} [built]
[./src/app/pages/quick-links/quick-links.style.scss] ./src/app/pages/quick-links/quick-links.style.scss 316 bytes {0} [built]
Child src/app/pages/contact/contact.style.scss:
[./node_modules/css-loader/index.js!./node_modules/sass-loader/lib/loader.js!./src/app/pages/contact/contact.style.scss] ./~/css-loader!./~/sass-loader/lib/loader.js!./src/app/pages/contact/contact.style.scss 4.71 kB {0} [built]
[./node_modules/css-loader/lib/css-base.js] ./~/css-loader/lib/css-base.js 2.19 kB {0} [built]
[./src/app/pages/contact/contact.style.scss] ./src/app/pages/contact/contact.style.scss 312 bytes {0} [built]
Child src/app/components/toasts/failure/failure-toast.style.scss:
[./node_modules/css-loader/lib/css-base.js] ./~/css-loader/lib/css-base.js 2.19 kB {0} [built]
+ 2 hidden modules
Child src/app/pages/login/login.style.scss:
[./node_modules/css-loader/index.js!./node_modules/sass-loader/lib/loader.js!./src/app/pages/login/login.style.scss] ./~/css-loader!./~/sass-loader/lib/loader.js!./src/app/pages/login/login.style.scss 4.09 kB {0} [built]
[./node_modules/css-loader/lib/css-base.js] ./~/css-loader/lib/css-base.js 2.19 kB {0} [built]
[./src/app/pages/login/login.style.scss] ./src/app/pages/login/login.style.scss 310 bytes {0} [built]
Child src/app/components/toasts/success/success-toast.style.scss:
[./node_modules/css-loader/lib/css-base.js] ./~/css-loader/lib/css-base.js 2.19 kB {0} [built]
+ 2 hidden modules                                                                                                                                                                                                  npm info lifecycle angular-webpack2-starter@3.0.0~build:server:aot:prod: Failed to exec build:server:aot:prod script
npm ERR! Linux 4.9.31-moby
npm ERR! argv "/usr/local/bin/node" "/usr/local/bin/npm" "run" "build:server:aot:prod"
npm ERR! node v7.8.0
npm ERR! npm  v4.2.0
npm ERR! code ELIFECYCLE
npm ERR! errno 2
npm ERR! angular-webpack2-starter@3.0.0 build:server:aot:prod: `npm run sass && webpack`
npm ERR! Exit status 2
npm ERR!
npm ERR! Failed at the angular-webpack2-starter@3.0.0 build:server:aot:prod script 'npm run sass && webpack'.
npm ERR! Make sure you have the latest version of node.js and npm installed.
npm ERR! If you do, this is most likely a problem with the angular-webpack2-starter package,
npm ERR! not with npm itself.
npm ERR! Tell the author that this fails on your system:
npm ERR!     npm run sass && webpack
npm ERR! You can get information on how to open an issue for this project with:
npm ERR!     npm bugs angular-webpack2-starter
npm ERR! Or if that isn't available, you can get their info via:
npm ERR!     npm owner ls angular-webpack2-starter
npm ERR! There is likely additional logging output above.

npm ERR! Please include the following file with any support request:
npm ERR!     /root/.npm/_logs/2017-07-03T21_19_00_225Z-debug.log

npm info lifecycle angular-webpack2-starter@3.0.0~build:server:aot: Failed to exec build:server:aot script
npm ERR! Linux 4.9.31-moby
npm ERR! argv "/usr/local/bin/node" "/usr/local/lib/node_modules/npm/bin/npm-cli.js" "run" "build:server:aot"
npm ERR! node v7.8.0
npm ERR! npm  v4.2.0
npm ERR! code ELIFECYCLE
npm ERR! errno 2
npm ERR! angular-webpack2-starter@3.0.0 build:server:aot: `npm run build:server:aot:prod`
npm ERR! Exit status 2
npm ERR!
npm ERR! Failed at the angular-webpack2-starter@3.0.0 build:server:aot script 'npm run build:server:aot:prod'.
npm ERR! Make sure you have the latest version of node.js and npm installed.
npm ERR! If you do, this is most likely a problem with the angular-webpack2-starter package,
npm ERR! not with npm itself.
npm ERR! Tell the author that this fails on your system:
npm ERR!     npm run build:server:aot:prod
npm ERR! You can get information on how to open an issue for this project with:
npm ERR!     npm bugs angular-webpack2-starter
npm ERR! Or if that isn't available, you can get their info via:
npm ERR!     npm owner ls angular-webpack2-starter
npm ERR! There is likely additional logging output above.

npm ERR! Please include the following file with any support request:
npm ERR!     /root/.npm/_logs/2017-07-03T21_19_00_252Z-debug.log
npm info lifecycle angular-webpack2-starter@3.0.0~postbuild:aot:prod: angular-webpack2-starter@3.0.0
ERROR: "build:server:aot" exited with 2.

npm info lifecycle angular-webpack2-starter@3.0.0~build:universal:aot: Failed to exec build:universal:aot script
npm ERR! Linux 4.9.31-moby
npm ERR! argv "/usr/local/bin/node" "/usr/local/bin/npm" "run" "build:universal:aot"
npm ERR! node v7.8.0
npm ERR! npm  v4.2.0
npm ERR! code ELIFECYCLE
npm ERR! errno 1
npm ERR! angular-webpack2-starter@3.0.0 build:universal:aot: `npm-run-all -p build:aot build:server:aot`
npm ERR! Exit status 1
npm ERR!
npm ERR! Failed at the angular-webpack2-starter@3.0.0 build:universal:aot script 'npm-run-all -p build:aot build:server:aot'.
npm ERR! Make sure you have the latest version of node.js and npm installed.
npm ERR! If you do, this is most likely a problem with the angular-webpack2-starter package,
npm ERR! not with npm itself.
npm ERR! Tell the author that this fails on your system:
npm ERR!     npm-run-all -p build:aot build:server:aot
npm ERR! You can get information on how to open an issue for this project with:
npm ERR!     npm bugs angular-webpack2-starter
npm ERR! Or if that isn't available, you can get their info via:
npm ERR!     npm owner ls angular-webpack2-starter
npm ERR! There is likely additional logging output above.

npm ERR! Please include the following file with any support request:
npm ERR!     /root/.npm/_logs/2017-07-03T21_19_00_420Z-debug.log
error Command failed with exit code 1.

and when the build succeeds correctly (which it sometimes magically does when I'm tinkering with it....), all the defined environment variables are undefined.

Do you perhaps have any idea if I'm missing something? I'm beginning to be a bit clueless due to the minimal error reporting sadly.

Thanks in advance!

ValentinFunk commented 7 years ago

What i do is this in constants.js:

const StringReplacePlugin = require('string-replace-webpack-plugin');

const CONFIG = {
  ORIGIN: process.env.WEBSITE_ORIGIN || "http://localhost:3000",
  CLIENT_SECRET: process.env.CLIENT_SECRET || "SOME DEV SECRET"
}

exports.MY_CLIENT_PLUGINS = [
  new StringReplacePlugin(),
];

// Files to replace CONFIG keys in.
const replaceInFiles = [
  root('src/app/app.settings.ts'),
];

// Put this below exports.MY_CLIENT_RULES
const configReplaceLoader = StringReplacePlugin.replace({
  replacements: [
    {
      pattern: /\{\{\{(.*)\}\}\}/ig,
      replacement: function (match, p1, offset, string) {
        return CONFIG[p1];
      }
    }
  ]
});

for (let path of replaceInFiles) {
  exports.MY_CLIENT_RULES.push({
    test: path,
    loaders: configReplaceLoader
  });
}

In my angular file (e.g. src/app/app.settings.ts):

export const APP_SETTINGS = {
  clientId: '{{{CLIENT_SECRET}}}',
  origin: '{{{ORIGIN}}}'
};

It's a pretty simple string replacement that is done at build time.

NickvdMeij commented 7 years ago

@Kamshak so you only changed those 2 filed and nothing else? =D will definitely try this, looks like a better and cleaner implementation.

ValentinFunk commented 7 years ago

Yes :) a little fix: in the loader definition you need to put enforce: 'pre':

for (let path of replaceInFiles) {
  exports.MY_CLIENT_RULES.push({
    test: path,
    enforce: 'pre',
    loaders: configReplaceLoader
  });
}
NickvdMeij commented 7 years ago

@Kamshak your solution doesn't seem to quite work..

For some reason, the environment variables are being reconized during the build process. However, the string replace webpack plugin doesn't seem to replace the variables in the file.

Here is my config so far:

constants.js:

"use strict";
const root = require('./helpers.js').root
const ip = require('ip');

exports.HOST = ip.address();
exports.DEV_PORT = 3000;
exports.E2E_PORT = 4201;
exports.PROD_PORT = 8088;
exports.UNIVERSAL_PORT = 8000;

exports.SHOW_WEBPACK_BUNDLE_ANALYZER = false;

/**
 * These constants set whether or not you will use proxy for Webpack DevServer
 * For advanced configuration details, go to:
 * https://webpack.github.io/docs/webpack-dev-server.html#proxy
 */
exports.USE_DEV_SERVER_PROXY = false;
exports.DEV_SERVER_PROXY_CONFIG = {
  '**': 'http://localhost:8089'
}

/**
 * These constants set the source maps that will be used on build.
 * For info on source map options, go to:
 * https://webpack.github.io/docs/configuration.html#devtool
 */
exports.DEV_SOURCE_MAPS = 'eval';
exports.PROD_SOURCE_MAPS = 'source-map';

/**
 * Set watch options for Dev Server. For better HMR performance, you can
 * try setting poll to 1000 or as low as 300 and set aggregateTimeout to as low as 0.
 * These settings will effect CPU usage, so optimal setting will depend on your dev environment.
 * https://github.com/webpack/docs/wiki/webpack-dev-middleware#watchoptionsaggregatetimeout
 */
exports.DEV_SERVER_WATCH_OPTIONS = {
  poll: 1000,
  aggregateTimeout: 0,
  ignored: /node_modules/
}

/**
 * specifies which @ngrx dev tools will be available when you build and load
 * your app in dev mode. Options are: monitor | logger | both | none
 */
exports.STORE_DEV_TOOLS = 'logger'

exports.EXCLUDE_SOURCE_MAPS = [
  // these packages have problems with their sourcemaps
  root('node_modules/@angular'),
  root('node_modules/@nguniversal'),
  root('node_modules/rxjs')
]

exports.MY_COPY_FOLDERS = [
  // use this for folders you want to be copied in to Client dist
  // src/assets and index.html are already copied by default.
  // format is { from: 'folder_name', to: 'folder_name' }
]

exports.MY_POLYFILL_DLLS = [
  // list polyfills that you want to be included in your dlls files
  // this will speed up initial dev server build and incremental builds.
  // Be sure to run `npm run build:dll` if you make changes to this array.
]

exports.MY_VENDOR_DLLS = [
  // list vendors that you want to be included in your dlls files
  // this will speed up initial dev server build and incremental builds.
  // Be sure to run `npm run build:dll` if you make changes to this array.
]

exports.MY_CLIENT_PRODUCTION_PLUGINS = [
  // use this to import your own webpack config plugins for production use.
]

exports.MY_TEST_RULES = [
  // use this to import your own rules for Test webpack config.
]

exports.MY_TEST_PLUGINS = [
  // use this to import your own Test webpack config plugins.
]

const StringReplacePlugin = require('string-replace-webpack-plugin');

const CONFIG = {
    MAKE_IT_ENVIRONMENT: process.env.MAKE_IT_ENVIRONMENT || "development",
    MAKE_IT_API_URL: process.env.MAKE_IT_API_URL || "http://example.com",
    MAKE_IT_CLIENT_SECRET: process.env.MAKE_IT_CLIENT_SECRET || "1",
    MAKE_IT_CLIENT_ID: process.env.MAKE_IT_CLIENT_ID || "secret"
}

console.log('CONFIG', CONFIG);

exports.MY_CLIENT_PLUGINS = [
    new StringReplacePlugin(),
];

let rulesArray = [

];

for (let path of [
    root('src/app/services/constants.ts'),
]) {
    console.log('PATH', path)
    rulesArray.push({
        test: path,
        loaders: StringReplacePlugin.replace({
            replacements: [
                {
                    pattern: /\{\{\{(.*)\}\}\}/ig,
                    replacement: function (match, p1, offset, string) {
                        console.log('REPLACEMENT', { match: match, return: CONFIG[p1]});
                        return CONFIG[p1];
                    }
                }
            ]
        })
    });
    console.log('TMP RULES', rulesArray);
}

exports.MY_CLIENT_RULES = rulesArray;

webpack.config.ts

/* tslint:disable: variable-name max-line-length */
/**
 * Try to not make your own edits to this file, use the constants folder instead.
 * If more constants should be added file an issue or create PR.
 */
import 'ts-helpers';

import {
  DEV_PORT, PROD_PORT, UNIVERSAL_PORT, EXCLUDE_SOURCE_MAPS, HOST,
  USE_DEV_SERVER_PROXY, DEV_SERVER_PROXY_CONFIG, DEV_SERVER_WATCH_OPTIONS,
  DEV_SOURCE_MAPS, PROD_SOURCE_MAPS, STORE_DEV_TOOLS,
  MY_COPY_FOLDERS, MY_POLYFILL_DLLS, MY_VENDOR_DLLS, MY_CLIENT_PLUGINS, MY_CLIENT_PRODUCTION_PLUGINS,
  MY_CLIENT_RULES, SHOW_WEBPACK_BUNDLE_ANALYZER
} from './constants';

const {
  DefinePlugin,
  DllPlugin,
  DllReferencePlugin,
  ProgressPlugin,
  NoEmitOnErrorsPlugin
} = require('webpack');

const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
const CompressionPlugin = require('compression-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const { CheckerPlugin } = require('awesome-typescript-loader');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const NamedModulesPlugin = require('webpack/lib/NamedModulesPlugin');
const ScriptExtPlugin = require('script-ext-html-webpack-plugin');
const UglifyJsPlugin = require('webpack/lib/optimize/UglifyJsPlugin');
const webpackMerge = require('webpack-merge');
const { getAotPlugin } = require('./webpack.aot');

const { hasProcessFlag, includeClientPackages, root, testDll } = require('./helpers.js');

const EVENT = process.env.npm_lifecycle_event || '';
const AOT = EVENT.includes('aot');
const DEV_SERVER = EVENT.includes('webdev');
const DLL = EVENT.includes('dll');
const E2E = EVENT.includes('e2e');
const HMR = hasProcessFlag('hot');
const PROD = EVENT.includes('prod');
const SERVER = EVENT.includes('server');
const WATCH = hasProcessFlag('watch');
const UNIVERSAL = EVENT.includes('universal');

let port: number;
if (!UNIVERSAL) {
  if (PROD) {
    port = PROD_PORT;
  } else {
    port = DEV_PORT;
  }
} else {
  port = UNIVERSAL_PORT;
}

const PORT = port;

console.log('PRODUCTION BUILD: ', PROD);
console.log('AOT: ', AOT);
if (DEV_SERVER) {
  testDll();
  console.log(`Starting dev server on: http://${HOST}:${PORT}`);
}

const CONSTANTS = {
  AOT: AOT,
  DEV_SERVER: DEV_SERVER,
  ENV: PROD ? JSON.stringify('production') : JSON.stringify('development'),
  HMR: HMR,
  HOST: JSON.stringify(HOST),
  PORT: PORT,
  STORE_DEV_TOOLS: JSON.stringify(STORE_DEV_TOOLS),
  UNIVERSAL: UNIVERSAL || SERVER
};

const DLL_VENDORS = [
  '@angular/common',
  '@angular/compiler',
  '@angular/core',
  '@angular/forms',
  '@angular/http',
  '@angular/material',
  '@angular/platform-browser',
  '@angular/platform-browser-dynamic',
  '@angular/platform-server',
  '@angular/router',
  '@ngrx/core',
  '@ngrx/core/add/operator/select.js',
  '@ngrx/effects',
  '@ngrx/router-store',
  '@ngrx/store',
  '@ngrx/store-devtools',
  '@ngrx/store-log-monitor',
  'ngrx-store-freeze',
  'ngrx-store-logger',
  'rxjs',
  ...MY_VENDOR_DLLS
];

const COPY_FOLDERS = [
  { from: 'src/assets', to: 'assets' },
  { from: 'node_modules/hammerjs/hammer.min.js' },
  { from: 'node_modules/hammerjs/hammer.min.js.map' },
  { from: 'src/app/styles.css' },
  ...MY_COPY_FOLDERS
];

if (!DEV_SERVER) {
  COPY_FOLDERS.unshift({ from: 'src/index.html' });
} else {
  COPY_FOLDERS.push({ from: 'dll' });
}

const commonConfig = function webpackConfig(): WebpackConfig {
  let config: WebpackConfig = Object.assign({});

  config.module = {
    rules: [
      {
        test: /\.js$/,
        loader: 'source-map-loader',
        exclude: [EXCLUDE_SOURCE_MAPS]
      },
      {
        test: /\.ts$/,
        loaders: !DLL && !DEV_SERVER ? ['@ngtools/webpack'] : [
          '@angularclass/hmr-loader',
          'awesome-typescript-loader?{configFileName: "tsconfig.webpack.json"}',
          'angular2-template-loader',
          'angular-router-loader?loader=system&genDir=compiled&aot=' + AOT
        ],
        exclude: [/\.(spec|e2e|d)\.ts$/]
      },
      { test: /\.json$/, loader: 'json-loader' },
      { test: /\.html/, loader: 'raw-loader', exclude: [root('src/index.html')] },
      { test: /\.css$/, loader: 'raw-loader' },
      {
        test: /\.scss$/,
        loaders: ['to-string-loader', 'css-loader', 'sass-loader']
      },
      ...MY_CLIENT_RULES
    ]
  };

  config.plugins = [
    new ProgressPlugin(),
    new CheckerPlugin(),
    new DefinePlugin(CONSTANTS),
    new NamedModulesPlugin(),
    ...MY_CLIENT_PLUGINS
  ];

  if (DEV_SERVER) {
    config.plugins.push(
      new DllReferencePlugin({
        context: '.',
        manifest: require(`./dll/polyfill-manifest.json`)
      }),
      new DllReferencePlugin({
        context: '.',
        manifest: require(`./dll/vendor-manifest.json`)
      }),
      new HtmlWebpackPlugin({
        template: 'src/index.html',
        inject: false
      })
    );
  }

  if (DLL) {
    config.plugins.push(
      new DllPlugin({
        name: '[name]',
        path: root('dll/[name]-manifest.json'),
      })
    );
  } else {
    config.plugins.push(
      new CopyWebpackPlugin(COPY_FOLDERS, { ignore: ['*dist_root/*'] }),
      new CopyWebpackPlugin([{ from: 'src/assets/dist_root' }])
    );
  }

  if (PROD) {
    config.plugins.push(
      new NoEmitOnErrorsPlugin(),
      new CompressionPlugin({
        asset: '[path].gz[query]',
        algorithm: 'gzip',
        test: /\.js$|\.html$/,
        threshold: 10240,
        minRatio: 0.8
      }),
      ...MY_CLIENT_PRODUCTION_PLUGINS,
    );
    if (!E2E && !WATCH && !UNIVERSAL && SHOW_WEBPACK_BUNDLE_ANALYZER) {
      config.plugins.push(
        new BundleAnalyzerPlugin({ analyzerPort: 5000 })
      );
    }
  }

  console.log('full_config', config);
  console.log('plugins', config.plugins);
  console.log('rules', config.module.rules);
  console.log('full_config', config);

  return config;
}();

// type definition for WebpackConfig at the bottom
const clientConfig = function webpackConfig(): WebpackConfig {

  let config: WebpackConfig = Object.assign({});

  config.cache = true;
  config.target = 'web';
  PROD ? config.devtool = PROD_SOURCE_MAPS : config.devtool = DEV_SOURCE_MAPS;
  config.plugins = [getAotPlugin('client', AOT)];

  if (PROD) {
    config.plugins.push(
      new UglifyJsPlugin({
        beautify: false,
        comments: false
      })
    );
  }

  if (UNIVERSAL || SERVER) {
    config.plugins.push(
      new ScriptExtPlugin({
        defaultAttribute: 'defer'
      })
    );
  }

  if (DLL) {
    config.entry = {
      app_assets: ['./src/main.browser'],
      polyfill: [
        'sockjs-client',
        '@angularclass/hmr',
        'ts-helpers',
        'zone.js',
        'core-js/client/shim.js',
        'core-js/es6/reflect.js',
        'core-js/es7/reflect.js',
        'querystring-es3',
        'strip-ansi',
        'url',
        'punycode',
        'events',
        'web-animations-js/web-animations.min.js',
        'webpack-dev-server/client/socket.js',
        'webpack/hot/emitter.js',
        'zone.js/dist/long-stack-trace-zone.js',
        ...MY_POLYFILL_DLLS
      ],
      vendor: [...DLL_VENDORS]
    };
  } else {
    config.entry = {
      main: root('./src/main.browser.ts')
    };
  }

  if (!DLL) {
    config.output = {
      path: root('dist'),
      filename: 'index.js'
    };
  } else {
    config.output = {
      path: root('dll'),
      filename: '[name].dll.js',
      library: '[name]'
    };
  }

  config.devServer = {
    contentBase: AOT ? './compiled' : './src',
    port: CONSTANTS.PORT,
    historyApiFallback: {
      disableDotRule: true,
    },
    stats: 'minimal',
    host: '0.0.0.0',
    watchOptions: DEV_SERVER_WATCH_OPTIONS
  };

  if (USE_DEV_SERVER_PROXY) {
    Object.assign(config.devServer, {
      proxy: DEV_SERVER_PROXY_CONFIG
    });
  }

  config.performance = {
    hints: false
  };

  config.node = {
    global: true,
    process: true,
    Buffer: false,
    crypto: true,
    module: false,
    clearImmediate: false,
    setImmediate: false,
    clearTimeout: true,
    setTimeout: true
  };

  return config;

}();

const serverConfig: WebpackConfig = {
  target: 'node',
  entry: AOT ? './src/server.aot.ts' : root('./src/server.ts'),
  output: {
    filename: 'server.js',
    path: root('dist')
  },
  plugins: [
    getAotPlugin('server', AOT)
  ],
  module: {
    rules: [
      {
        test: /@angular(\\|\/)material/,
        loader: 'imports-loader',
        options: {
          window: '>global',
          'CSS': '>null',
          navigator: '>{get userAgent(){ return \'Chrome\'; }}',
          document: '>global.document',
        },
      },
    ]
  },

};

const defaultConfig = {
  resolve: {
    extensions: ['.ts', '.js', '.json']
  }
};

if (!UNIVERSAL && !SERVER) {
  DLL ? console.log('BUILDING DLLs') : console.log('BUILDING APP');
  module.exports = webpackMerge({}, defaultConfig, commonConfig, clientConfig);
} else if (SERVER) {
  module.exports = webpackMerge({}, defaultConfig, commonConfig, serverConfig);
} else {
  console.log('BUILDING UNIVERSAL');
  module.exports = [
    webpackMerge({}, defaultConfig, commonConfig, clientConfig),
    webpackMerge({}, defaultConfig, commonConfig, serverConfig)
  ];
}

/src/app/services/constants.ts

export const APP_SETTINGS = {
    MAKE_IT_ENVIRONMENT: '{{{MAKE_IT_ENVIRONMENT}}}',
    MAKE_IT_API_URL: '{{{MAKE_IT_API_URL}}}',
    MAKE_IT_CLIENT_SECRET: '{{{MAKE_IT_CLIENT_SECRET}}}',
    MAKE_IT_CLIENT_ID: '{{{MAKE_IT_CLIENT_ID}}}'
};

console.log('APP_SETTINGS', APP_SETTINGS); // returns the unreplaced variables like '{{{MAKE_IT_ENVIRONMENT}}}'

export const MOBILE = (typeof window !== 'undefined') ? (window.screen.availWidth < 800) : true;
export const API_BASE_URL: string = `http://${HOST}:${PORT}`;

npm log for npm run univeral:aot

info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.
yarn run v0.24.6
$ npm run build:universal:aot && npm run server:universal
npm info it worked if it ends with ok
npm info using npm@4.2.0
npm info using node@v7.8.0
npm info lifecycle angular-webpack2-starter@3.0.0~prebuild:universal:aot: angular-webpack2-starter@3.0.0
npm info lifecycle angular-webpack2-starter@3.0.0~build:universal:aot: angular-webpack2-starter@3.0.0

> angular-webpack2-starter@3.0.0 build:universal:aot /var/make-it.business/backend-application
> npm-run-all -p build:aot build:server:aot

npm info it worked if it ends with ok
npm info using npm@4.2.0
npm info using node@v7.8.0
npm info it worked if it ends with ok
npm info using npm@4.2.0
npm info using node@v7.8.0
npm info lifecycle angular-webpack2-starter@3.0.0~prebuild:aot: angular-webpack2-starter@3.0.0
npm info lifecycle angular-webpack2-starter@3.0.0~prebuild:server:aot: angular-webpack2-starter@3.0.0
npm info lifecycle angular-webpack2-starter@3.0.0~build:server:aot: angular-webpack2-starter@3.0.0
npm info lifecycle angular-webpack2-starter@3.0.0~build:aot: angular-webpack2-starter@3.0.0

> angular-webpack2-starter@3.0.0 build:server:aot /var/make-it.business/backend-application
> npm run build:server:aot:prod

> angular-webpack2-starter@3.0.0 build:aot /var/make-it.business/backend-application
> npm run build:aot:prod

npm info it worked if it ends with ok
npm info using npm@4.2.0
npm info using node@v7.8.0
npm info it worked if it ends with ok
npm info using npm@4.2.0
npm info using node@v7.8.0
npm info lifecycle angular-webpack2-starter@3.0.0~prebuild:aot:prod: angular-webpack2-starter@3.0.0
npm info lifecycle angular-webpack2-starter@3.0.0~build:aot:prod: angular-webpack2-starter@3.0.0

> angular-webpack2-starter@3.0.0 build:aot:prod /var/make-it.business/backend-application
> npm run clean:dist && npm run sass && webpack

npm info lifecycle angular-webpack2-starter@3.0.0~prebuild:server:aot:prod: angular-webpack2-starter@3.0.0
npm info lifecycle angular-webpack2-starter@3.0.0~build:server:aot:prod: angular-webpack2-starter@3.0.0

> angular-webpack2-starter@3.0.0 build:server:aot:prod /var/make-it.business/backend-application
> npm run sass && webpack

npm info it worked if it ends with ok
npm info using npm@4.2.0
npm info using node@v7.8.0
npm info it worked if it ends with ok
npm info using npm@4.2.0
npm info using node@v7.8.0
npm info lifecycle angular-webpack2-starter@3.0.0~presass: angular-webpack2-starter@3.0.0
npm info lifecycle angular-webpack2-starter@3.0.0~preclean:dist: angular-webpack2-starter@3.0.0
npm info lifecycle angular-webpack2-starter@3.0.0~sass: angular-webpack2-starter@3.0.0
npm info lifecycle angular-webpack2-starter@3.0.0~clean:dist: angular-webpack2-starter@3.0.0

> angular-webpack2-starter@3.0.0 sass /var/make-it.business/backend-application
> node-sass "src/app/styles.scss" "src/app/styles.css" --include-path node_modules --output-style compressed -q

> angular-webpack2-starter@3.0.0 clean:dist /var/make-it.business/backend-application
> npm run rimraf -- dist .awcache

npm info it worked if it ends with ok
npm info using npm@4.2.0
npm info using node@v7.8.0
npm info lifecycle angular-webpack2-starter@3.0.0~prerimraf: angular-webpack2-starter@3.0.0
npm info lifecycle angular-webpack2-starter@3.0.0~rimraf: angular-webpack2-starter@3.0.0

> angular-webpack2-starter@3.0.0 rimraf /var/make-it.business/backend-application
> rimraf "dist" ".awcache"

npm info lifecycle angular-webpack2-starter@3.0.0~postrimraf: angular-webpack2-starter@3.0.0
npm info ok
npm info lifecycle angular-webpack2-starter@3.0.0~postclean:dist: angular-webpack2-starter@3.0.0
npm info ok
npm info lifecycle angular-webpack2-starter@3.0.0~postsass: angular-webpack2-starter@3.0.0
npm info ok
npm info it worked if it ends with ok
npm info using npm@4.2.0
npm info using node@v7.8.0
npm info lifecycle angular-webpack2-starter@3.0.0~presass: angular-webpack2-starter@3.0.0
npm info lifecycle angular-webpack2-starter@3.0.0~sass: angular-webpack2-starter@3.0.0

> angular-webpack2-starter@3.0.0 sass /var/make-it.business/backend-application
> node-sass "src/app/styles.scss" "src/app/styles.css" --include-path node_modules --output-style compressed -q

npm info lifecycle angular-webpack2-starter@3.0.0~postsass: angular-webpack2-starter@3.0.0
npm info ok
CONFIG { MAKE_IT_ENVIRONMENT: 'development',
  MAKE_IT_API_URL: 'http://api.make-it.dev',
  MAKE_IT_CLIENT_SECRET: 'WJDFtymc0POFNfAHsV84R3bAbo1MIt4wRlrTxwIx',
  MAKE_IT_CLIENT_ID: '2' }
PATH /var/make-it.business/backend-application/src/app/services/constants.ts
TMP RULES [ { test: '/var/make-it.business/backend-application/src/app/services/constants.ts',
    loaders: '/var/make-it.business/backend-application/node_modules/string-replace-webpack-plugin/loader.js?id=79iq8tzv2b6snk9guc0p1a714i' } ]
CONFIG { MAKE_IT_ENVIRONMENT: 'development',
  MAKE_IT_API_URL: 'http://api.make-it.dev',
  MAKE_IT_CLIENT_SECRET: 'WJDFtymc0POFNfAHsV84R3bAbo1MIt4wRlrTxwIx',
  MAKE_IT_CLIENT_ID: '2' }
PATH /var/make-it.business/backend-application/src/app/services/constants.ts
TMP RULES [ { test: '/var/make-it.business/backend-application/src/app/services/constants.ts',
    loaders: '/var/make-it.business/backend-application/node_modules/string-replace-webpack-plugin/loader.js?id=7jy3jcdeuvu9d1sx1kf82p4x6r' } ]
PRODUCTION BUILD:  true
AOT:  true
full_config { module:
   { rules:
      [ [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object] ] },
  plugins:
   [ ProgressPlugin { profile: undefined, handler: undefined },
     CheckerPlugin {},
     DefinePlugin { definitions: [Object] },
     NamedModulesPlugin { options: {} },
     StringReplacePlugin {},
     { apply: [Function: apply] },
     { apply: [Function: apply] },
     NoEmitOnErrorsPlugin {},
     CompressionPlugin {
       asset: '[path].gz[query]',
       algorithm: [Function],
       filename: false,
       compressionOptions: [Object],
       test: /\.js$|\.html$/,
       threshold: 10240,
       minRatio: 0.8,
       deleteOriginalAssets: false } ] }
plugins [ ProgressPlugin { profile: undefined, handler: undefined },
  CheckerPlugin {},
  DefinePlugin {
    definitions:
     { AOT: true,
       DEV_SERVER: false,
       ENV: '"production"',
       HMR: false,
       HOST: '"172.17.0.2"',
       PORT: 8088,
       STORE_DEV_TOOLS: '"logger"',
       UNIVERSAL: true } },
  NamedModulesPlugin { options: {} },
  StringReplacePlugin {},
  { apply: [Function: apply] },
  { apply: [Function: apply] },
  NoEmitOnErrorsPlugin {},
  CompressionPlugin {
    asset: '[path].gz[query]',
    algorithm: [Function],
    filename: false,
    compressionOptions:
     { level: 9,
       flush: undefined,
       chunkSize: undefined,
       windowBits: undefined,
       memLevel: undefined,
       strategy: undefined,
       dictionary: undefined },
    test: /\.js$|\.html$/,
    threshold: 10240,
    minRatio: 0.8,
    deleteOriginalAssets: false } ]
rules [ { test: /\.js$/,
    loader: 'source-map-loader',
    exclude: [ [Object] ] },
  { test: /\.ts$/,
    loaders: [ '@ngtools/webpack' ],
    exclude: [ /\.(spec|e2e|d)\.ts$/ ] },
  { test: /\.json$/, loader: 'json-loader' },
  { test: /\.html/,
    loader: 'raw-loader',
    exclude: [ '/var/make-it.business/backend-application/src/index.html' ] },
  { test: /\.css$/, loader: 'raw-loader' },
  { test: /\.scss$/,
    loaders: [ 'to-string-loader', 'css-loader', 'sass-loader' ] },
  { test: '/var/make-it.business/backend-application/src/app/services/constants.ts',
    loaders: '/var/make-it.business/backend-application/node_modules/string-replace-webpack-plugin/loader.js?id=79iq8tzv2b6snk9guc0p1a714i' } ]
full_config { module:
   { rules:
      [ [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object] ] },
  plugins:
   [ ProgressPlugin { profile: undefined, handler: undefined },
     CheckerPlugin {},
     DefinePlugin { definitions: [Object] },
     NamedModulesPlugin { options: {} },
     StringReplacePlugin {},
     { apply: [Function: apply] },
     { apply: [Function: apply] },
     NoEmitOnErrorsPlugin {},
     CompressionPlugin {
       asset: '[path].gz[query]',
       algorithm: [Function],
       filename: false,
       compressionOptions: [Object],
       test: /\.js$|\.html$/,
       threshold: 10240,
       minRatio: 0.8,
       deleteOriginalAssets: false } ] }
PRODUCTION BUILD:  true
AOT:  true
full_config { module:
   { rules:
      [ [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object] ] },
  plugins:
   [ ProgressPlugin { profile: undefined, handler: undefined },
     CheckerPlugin {},
     DefinePlugin { definitions: [Object] },
     NamedModulesPlugin { options: {} },
     StringReplacePlugin {},
     { apply: [Function: apply] },
     { apply: [Function: apply] },
     NoEmitOnErrorsPlugin {},
     CompressionPlugin {
       asset: '[path].gz[query]',
       algorithm: [Function],
       filename: false,
       compressionOptions: [Object],
       test: /\.js$|\.html$/,
       threshold: 10240,
       minRatio: 0.8,
       deleteOriginalAssets: false } ] }
plugins [ ProgressPlugin { profile: undefined, handler: undefined },
  CheckerPlugin {},
  DefinePlugin {
    definitions:
     { AOT: true,
       DEV_SERVER: false,
       ENV: '"production"',
       HMR: false,
       HOST: '"172.17.0.2"',
       PORT: 8088,
       STORE_DEV_TOOLS: '"logger"',
       UNIVERSAL: false } },
  NamedModulesPlugin { options: {} },
  StringReplacePlugin {},
  { apply: [Function: apply] },
  { apply: [Function: apply] },
  NoEmitOnErrorsPlugin {},
  CompressionPlugin {
    asset: '[path].gz[query]',
    algorithm: [Function],
    filename: false,
    compressionOptions:
     { level: 9,
       flush: undefined,
       chunkSize: undefined,
       windowBits: undefined,
       memLevel: undefined,
       strategy: undefined,
       dictionary: undefined },
    test: /\.js$|\.html$/,
    threshold: 10240,
    minRatio: 0.8,
    deleteOriginalAssets: false } ]
rules [ { test: /\.js$/,
    loader: 'source-map-loader',
    exclude: [ [Object] ] },
  { test: /\.ts$/,
    loaders: [ '@ngtools/webpack' ],
    exclude: [ /\.(spec|e2e|d)\.ts$/ ] },
  { test: /\.json$/, loader: 'json-loader' },
  { test: /\.html/,
    loader: 'raw-loader',
    exclude: [ '/var/make-it.business/backend-application/src/index.html' ] },
  { test: /\.css$/, loader: 'raw-loader' },
  { test: /\.scss$/,
    loaders: [ 'to-string-loader', 'css-loader', 'sass-loader' ] },
  { test: '/var/make-it.business/backend-application/src/app/services/constants.ts',
    loaders: '/var/make-it.business/backend-application/node_modules/string-replace-webpack-plugin/loader.js?id=7jy3jcdeuvu9d1sx1kf82p4x6r' } ]
full_config { module:
   { rules:
      [ [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object],
        [Object] ] },
  plugins:
   [ ProgressPlugin { profile: undefined, handler: undefined },
     CheckerPlugin {},
     DefinePlugin { definitions: [Object] },
     NamedModulesPlugin { options: {} },
     StringReplacePlugin {},
     { apply: [Function: apply] },
     { apply: [Function: apply] },
     NoEmitOnErrorsPlugin {},
     CompressionPlugin {
       asset: '[path].gz[query]',
       algorithm: [Function],
       filename: false,
       compressionOptions: [Object],
       test: /\.js$|\.html$/,
       threshold: 10240,
       minRatio: 0.8,
       deleteOriginalAssets: false } ] }
BUILDING APP
  0% compiling 13% building modules 28/57 modules 29 active ...angular/router/@angu    19% building modules 79/104 modulesREPLACEMENT { match: '{{{MAKE_IT_ENVIRONMENT}}}', return: 'development' }
REPLACEMENT { match: '{{{MAKE_IT_API_URL}}}',
  return: 'http://api.make-it.dev' }
REPLACEMENT { match: '{{{MAKE_IT_CLIENT_SECRET}}}',
  return: 'WJDFtymc0POFNfAHsV84R3bAbo1MIt4wRlrTxwIx' }
REPLACEMENT { match: '{{{MAKE_IT_CLIENT_ID}}}', return: '2' }              53% building modules 372/517 modules 145 active ...les/@ngrx/router-store/src/connect.js 53% building modules 378/523 modules 145 active ...xjs/observable/ArrayLikeObservable.jsREPLACEMENT { match: '{{{MAKE_IT_ENVIRONMENT}}}', return: 'development' }
REPLACEMENT { match: '{{{MAKE_IT_API_URL}}}',
  return: 'http://api.make-it.dev' }
REPLACEMENT { match: '{{{MAKE_IT_CLIENT_SECRET}}}',
  return: 'WJDFtymc0POFNfAHsV84R3bAbo1MIt4wRlrTxwIx' }
REPLACEMENT { matc 64% building modules 464/510 modules 46 activ 69% building modules 719/722 modules 3 a 69% building modulHash: 0bc75261db11c53cc96ae ...finalhandler/node_modules/ms/index.js
Version: webpack 2.6.0
Time: 37891ms
                                                       Asset       Size  Chunks                    Chunk Names
                               assets/icon/browserconfig.xml  281 bytes          [emitted]
                                                   server.js    7.38 MB       0  [emitted]  [big]  main
                                                  index.html    1.76 kB          [emitted]
                        assets/icon/android-icon-144x144.png    9.49 kB          [emitted]
                        assets/icon/android-icon-192x192.png      12 kB          [emitted]
                          assets/icon/android-icon-36x36.png    4.37 kB          [emitted]
                          assets/icon/android-icon-48x48.png    4.83 kB          [emitted]
                          assets/icon/android-icon-96x96.png    7.21 kB          [emitted]
                          assets/icon/apple-icon-144x144.png    9.41 kB          [emitted]
                          assets/icon/android-icon-72x72.png    5.88 kB          [emitted]
                          assets/icon/apple-icon-120x120.png     8.2 kB          [emitted]
                          assets/icon/apple-icon-114x114.png    7.97 kB          [emitted]
                          assets/icon/apple-icon-180x180.png    11.6 kB          [emitted]
                            assets/icon/apple-icon-60x60.png    5.28 kB          [emitted]
                            assets/icon/apple-icon-72x72.png    5.88 kB          [emitted]
                            assets/icon/apple-icon-76x76.png     6.1 kB          [emitted]
                          assets/icon/apple-icon-152x152.png    9.84 kB          [emitted]
                            assets/icon/apple-icon-57x57.png    5.25 kB          [emitted]
                      assets/icon/apple-icon-precomposed.png    11.9 kB          [emitted]
                                  assets/icon/apple-icon.png    11.9 kB          [emitted]
                               assets/icon/favicon-16x16.png     3.4 kB          [emitted]
                                                server.js.gz    1.14 MB          [emitted]  [big]
                                     assets/icon/favicon.ico    1.15 kB          [emitted]
                               assets/icon/favicon-32x32.png    4.17 kB          [emitted]
                             assets/icon/ms-icon-150x150.png    9.65 kB          [emitted]
                             assets/icon/ms-icon-144x144.png    9.38 kB          [emitted]
                               assets/icon/favicon-96x96.png    6.97 kB          [emitted]
                             assets/icon/ms-icon-310x310.png    24.3 kB          [emitted]
                                 assets/img/make_it_logo.png    4.74 kB          [emitted]
                               assets/icon/ms-icon-70x70.png    5.76 kB          [emitted]
                     assets/img/stock/cloud_with_nothing.jpg     470 kB          [emitted]  [big]
                           assets/img/stock/default-apps.png    28.4 kB          [emitted]
                             assets/img/stock/responsive.png    22.4 kB          [emitted]
                                    assets/img/stock/seo.png     252 kB          [emitted]  [big]
assets/img/stock/wooden__table__with__laptop__and__paper.jpg    1.24 MB          [emitted]  [big]
                                               hammer.min.js    20.8 kB          [emitted]
                                           hammer.min.js.map    32.3 kB          [emitted]
                                                  styles.css    37.6 kB          [emitted]
                                                 favicon.ico    1.15 kB          [emitted]
                                           service-worker.js   44 bytes          [emitted]
                                               manifest.json  773 bytes          [emitted]
                                                  robots.txt   25 bytes          [emitted]
[./constants.js] ./constants.js 3.82 kB {0} [built]
[./node_modules/@angular/core/@angular/core.es5.js] ./~/@angular/core/@angular/core.es5.js 461 kB {0} [built]
[./node_modules/@angular/platform-browser/@angular/platform-browser.es5.js] ./~/@angular/platform-browser/@angular/platform-browser.es5.js 142 kB {0} [built]
[./node_modules/@ngrx/store/src/store.js] ./~/@ngrx/store/src/store.js 1.6 kB {0} [built]
[./node_modules/@nguniversal/express-engine/index.js] ./~/@nguniversal/express-engine/index.js 196 bytes {0} [built]
[./node_modules/compression/index.js] ./~/compression/index.js 5.76 kB {0} [built]
[./node_modules/express/index.js] ./~/express/index.js 224 bytes {0} [built]
[./node_modules/zone.js/dist/zone-node.js] ./~/zone.js/dist/zone-node.js 81.2 kB {0} [built]
[./src/ngfactory/app/server.app.module.ngfactory.ts] ./src/ngfactory/app/server.app.module.ngfactory.ts 50.4 kB {0} [built]
[./src/ngfactory/node_modules/@angular/material/typings/index.ngfactory.ts] ./src/ngfactory/~/@angular/material/typings/index.ngfactory.ts 572 kB {0} [built]
[./src/polyfills.server.ts] ./src/polyfills.server.ts 125 bytes {0} [built]
[./src/rxjs.imports.ts] ./src/rxjs.imports.ts 964 bytes {0} [built]
[./src/server.aot.ts] ./src/server.aot.ts 1.55 kB {0} [built]
[./src/server.routes.ts] ./src/server.routes.ts 240 bytes {0} [built]
[./src/server/app.ts] ./src/server/app.ts 222 bytes {0} [built]
    + 713 hidden modules

WARNING in ./~/express/lib/view.js
80:29-41 Critical dependency: the request of a dependency is an expression
Child src/app/app.component.html:
    [./src/app/app.component.html] ./src/app/app.component.html 450 bytes {0} [built]
Child src/app/components/topnav/topnav.template.html:
        + 1 hidden modules
Child src/app/features/store-devtools.component.html:
    [./src/app/features/store-devtools.component.html] ./src/app/features/store-devtools.component.html 172 bytes {0} [built]
Child src/app/components/sidenav/sidenav.template.html:
        + 1 hidden modules
Child src/app/pages/home/home.template.html:
    [./src/app/pages/home/home.template.html] ./src/app/pages/home/home.template.html 640 bytes {0} [built]
Child src/app/components/toasts/failure/failure-toast.template.html:
        + 1 hidden modules
Child src/app/components/toasts/success/success-toast.template.html:
        + 1 hidden modules
Child src/app/pages/quick-links/quick-links.template.html:
    [./src/app/pages/quick-links/quick-links.template.html] ./src/app/pages/quick-links/quick-links.template.html 3.93 kB {0} [built]
Child src/app/pages/login/login.template.html:
    [./src/app/pages/login/login.template.html] ./src/app/pages/login/login.template.html 1.62 kB {0} [built]
Child src/app/pages/user-settings/user-settings.template.html:
    [./src/app/pages/user-settings/user-settings.template.html] ./src/app/pages/user-settings/user-settings.template.html 1.96 kB {0} [built]
Child src/app/pages/contact/contact.template.html:
    [./src/app/pages/contact/contact.template.html] ./src/app/pages/contact/contact.template.html 11.3 kB {0} [built]
Child node_modules/flexboxgrid/dist/flexboxgrid.min.css:
    [./node_modules/flexboxgrid/dist/flexboxgrid.min.css] ./~/flexboxgrid/dist/flexboxgrid.min.css 12.3 kB {0} [built]
Child src/app/components/sidenav/sidenav.style.scss:
    [./node_modules/css-loader/lib/css-base.js] ./~/css-loader/lib/css-base.js 2.19 kB {0} [built]
        + 2 hidden modules
Child src/app/components/topnav/topnav.style.scss:
    [./node_modules/css-loader/lib/css-base.js] ./~/css-loader/lib/css-base.js 2.19 kB {0} [built]
        + 2 hidden modules
Child src/app/app.component.scss:
    [./node_modules/css-loader/index.js!./node_modules/sass-loader/lib/loader.js!./src/app/app.component.scss] ./~/css-loader!./~/sass-loader/lib/loader.js!./src/app/app.component.scss 3.94 kB {0} [built]
    [./node_modules/css-loader/lib/css-base.js] ./~/css-loader/lib/css-base.js 2.19 kB {0} [built]
    [./src/app/app.component.scss] ./src/app/app.component.scss 300 bytes {0} [built]
Child src/app/pages/quick-links/quick-links.style.scss:
    [./node_modules/css-loader/index.js!./node_modules/sass-loader/lib/loader.js!./src/app/pages/quick-links/quick-links.style.scss] ./~/css-loader!./~/sass-loader/lib/loader.js!./src/app/pages/quick-links/quick-links.style.scss 4.26 kB {0} [built]
    [./node_modules/css-loader/lib/css-base.js] ./~/css-loader/lib/css-base.js 2.19 kB {0} [built]
    [./src/app/pages/quick-links/quick-links.style.scss] ./src/app/pages/quick-links/quick-links.style.scss 316 bytes {0} [built]
Child src/app/pages/home/home.style.scss:
    [./node_modules/css-loader/index.js!./node_modules/sass-loader/lib/loader.js!./src/app/pages/home/home.style.scss] ./~/css-loader!./~/sass-loader/lib/loader.js!./src/app/pages/home/home.style.scss 3.93 kB {0} [built]
    [./node_modules/css-loader/lib/css-base.js] ./~/css-loader/lib/css-base.js 2.19 kB {0} [built]
    [./src/app/pages/home/home.style.scss] ./src/app/pages/home/home.style.scss 309 bytes {0} [built]
Child src/app/pages/login/login.style.scss:
    [./node_modules/css-loader/index.js!./node_modules/sass-loader/lib/loader.js!./src/app/pages/login/login.style.scss] ./~/css-loader!./~/sass-loader/lib/loader.js!./src/app/pages/login/login.style.scss 4.09 kB {0} [built]
    [./node_modules/css-loader/lib/css-base.js] ./~/css-loader/lib/css-base.js 2.19 kB {0} [built]
    [./src/app/pages/login/login.style.scss] ./src/app/pages/login/login.style.scss 310 bytes {0} [built]
Child src/app/pages/user-settings/user-settings.style.scss:
    [./node_modules/css-loader/index.js!./node_modules/sass-loader/lib/loader.js!./src/app/pages/user-settings/user-settings.style.scss] ./~/css-loader!./~/sass-loader/lib/loader.js!./src/app/pages/user-settings/user-settings.style.scss 4.36 kB {0} [built]
    [./node_modules/css-loader/lib/css-base.js] ./~/css-loader/lib/css-base.js 2.19 kB {0} [built]
    [./src/app/pages/user-settings/user-settings.style.scss] ./src/app/pages/user-settings/user-settings.style.scss 318 bytes {0} [built]
Child src/app/components/toasts/failure/failure-toast.style.scss:
    [./node_modules/css-loader/lib/css-base.js] ./~/css-loader/lib/css-base.js 2.19 kB {0} [built]
        + 2 hidden modules
Child src/app/pages/contact/contact.style.scss:
    [./node_modules/css-loader/index.js!./node_modules/sass-loader/lib/loader.js!./src/app/pages/contact/contact.style.scss] ./~/css-loader!./~/sass-loader/lib/loader.js!./src/app/pages/contact/contact.style.scss 4.71 kB {0} [built]
    [./node_modules/css-loader/lib/css-base.js] ./~/css-loader/lib/css-base.js 2.19 kB {0} [built]
    [./src/app/pages/contact/contact.style.scss] ./src/app/pages/contact/contact.style.scss 312 bytes {0} [built]
Child src/app/components/toasts/success/success-toast.style.scss:
    [./node_modules/css-loader/lib/css-base.js] ./~/css-loader/lib/css-base.js 2.19 kB {0} [built]
        + 2 hidden modules                                                                             88% chunk asset npm info lifecycle angular-webpack2-starter@3.0.0~postbuild:server:aot:prod: angular-webpack2-starter@3.0.0
npm info ok
npm info lifecycle angular-webpack2-starter@3.0.0~postbuild:server:aot: angular-webpack2-starter@3.0.0
npm info ok

What version of the string-replace-webpack-plugin are you using? Also, the documentation of the plugin says you need to use the loader config in webpack, yet we use the rules? Is it maybe a problem there?

Thanks in advance, NickvdMeij

ValentinFunk commented 7 years ago

Think you can use it for both. In your constants.js make sure the enforce: 'pre', is present in the rule. It doesn't seem to work well with universal like this though.

I've just switched to DefinePlugin which works great and doesn't require an additional plugin. It even works great with dotenv. Try this:

constants.js:

const DefinePlugin = require('webpack').DefinePlugin;
require('dotenv').config();

const MY_ENV = {
  CLIENT_ID: process.env.CLIENT_ID
}
exports.MY_CLIENT_PLUGINS = [
  new DefinePlugin(MY_ENV ),
];

custom-typings.d.ts

declare var CLIENT_ID: string; // you can also use any if you pass in objects

any-of-your.ts

console.log(CLIENT_ID);

Keep in mind it's injected at build time.

NickvdMeij commented 7 years ago

@Kamshak @qdouble sorry for the late reaction, had some stuff I needed to take care of in real life first.

After a few hours of more debugging, I narrowed the problem down to 1 problem that I can't seem te get rid of when adding more environment variables.

First of all, using the Define Plugin works like a charm. At the moment I use the CONSTANTS variable in webpack.config.js, since these are already used in a define plugin thats get put in the same array as MY_CLIENT_PLUGINS.

Second of all, when I build the application, I get the correct environment variables printed out when i console.log them, which is great because this means they get set correctly.

However, when I add the source code needed to get this to work (the new code in webpack.config.ts, the lines in the custom-typings.d.ts and the location in my own code where I need the environment variables, a total of +- 10 lines of code) I get an error from UglifyJS saying the following:

ERROR in index.js from UglifyJs
Unexpected token punc «:», expected punc «,» [index.js:104493,26]

However, it doesn't specify which index.js, of where to find it (and I think it doesnt even exist, since the largest index.js I could find in the whole source code was +- 20k lines long). Furthermore, it doesn't specify where the error is coming from... Furthermore, when I remove the lines I wrote to get the environment variables to work (or when I comment them out), the error disappears and the build is successful and the application runs like a charm, which would indicate that the syntax error is somewhere within my code.

Now here comes the tricky part, I don't think there are any syntax errors in the code I wrote. I checked it multiple times, and also ran a codelyzer and default linting, but there seems to be nothing wrong at all...

Here are the tiles I added or modified that I made changes to: webpack.config.ts

...
if (DEV_SERVER) {
  testDll();
  console.log(`Starting dev server on: http://${HOST}:${PORT}`);
}

const CONSTANTS = {
  AOT: AOT,
  DEV_SERVER: DEV_SERVER,
  ENV: PROD ? JSON.stringify('production') : JSON.stringify('development'),
  HMR: HMR,
  HOST: JSON.stringify(HOST),
  PORT: PORT,
  STORE_DEV_TOOLS: JSON.stringify(STORE_DEV_TOOLS),
  UNIVERSAL: UNIVERSAL || SERVER,
  MAKE_IT_ENVIRONMENT: process.env.MAKE_IT_ENVIRONMENT, //added this line
  MAKE_IT_API_URL: process.env.MAKE_IT_API_URL //and this one
};

const DLL_VENDORS = [
  '@angular/common',
  '@angular/compiler',
...

custom.typings.ts

...

declare var UNIVERSAL: boolean;

declare var MAKE_IT_ENVIRONMENT: string; //added this line
declare var MAKE_IT_API_URL: string; //and this one

interface SystemJS {
...

constants.ts (my own code)

export const API_SETTINGS = {
    MAKE_IT_ENVIRONMENT: MAKE_IT_ENVIRONMENT,
    MAKE_IT_API_URL: MAKE_IT_API_URL
};

Do you guys have any idea what might be wrong with it?... Hopefully a fresh pair of eyes might solve the problem. Thanks in advance!

ValentinFunk commented 7 years ago

The DefinePlugin replaces the text in the sourcecode, say you have

this.apiUrl = MAKE_IT_API_URL;

and in your webpack config

MAKE_IT_API_URL: 'https://myapi.com'

the code becomes (note the missing string quotes)

this.apiUrl = https://myapi.com

To solve this you can simply stringify the value as JSON so it becomes valid JS.

MAKE_IT_API_URL: JSON.stringify('https://myapi.com')
NickvdMeij commented 7 years ago

Awesome! This indeed fixes the problem :). I discovered this last night (at 3AM in the morning) as well. It works like a charm now! I'll make a pull request later tonight adding some lines to the documentation about this, so people can easily add environment variables ;-). Thanks for all the help guys, really appreciated!