Skip to content

Commit df2a58f

Browse files
committed
Fixing a bug where async-split chunks caused undefined in
entrypoints.json
1 parent 4b43766 commit df2a58f

File tree

2 files changed

+75
-6
lines changed

2 files changed

+75
-6
lines changed

lib/webpack/entry-files-manifest-plugin.js

+41-6
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
const logger = require('../logger');
1313
const fse = require('fs-extra');
1414

15+
const bugMessage = 'This is possibly a bug, but will not impact your setup unless you use the entrypoints.json (e.g. splitEntryChunks()) file. To be super awesome, please report this as an issue.';
16+
1517
function EntryFilesManifestPlugin(manifestFilename, entryNamesToSkip, styleEntriesMap) {
1618
this.manifestFilename = manifestFilename;
1719
this.entryNamesToSkip = entryNamesToSkip;
@@ -36,7 +38,7 @@ function extractChunkIds(entryPoint) {
3638
} else if (/\.css$/.test(filename)) {
3739
files.cssChunkIds.push(chunk.id);
3840
} else {
39-
logger.debug(`Unable to determine file type for entry ${filename}. This is possibly a bug, but will not impact your setup unless you use the entrypoints.json file. To be super awesome, please report this as an issue.`);
41+
logger.warning(`Unable to determine file type for entry ${filename}. ${bugMessage}`);
4042
}
4143
}
4244
}
@@ -45,13 +47,46 @@ function extractChunkIds(entryPoint) {
4547
}
4648

4749
function getChunkNameFromId(allChunks, chunkId) {
48-
return allChunks.find(chunk => {
50+
const matchedChunk = allChunks.find(chunk => {
4951
return chunk.id === chunkId;
50-
}).name;
52+
});
53+
54+
if (!matchedChunk) {
55+
logger.warning(`Could not locate chunk with id ${chunkId}. ${bugMessage}`);
56+
57+
return false;
58+
}
59+
60+
if (typeof matchedChunk.name !== 'undefined') {
61+
return matchedChunk.name;
62+
}
63+
64+
// this can happen if the chunk was already split due to async code splitting
65+
if (matchedChunk.files.length !== 1) {
66+
logger.warning(`Found ${matchedChunk.files.length} files in chunk id ${matchedChunk.id} but expected exactly 1. ${bugMessage}`);
67+
68+
return false;
69+
}
70+
71+
// the only file has the correct filename (without versioning problems)
72+
return matchedChunk.files[0];
73+
}
74+
75+
function convertChunkIdsToChunkNames(allChunks, chunkIds) {
76+
return chunkIds.map(
77+
chunkId => getChunkNameFromId(allChunks, chunkId)
78+
).filter(chunkName => chunkName !== false);
5179
}
5280

5381
function convertChunkNamesToFilenames(chunkNames, extension) {
54-
return chunkNames.map(chunkName => `${chunkName}.${extension}`);
82+
return chunkNames.map(chunkName => {
83+
// possible for the async-split chunks
84+
if (chunkName.endsWith(`.${extension}`)) {
85+
return chunkName;
86+
}
87+
88+
return `${chunkName}.${extension}`;
89+
});
5590
}
5691

5792
EntryFilesManifestPlugin.prototype.apply = function(compiler) {
@@ -71,8 +106,8 @@ EntryFilesManifestPlugin.prototype.apply = function(compiler) {
71106
}
72107

73108
// look up the original chunk name by id
74-
const cssChunkNames = cssChunkIds.map(chunkId => getChunkNameFromId(stats.compilation.chunks, chunkId));
75-
const jsChunkNames = jsChunkIds.map(chunkId => getChunkNameFromId(stats.compilation.chunks, chunkId));
109+
const cssChunkNames = convertChunkIdsToChunkNames(stats.compilation.chunks, cssChunkIds);
110+
const jsChunkNames = convertChunkIdsToChunkNames(stats.compilation.chunks, jsChunkIds);
76111

77112
const cssFiles = convertChunkNamesToFilenames(cssChunkNames, 'css');
78113
const jsFiles = convertChunkNamesToFilenames(jsChunkNames, 'js');

test/functional.js

+34
Original file line numberDiff line numberDiff line change
@@ -1393,6 +1393,40 @@ module.exports = {
13931393
done();
13941394
});
13951395
});
1396+
1397+
it('Use splitEntryChunks() with code splitting', (done) => {
1398+
const config = createWebpackConfig('web/build', 'dev');
1399+
config.addEntry('main', ['./js/code_splitting', 'vue']);
1400+
config.addEntry('other', ['./js/no_require', 'vue']);
1401+
config.setPublicPath('/build');
1402+
// enable versioning to make sure entrypoints.json is not affected
1403+
config.enableVersioning();
1404+
config.splitEntryChunks();
1405+
config.configureSplitChunks((splitChunks) => {
1406+
splitChunks.minSize = 0;
1407+
});
1408+
1409+
testSetup.runWebpack(config, (webpackAssert) => {
1410+
webpackAssert.assertOutputJsonFileMatches('entrypoints.json', {
1411+
main: {
1412+
js: ['runtime.js', 'vendors~main~other.js', 'main.js'],
1413+
css: []
1414+
},
1415+
other: {
1416+
// the 0.[hash].js is because the "no_require" module was already split to this
1417+
// so, it has that filename, instead of following the normal pattern
1418+
js: ['runtime.js', 'vendors~main~other.js', '0.f1e0a935.js', 'other.js'],
1419+
css: []
1420+
},
1421+
});
1422+
1423+
// make split chunks are correct in manifest
1424+
webpackAssert.assertManifestKeyExists('build/vendors~main~other.js');
1425+
webpackAssert.assertManifestKeyExists('build/0.f1e0a935.js');
1426+
1427+
done();
1428+
});
1429+
});
13961430
});
13971431
});
13981432
});

0 commit comments

Comments
 (0)