diff --git a/addon/ng2/blueprints/ng2/files/config/environment.dev.ts b/addon/ng2/blueprints/ng2/files/__path__/app/environments/environment.dev.ts similarity index 100% rename from addon/ng2/blueprints/ng2/files/config/environment.dev.ts rename to addon/ng2/blueprints/ng2/files/__path__/app/environments/environment.dev.ts diff --git a/addon/ng2/blueprints/ng2/files/config/environment.prod.ts b/addon/ng2/blueprints/ng2/files/__path__/app/environments/environment.prod.ts similarity index 100% rename from addon/ng2/blueprints/ng2/files/config/environment.prod.ts rename to addon/ng2/blueprints/ng2/files/__path__/app/environments/environment.prod.ts diff --git a/addon/ng2/blueprints/ng2/files/__path__/app/environment.ts b/addon/ng2/blueprints/ng2/files/__path__/app/environments/environment.ts similarity index 100% rename from addon/ng2/blueprints/ng2/files/__path__/app/environment.ts rename to addon/ng2/blueprints/ng2/files/__path__/app/environments/environment.ts diff --git a/addon/ng2/blueprints/ng2/files/__path__/app/index.ts b/addon/ng2/blueprints/ng2/files/__path__/app/index.ts index 30c9dfb021b8..7aa84b623989 100644 --- a/addon/ng2/blueprints/ng2/files/__path__/app/index.ts +++ b/addon/ng2/blueprints/ng2/files/__path__/app/index.ts @@ -1,2 +1,2 @@ -export * from './environment'; +export * from './environments/environment'; export * from './app.component'; diff --git a/addon/ng2/models/webpack-config.ts b/addon/ng2/models/webpack-config.ts index e5cd3e00f294..95e3ddb3d0d6 100644 --- a/addon/ng2/models/webpack-config.ts +++ b/addon/ng2/models/webpack-config.ts @@ -1,4 +1,5 @@ import { CliConfig } from './config'; +import { NgCliEnvironmentPlugin } from '../utilities/environment-plugin'; import { getWebpackCommonConfig, getWebpackDevConfigPartial, @@ -35,6 +36,7 @@ export class NgCliWebpackConfig { } this.generateConfig(); + this.config.plugins.unshift(new NgCliEnvironmentPlugin({env: this.environment})); } generateConfig(): void { @@ -59,4 +61,3 @@ export class NgCliWebpackConfig { } } } - diff --git a/addon/ng2/utilities/environment-plugin.ts b/addon/ng2/utilities/environment-plugin.ts new file mode 100644 index 000000000000..6825769d8f95 --- /dev/null +++ b/addon/ng2/utilities/environment-plugin.ts @@ -0,0 +1,79 @@ +import * as fs from 'fs'; + +interface WebpackPlugin { + apply(compiler: any): void; +} + +export class NgCliEnvironmentPlugin implements WebpackPlugin { + _file: string; + _alias: string; + _env: string; + + constructor(config: any) { + if (typeof config === 'string') { + config = {env: config}; + } + if (typeof config.env !== 'string') { + throw new Error('must provide env') + } + const ALIAS = { + '"dev"': 'dev', + 'development': 'dev', + '"development"': 'dev', + '"prod"': 'prod', + 'production': 'prod', + '"production"': 'prod', + '"test"': 'test', + 'testing': 'test', + '"testing"': 'test', + }; + const ENV = config.env.toLowerCase(); + + this._file = config.file || 'environment'; + this._alias = config.alias || ALIAS; + this._env = this._alias[ENV] || ENV; + } + + isEnvFile(file: string): boolean { + return file.indexOf(this._file + '.') !== -1; + } + + replaceFile(file: string): any { + return file + .replace(this._file, this._file + '.' + this._env); + } + + updateResult(result: any): any { + ['request', 'userRequest', 'resource'] + .filter((key) => { return result[key]; }) + .forEach((key) => { + result[key] = this.replaceFile(result[key]); + }); + + return result; + } + + apply(compiler: any): void { + compiler.plugin('normal-module-factory', (normalModuleFactory: any) => { + normalModuleFactory.plugin('after-resolve', (result, callback) => { + var _resource = result['resource']; + if (!this.isEnvFile(_resource)) { + return callback(null, result); + } + var envFile = this.replaceFile(_resource); + + fs.stat(envFile, (err, stats) => { + if (err || !stats.isFile()) { + var errorText = (!err && stats.isFile()) ? 'Is not a file.' : 'Does not exist.'; + console.log('\nWARNING:\n' + envFile + '\n' + errorText + ' ' + 'Using file\n' + _resource + '\n'); + return callback(null, result); + } + // mutate result + var newResult = this.updateResult(result); + return callback(null, newResult); + }); + + }); + }); + } +} diff --git a/tests/e2e/e2e_workflow.spec.js b/tests/e2e/e2e_workflow.spec.js index 3864e7fc9c89..053a4d714360 100644 --- a/tests/e2e/e2e_workflow.spec.js +++ b/tests/e2e/e2e_workflow.spec.js @@ -82,13 +82,6 @@ describe('Basic end-to-end Workflow', function () { expect(sh.exec('git status --porcelain').output).to.be.equal(undefined); }); - xit('Supports production builds config file replacement', function() { - var mainBundlePath = path.join(process.cwd(), 'dist', 'main.js'); - var mainBundleContent = fs.readFileSync(mainBundlePath, { encoding: 'utf8' }); - // production: true minimized turns into production:!0 - expect(mainBundleContent).to.include('production:!0'); - }); - it_mobile('Enables mobile-specific production features in prod builds', () => { let indexHtml = fs.readFileSync(path.join(process.cwd(), 'dist/index.html'), 'utf-8'); // Service Worker @@ -106,6 +99,16 @@ describe('Basic end-to-end Workflow', function () { expect(indexHtml).to.match(/app works!/); }); + it('Supports build config file replacement', function() { + this.timeout(420000); + + sh.exec(`${ngBin} build --dev`); + var mainBundlePath = path.join(process.cwd(), 'dist', 'main.bundle.js'); + var mainBundleContent = fs.readFileSync(mainBundlePath, { encoding: 'utf8' }); + + expect(mainBundleContent).to.include('production: false'); + }); + it('Can run `ng build` in created project', function () { this.timeout(420000);