Skip to content

Commit

Permalink
feat(@angular/cli): add ngo support
Browse files Browse the repository at this point in the history
  • Loading branch information
filipesilva committed Jul 2, 2017
1 parent 64e6b94 commit 07a0630
Show file tree
Hide file tree
Showing 10 changed files with 81 additions and 13 deletions.
10 changes: 10 additions & 0 deletions docs/documentation/build.md
Original file line number Diff line number Diff line change
Expand Up @@ -322,3 +322,13 @@ Note: service worker support is experimental and subject to change.
Show circular dependency warnings on builds.
</p>
</details>

<details>
<summary>ngo</summary>
<p>
<code>--ngo</code>
</p>
<p>
Enables NGO optimizations when using `--aot`.
</p>
</details>
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@
"magic-string": "^0.19.0",
"memory-fs": "^0.4.1",
"minimatch": "^3.0.3",
"ngo-loader": "github:angular/ngo",
"node-modules-path": "^1.0.0",
"nopt": "^4.0.1",
"opn": "4.0.2",
Expand Down
29 changes: 22 additions & 7 deletions packages/@angular/cli/commands/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ export const baseBuildCommandOptions: any = [
{
name: 'environment',
type: String,
aliases: ['e'] ,
aliases: ['e'],
description: 'Defines the build environment.'
},
{
Expand All @@ -43,7 +43,6 @@ export const baseBuildCommandOptions: any = [
{
name: 'vendor-chunk',
type: Boolean,
default: true,
aliases: ['vc'],
description: 'Use a separate bundle containing only vendor libraries.'
},
Expand Down Expand Up @@ -144,6 +143,12 @@ export const baseBuildCommandOptions: any = [
type: Boolean,
aliases: ['scd'],
description: 'Show circular dependency warnings on builds.'
},
{
name: 'ngo',
type: Boolean,
default: false,
description: 'Enables NGO optimizations when using `--aot`.'
}
];

Expand All @@ -158,15 +163,25 @@ const BuildCommand = Command.extend({

availableOptions: baseBuildCommandOptions.concat([
{
name: 'stats-json',
type: Boolean,
default: false,
description: oneLine`Generates a \`stats.json\` file which can be analyzed using tools
name: 'stats-json',
type: Boolean,
default: false,
description: oneLine`Generates a \`stats.json\` file which can be analyzed using tools
such as: \`webpack-bundle-analyzer\` or https://webpack.github.io/analyse.`
}
}
]),

run: function (commandOptions: BuildTaskOptions) {

// Remove vendor chunk if undefined and --ngo if on.
if (commandOptions.vendorChunk === undefined) {
if (commandOptions.ngo) {
commandOptions.vendorChunk = false;
} else {
commandOptions.vendorChunk = true;
}
}

// Check angular version.
Version.assertAngularVersionIs2_3_1OrHigher(this.project.root);

Expand Down
1 change: 1 addition & 0 deletions packages/@angular/cli/models/build-options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,5 @@ export interface BuildOptions {
preserveSymlinks?: boolean;
extractLicenses?: boolean;
showCircularDependencies?: boolean;
ngo?: boolean;
}
4 changes: 4 additions & 0 deletions packages/@angular/cli/models/webpack-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,10 @@ export class NgCliWebpackConfig {
if (buildOptions.target !== 'development' && buildOptions.target !== 'production') {
throw new Error("Invalid build target. Only 'development' and 'production' are available.");
}

if (buildOptions.ngo && !(buildOptions.aot || buildOptions.target === 'production')) {
throw new Error('The `--ngo` option cannot be used without `--aot` (or `--prod`).');
}
}

// Fill in defaults for build targets
Expand Down
11 changes: 11 additions & 0 deletions packages/@angular/cli/models/webpack-configs/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ const CircularDependencyPlugin = require('circular-dependency-plugin');
* require('json-loader')
* require('url-loader')
* require('file-loader')
* require('ngo-loader')
*/

export function getCommonConfig(wco: WebpackConfigOptions) {
Expand Down Expand Up @@ -79,6 +80,16 @@ export function getCommonConfig(wco: WebpackConfigOptions) {
}));
}

if (buildOptions.ngo) {
extraRules.push({
test: /\.js$/,
use: [{
loader: 'ngo-loader',
options: { sourceMap: buildOptions.sourcemaps }
}]
});
}

return {
resolve: {
extensions: ['.ts', '.js'],
Expand Down
15 changes: 12 additions & 3 deletions packages/@angular/cli/models/webpack-configs/production.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { StaticAssetPlugin } from '../../plugins/static-asset';
import { GlobCopyWebpackPlugin } from '../../plugins/glob-copy-webpack-plugin';
import { WebpackConfigOptions } from '../webpack-config';

const PurifyPlugin = require('ngo-loader').PurifyPlugin;
const licensePlugin = require('license-webpack-plugin');

export const getProdConfig = function (wco: WebpackConfigOptions) {
Expand Down Expand Up @@ -91,19 +92,27 @@ export const getProdConfig = function (wco: WebpackConfigOptions) {
}));
}

const uglifyCompressOptions: any = { screw_ie8: true, warnings: buildOptions.verbose };

if (buildOptions.ngo) {
// This plugin must be before webpack.optimize.UglifyJsPlugin.
extraPlugins.push(new PurifyPlugin());
uglifyCompressOptions.pure_getters = true;
}

return {
entry: entryPoints,
plugins: [
plugins: extraPlugins.concat([
new webpack.EnvironmentPlugin({
'NODE_ENV': 'production'
}),
new (<any>webpack).HashedModuleIdsPlugin(),
new webpack.optimize.UglifyJsPlugin(<any>{
mangle: { screw_ie8: true },
compress: { screw_ie8: true, warnings: buildOptions.verbose },
compress: uglifyCompressOptions,
sourceMap: buildOptions.sourcemaps,
comments: false
})
].concat(extraPlugins)
])
};
};
13 changes: 10 additions & 3 deletions packages/@angular/cli/models/webpack-configs/typescript.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,6 @@ function _createAotPlugin(wco: WebpackConfigOptions, options: any) {
}, options));
}


