Skip to content

Commit 00f2aa7

Browse files
author
Charles Lyding
committed
fix(@angular/cli): stabilize webpack module identifiers
1 parent 121c390 commit 00f2aa7

File tree

3 files changed

+78
-34
lines changed

3 files changed

+78
-34
lines changed

packages/@angular/cli/models/webpack-configs/production.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ export const getProdConfig = function (wco: WebpackConfigOptions) {
7070
new webpack.DefinePlugin({
7171
'process.env.NODE_ENV': JSON.stringify('production')
7272
}),
73+
new (<any>webpack).HashedModuleIdsPlugin(),
7374
new webpack.optimize.UglifyJsPlugin(<any>{
7475
mangle: { screw_ie8: true },
7576
compress: { screw_ie8: true, warnings: buildOptions.verbose },

packages/@angular/cli/tasks/eject.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,9 @@ class JsonWebpackSerializer {
165165
case webpack.NoEmitOnErrorsPlugin:
166166
this._addImport('webpack', 'NoEmitOnErrorsPlugin');
167167
break;
168+
case (<any>webpack).HashedModuleIdsPlugin:
169+
this._addImport('webpack', 'HashedModuleIdsPlugin');
170+
break;
168171
case webpack.optimize.UglifyJsPlugin:
169172
this._addImport('webpack.optimize', 'UglifyJsPlugin');
170173
break;
@@ -487,13 +490,13 @@ export default Task.extend({
487490
console.log(yellow(stripIndent`
488491
==========================================================================================
489492
Ejection was successful.
490-
493+
491494
To run your builds, you now need to do the following commands:
492495
- "npm run build" to build.
493496
- "npm run test" to run unit tests.
494497
- "npm start" to serve the app using webpack-dev-server.
495498
- "npm run e2e" to run protractor.
496-
499+
497500
Running the equivalent CLI commands will result in an error.
498501
499502
==========================================================================================

tests/e2e/tests/build/chunk-hash.ts

Lines changed: 72 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -5,52 +5,92 @@ import {ng} from '../../utils/process';
55
import {writeFile} from '../../utils/fs';
66
import {addImportToModule} from '../../utils/ast';
77

8+
const OUTPUT_RE = /(main|polyfills|vendor|inline|styles|\d+)\.[a-z0-9]+\.(chunk|bundle)\.(js|css)$/;
9+
10+
function generateFileHashMap(): Map<string, string> {
11+
const hashes = new Map<string, string>();
12+
13+
fs.readdirSync('./dist')
14+
.forEach(name => {
15+
if (!name.match(OUTPUT_RE)) {
16+
return;
17+
}
18+
19+
const [module, hash] = name.split('.');
20+
hashes.set(module, hash);
21+
});
22+
23+
return hashes;
24+
}
25+
26+
function validateHashes(
27+
oldHashes: Map<string, string>,
28+
newHashes: Map<string, string>,
29+
shouldChange: Array<string>): void {
30+
31+
console.log(' Validating hashes...');
32+
console.log(` Old hashes: ${JSON.stringify([...oldHashes])}`);
33+
console.log(` New hashes: ${JSON.stringify([...newHashes])}`);
34+
35+
oldHashes.forEach((hash, module) => {
36+
if (hash == newHashes.get(module)) {
37+
if (shouldChange.includes(module)) {
38+
throw new Error(`Module "${module}" did not change hash (${hash})...`);
39+
}
40+
} else if (!shouldChange.includes(module)) {
41+
throw new Error(`Module "${module}" changed hash (${hash})...`);
42+
}
43+
});
44+
}
845

946
export default function() {
10-
const oldHashes: {[module: string]: string} = {};
11-
const newHashes: {[module: string]: string} = {};
47+
let oldHashes: Map<string, string>;
48+
let newHashes: Map<string, string>;
1249
// First, collect the hashes.
1350
return Promise.resolve()
1451
.then(() => ng('generate', 'module', 'lazy', '--routing'))
1552
.then(() => addImportToModule('src/app/app.module.ts', oneLine`
1653
RouterModule.forRoot([{ path: "lazy", loadChildren: "./lazy/lazy.module#LazyModule" }])
1754
`, '@angular/router'))
55+
.then(() => addImportToModule(
56+
'src/app/app.module.ts', 'ReactiveFormsModule', '@angular/forms'))
1857
.then(() => ng('build', '--prod'))
1958
.then(() => {
20-
fs.readdirSync('./dist')
21-
.forEach(name => {
22-
if (!name.match(/(main|inline|styles|\d+)\.[a-z0-9]+\.bundle\.(js|css)/)) {
23-
return;
24-
}
25-
26-
const [module, hash] = name.split('.');
27-
oldHashes[module] = hash;
28-
});
59+
oldHashes = generateFileHashMap();
2960
})
30-
.then(() => writeFile('src/app/app.component.css', 'h1 { margin: 5px; }'))
31-
.then(() => writeFile('src/styles.css', 'body { background: red; }'))
3261
.then(() => ng('build', '--prod'))
3362
.then(() => {
34-
fs.readdirSync('./dist')
35-
.forEach(name => {
36-
if (!name.match(/(main|inline|styles|\d+)\.[a-z0-9]+\.bundle\.(js|css)/)) {
37-
return;
38-
}
39-
40-
const [module, hash] = name.split('.');
41-
newHashes[module] = hash;
42-
});
63+
newHashes = generateFileHashMap();
4364
})
4465
.then(() => {
45-
console.log(' Validating hashes...');
46-
console.log(` Old hashes: ${JSON.stringify(oldHashes)}`);
47-
console.log(` New hashes: ${JSON.stringify(newHashes)}`);
48-
49-
Object.keys(oldHashes)
50-
.forEach(module => {
51-
if (oldHashes[module] == newHashes[module]) {
52-
throw new Error(`Module "${module}" did not change hash (${oldHashes[module]})...`);
53-
}
54-
});
66+
validateHashes(oldHashes, newHashes, []);
67+
oldHashes = newHashes;
68+
})
69+
.then(() => writeFile('src/styles.css', 'body { background: blue; }'))
70+
.then(() => ng('build', '--prod'))
71+
.then(() => {
72+
newHashes = generateFileHashMap();
73+
})
74+
.then(() => {
75+
validateHashes(oldHashes, newHashes, ['styles']);
76+
oldHashes = newHashes;
77+
})
78+
.then(() => writeFile('src/app/app.component.css', 'h1 { margin: 10px; }'))
79+
.then(() => ng('build', '--prod'))
80+
.then(() => {
81+
newHashes = generateFileHashMap();
82+
})
83+
.then(() => {
84+
validateHashes(oldHashes, newHashes, ['inline', 'main']);
85+
oldHashes = newHashes;
86+
})
87+
.then(() => addImportToModule(
88+
'src/app/lazy/lazy.module.ts', 'ReactiveFormsModule', '@angular/forms'))
89+
.then(() => ng('build', '--prod'))
90+
.then(() => {
91+
newHashes = generateFileHashMap();
92+
})
93+
.then(() => {
94+
validateHashes(oldHashes, newHashes, ['inline', '0']);
5595
});
5696
}

0 commit comments

Comments
 (0)