Skip to content

Commit

Permalink
feat(@angular/cli): name lazy chunks
Browse files Browse the repository at this point in the history
Before:
```
$ ng build --no-progress
Hash: ff03df269349b817eef4
Time: 11202ms
chunk    {0} 0.chunk.js, 0.chunk.js.map 1.61 kB {1} {3} [rendered]
chunk    {1} 1.chunk.js, 1.chunk.js.map 1.46 kB {0} {3} [rendered]
chunk    {2} polyfills.bundle.js, polyfills.bundle.js.map (polyfills) 160 kB {6} [initial] [rendered]
chunk    {3} main.bundle.js, main.bundle.js.map (main) 6.38 kB {5} [initial] [rendered]
chunk    {4} styles.bundle.js, styles.bundle.js.map (styles) 10.5 kB {6} [initial] [rendered]
chunk    {5} vendor.bundle.js, vendor.bundle.js.map (vendor) 2.16 MB [initial] [rendered]
chunk    {6} inline.bundle.js, inline.bundle.js.map (inline) 0 bytes [entry] [rendered]
```

After:
```
$ ng build --no-progress
Hash: 2bc12a89f40f3b4818b5
Time: 9613ms
chunk {feature.module} feature.module.chunk.js, feature.module.chunk.js.map 1.46 kB {lazy.module} {main} [rendered]
chunk {inline} inline.bundle.js, inline.bundle.js.map (inline) 0 bytes [entry] [rendered]
chunk {lazy.module} lazy.module.chunk.js, lazy.module.chunk.js.map 1.61 kB {feature.module} {main} [rendered]
chunk {main} main.bundle.js, main.bundle.js.map (main) 6.38 kB {vendor} [initial] [rendered]
chunk {polyfills} polyfills.bundle.js, polyfills.bundle.js.map (polyfills) 160 kB {inline} [initial] [rendered]
chunk {styles} styles.bundle.js, styles.bundle.js.map (styles) 10.5 kB {inline} [initial] [rendered]
chunk {vendor} vendor.bundle.js, vendor.bundle.js.map (vendor) 2.16 MB [initial] [rendered]
```

Fix angular#6700
  • Loading branch information
filipesilva committed Jul 4, 2017
1 parent 64e6b94 commit de63632
Show file tree
Hide file tree
Showing 6 changed files with 60 additions and 3 deletions.
4 changes: 3 additions & 1 deletion packages/@angular/cli/models/webpack-configs/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 { NamedLazyChunksWebpackPlugin } from '../../plugins/named-lazy-chunks-webpack-plugin';
import { extraEntryParser, getOutputHashFormat } from './utils';
import { WebpackConfigOptions } from '../webpack-config';

Expand Down Expand Up @@ -109,7 +110,8 @@ export function getCommonConfig(wco: WebpackConfigOptions) {
].concat(extraRules)
},
plugins: [
new webpack.NoEmitOnErrorsPlugin()
new webpack.NoEmitOnErrorsPlugin(),
new NamedLazyChunksWebpackPlugin(),
].concat(extraPlugins),
node: {
fs: 'empty',
Expand Down
41 changes: 41 additions & 0 deletions packages/@angular/cli/plugins/named-lazy-chunks-webpack-plugin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import * as webpack from 'webpack';


// This just extends webpack.NamedChunksPlugin to prevent name collisions.
export class NamedLazyChunksWebpackPlugin extends webpack.NamedChunksPlugin {
constructor() {
const nameMap = new Map();
// Append a dot and number if the name already exists.
const getNextName = (baseName: string) => {
let num: number | null = null;
const name = () => num !== null ? `${baseName}.${num}` : baseName;
while (nameMap.has(name())) {
num = num ? num++ : 0;
}
nameMap.set(name(), true);
return name();
};

const nameResolver = (chunk: any) => {
// Entry chunks have a name already, use it.
if (chunk.name) {
return chunk.name;
}

// Try to figure out if it's a lazy loaded route.
if (chunk.blocks
&& chunk.blocks.length > 0
&& chunk.blocks[0].dependencies
&& chunk.blocks[0].dependencies.length > 0
&& chunk.blocks[0].dependencies[0].lazyRouteChunkName
) {
// lazyRouteChunkName was added by @ngtools/webpack.
return getNextName(chunk.blocks[0].dependencies[0].lazyRouteChunkName);
}

return null;
};

super(nameResolver);
}
}
4 changes: 3 additions & 1 deletion packages/@angular/cli/plugins/webpack.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,7 @@ module.exports = {
GlobCopyWebpackPlugin: require('../plugins/glob-copy-webpack-plugin').GlobCopyWebpackPlugin,
SuppressExtractedTextChunksWebpackPlugin:
require('../plugins/suppress-entry-chunks-webpack-plugin')
.SuppressExtractedTextChunksWebpackPlugin
.SuppressExtractedTextChunksWebpackPlugin,
NamedLazyChunksWebpackPlugin:
require('../plugins/named-lazy-chunks-webpack-plugin').NamedLazyChunksWebpackPlugin
};
1 change: 1 addition & 0 deletions packages/@angular/cli/tasks/eject.ts
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,7 @@ class JsonWebpackSerializer {
this._addImport('webpack.optimize', 'UglifyJsPlugin');
break;
case angularCliPlugins.BaseHrefWebpackPlugin:
case angularCliPlugins.NamedLazyChunksWebpackPlugin:
case angularCliPlugins.SuppressExtractedTextChunksWebpackPlugin:
this._addImport('@angular/cli/plugins/webpack', plugin.constructor.name);
break;
Expand Down
7 changes: 7 additions & 0 deletions packages/@angular/cli/webpack-custom-typings.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import * as webpack from 'webpack';

declare module 'webpack' {
export class NamedChunksPlugin {
constructor(nameResolver: (chunk: any) => string | null): NamedChunksPlugin;
}
}
6 changes: 5 additions & 1 deletion packages/@ngtools/webpack/src/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -310,7 +310,11 @@ export class AotPlugin implements Tapable {
.map((key) => {
const value = this._lazyRoutes[key];
if (value !== null) {
return new ContextElementDependency(value, key);
const dep = new ContextElementDependency(value, key);
// lazyRouteChunkName is used by webpack.NamedChunksPlugin to give the
// lazy loaded chunk a name.
dep.lazyRouteChunkName = path.basename(key, '.ts');
return dep;
} else {
return null;
}
Expand Down

0 comments on commit de63632

Please sign in to comment.