export const getNonAotConfig = function(wco: WebpackConfigOptions) {
const { appConfig, projectRoot } = wco;
const tsConfigPath = path.resolve(projectRoot, appConfig.root, appConfig.tsconfig);
Expand All @@ -86,7 +85,7 @@ export const getNonAotConfig = function(wco: WebpackConfigOptions) {
};

export const getAotConfig = function(wco: WebpackConfigOptions) {
const { projectRoot, appConfig } = wco;
const { projectRoot, buildOptions, appConfig } = wco;
const tsConfigPath = path.resolve(projectRoot, appConfig.root, appConfig.tsconfig);
const testTsConfigPath = path.resolve(projectRoot, appConfig.root, appConfig.testTsconfig);

Expand All @@ -99,8 +98,16 @@ export const getAotConfig = function(wco: WebpackConfigOptions) {
pluginOptions.exclude = exclude;
}

let ngoLoader: any = [];
if (buildOptions.ngo) {
ngoLoader = [{
loader: 'ngo-loader',
options: { sourceMap: buildOptions.sourcemaps }
}];
}

return {
module: { rules: [{ test: /\.ts$/, loader: webpackLoader }] },
module: { rules: [{ test: /\.ts$/, use: [...ngoLoader, webpackLoader] }] },
plugins: [ _createAotPlugin(wco, pluginOptions) ]
};
};
Expand Down
1 change: 1 addition & 0 deletions packages/@angular/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@
"lodash": "^4.11.1",
"memory-fs": "^0.4.1",
"minimatch": "^3.0.3",
"ngo-loader": "github:angular/ngo",
"node-modules-path": "^1.0.0",
"nopt": "^4.0.1",
"opn": "4.0.2",
Expand Down
9 changes: 9 additions & 0 deletions tests/e2e/tests/build/ngo.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { ng } from '../../utils/process';
import { expectFileToMatch } from '../../utils/fs';
import { expectToFail } from '../../utils/utils';


export default function () {
return ng('build', '--aot', '--ngo')
.then(() => expectToFail(() => expectFileToMatch('dist/vendor.js', /\.decorators =/)));
}

0 comments on commit 07a0630

Please sign in to comment.