Skip to content

Commit

Permalink
feat(build): auto generate vendor chunk
Browse files Browse the repository at this point in the history
Add `--vendor-chunk` option to `ng build/serve`.

Enabling vendor chunk can help with rebuild speeds. My tests on a medium project show a 34% improvement on rebuild.

This option is enabled by default on `ng serve`, and disabled by default on `ng build`.

Partially address #1980
  • Loading branch information
filipesilva committed Nov 17, 2016
1 parent 6f9d2c1 commit 00b64a6
Show file tree
Hide file tree
Showing 9 changed files with 57 additions and 13 deletions.
4 changes: 3 additions & 1 deletion packages/angular-cli/commands/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export interface BuildOptions {
baseHref?: string;
aot?: boolean;
sourcemap?: boolean;
vendorChunk?: boolean;
}

const BuildCommand = Command.extend({
Expand All @@ -33,7 +34,8 @@ const BuildCommand = Command.extend({
{ name: 'suppress-sizes', type: Boolean, default: false },
{ name: 'base-href', type: String, default: null, aliases: ['bh'] },
{ name: 'aot', type: Boolean, default: false },
{ name: 'sourcemap', type: Boolean, default: true, aliases: ['sm'] }
{ name: 'sourcemap', type: Boolean, default: true, aliases: ['sm'] },
{ name: 'vendor-chunk', type: Boolean, default: false }
],

run: function (commandOptions: BuildOptions) {
Expand Down
2 changes: 2 additions & 0 deletions packages/angular-cli/commands/serve.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export interface ServeTaskOptions {
aot?: boolean;
sourcemap?: boolean;
open?: boolean;
vendorChunk?: boolean;
}

const ServeCommand = Command.extend({
Expand Down Expand Up @@ -83,6 +84,7 @@ const ServeCommand = Command.extend({
{ name: 'ssl-cert', type: String, default: 'ssl/server.crt' },
{ name: 'aot', type: Boolean, default: false },
{ name: 'sourcemap', type: Boolean, default: true, aliases: ['sm'] },
{ name: 'vendor-chunk', type: Boolean, default: true },
{
name: 'open',
type: Boolean,
Expand Down
23 changes: 15 additions & 8 deletions packages/angular-cli/models/webpack-build-common.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import * as webpack from 'webpack';
import * as path from 'path';
import {GlobCopyWebpackPlugin} from '../plugins/glob-copy-webpack-plugin';
import {packageChunkSort} from '../utilities/package-chunk-sort';
import {BaseHrefWebpackPlugin} from '@angular-cli/base-href-webpack';

const HtmlWebpackPlugin = require('html-webpack-plugin');
Expand All @@ -12,7 +13,8 @@ export function getWebpackCommonConfig(
environment: string,
appConfig: any,
baseHref: string,
sourcemap: boolean
sourcemap: boolean,
vendorChunk: boolean
) {

const appRoot = path.resolve(projectRoot, appConfig.root);
Expand All @@ -23,6 +25,7 @@ export function getWebpackCommonConfig(
const scripts = appConfig.scripts
? appConfig.scripts.map((script: string) => path.resolve(appRoot, script))
: [];
const extraPlugins: any[] = [];

let entry: { [key: string]: string[] } = {
main: [appMain]
Expand All @@ -32,6 +35,14 @@ export function getWebpackCommonConfig(
if (appConfig.styles.length > 0) { entry['styles'] = styles; }
if (appConfig.scripts.length > 0) { entry['scripts'] = scripts; }

if (vendorChunk) {
extraPlugins.push(new webpack.optimize.CommonsChunkPlugin({
name: 'vendor',
chunks: ['main'],
minChunks: (module: any) => module.userRequest && !module.userRequest.includes(appRoot)
}));
}

return {
devtool: sourcemap ? 'source-map' : 'eval',
resolve: {
Expand Down Expand Up @@ -91,7 +102,7 @@ export function getWebpackCommonConfig(
new HtmlWebpackPlugin({
template: path.resolve(appRoot, appConfig.index),
filename: path.resolve(appConfig.outDir, appConfig.index),
chunksSortMode: 'dependency'
chunksSortMode: packageChunkSort(['inline', 'styles', 'scripts', 'vendor', 'main'])
}),
new BaseHrefWebpackPlugin({
baseHref: baseHref
Expand All @@ -104,10 +115,6 @@ export function getWebpackCommonConfig(
.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, '\\$&')),
path.resolve(appRoot, appConfig.environments[environment])
),
new webpack.optimize.CommonsChunkPlugin({
// Optimizing ensures loading order in index.html
name: ['styles', 'scripts', 'main'].reverse()
}),
new webpack.optimize.CommonsChunkPlugin({
minChunks: Infinity,
name: 'inline'
Expand All @@ -121,8 +128,8 @@ export function getWebpackCommonConfig(
options: {
postcss: [ autoprefixer() ]
},
}),
],
})
].concat(extraPlugins),
node: {
fs: 'empty',
global: true,
Expand Down
4 changes: 3 additions & 1 deletion packages/angular-cli/models/webpack-config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export class NgCliWebpackConfig {
baseHref?: string,
isAoT = false,
sourcemap = true,
vendorChunk = false,
) {
const config: CliConfig = CliConfig.fromProject();
const appConfig = config.config.apps[0];
Expand All @@ -36,7 +37,8 @@ export class NgCliWebpackConfig {
environment,
appConfig,
baseHref,
sourcemap
sourcemap,
vendorChunk
);
let targetConfigPartial = this.getTargetConfig(this.ngCliProject.root, appConfig);
const typescriptConfigPartial = isAoT
Expand Down
3 changes: 2 additions & 1 deletion packages/angular-cli/tasks/build-webpack-watch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ export default Task.extend({
outputDir,
runTaskOptions.baseHref,
runTaskOptions.aot,
runTaskOptions.sourcemap
runTaskOptions.sourcemap,
runTaskOptions.vendorChunk
).config;
const webpackCompiler: any = webpack(config);

Expand Down
3 changes: 2 additions & 1 deletion packages/angular-cli/tasks/build-webpack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ export default <any>Task.extend({
outputDir,
runTaskOptions.baseHref,
runTaskOptions.aot,
runTaskOptions.sourcemap
runTaskOptions.sourcemap,
runTaskOptions.vendorChunk
).config;

const webpackCompiler: any = webpack(config);
Expand Down
3 changes: 2 additions & 1 deletion packages/angular-cli/tasks/serve-webpack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ export default Task.extend({
undefined,
undefined,
commandOptions.aot,
commandOptions.sourcemap
commandOptions.sourcemap,
commandOptions.vendorChunk
).config;

// This allows for live reload of page when changes are made to repo.
Expand Down
17 changes: 17 additions & 0 deletions packages/angular-cli/utilities/package-chunk-sort.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
export function packageChunkSort(packages: string[]) {
return function sort(left: any, right: any) {
let leftIndex = packages.indexOf(left.names[0]);
let rightindex = packages.indexOf(right.names[0]);

if ( leftIndex < 0 || rightindex < 0) {
// Unknown packages are loaded last
return 1;
}

if (leftIndex > rightindex) {
return 1;
}

return -1;
};
}
11 changes: 11 additions & 0 deletions tests/e2e/tests/build/vendor-chunk.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import {ng} from '../../utils/process';
import {expectFileToExist} from '../../utils/fs';
import {expectToFail} from '../../utils/utils';


export default function() {
return ng('build', '--vendor-chunk')
.then(() => expectFileToExist('dist/vendor.bundle.js'))
.then(() => ng('build'))
.then(() => expectToFail(() => expectFileToExist('dist/vendor.bundle.js')));
}

0 comments on commit 00b64a6

Please sign in to comment.