add `asyncChunks: boolean` option to disable creation of async chunks

This commit is contained in:
Tobias Koppers 2021-11-10 14:23:03 +01:00
parent 970b368bda
commit 9bb5651e6a
13 changed files with 125 additions and 29 deletions

View File

@ -1019,6 +1019,10 @@ export interface EntryObject {
* An object with entry point description. * An object with entry point description.
*/ */
export interface EntryDescription { export interface EntryDescription {
/**
* Enable/disable creating async chunks that are loaded on demand.
*/
asyncChunks?: boolean;
/** /**
* The method of loading chunks (methods included by default are 'jsonp' (web), 'import' (ESM), 'importScripts' (WebWorker), 'require' (sync node.js), 'async-node' (async node.js), but others might be added by plugins). * The method of loading chunks (methods included by default are 'jsonp' (web), 'import' (ESM), 'importScripts' (WebWorker), 'require' (sync node.js), 'async-node' (async node.js), but others might be added by plugins).
*/ */
@ -1928,6 +1932,10 @@ export interface Output {
* The filename of asset modules as relative path inside the 'output.path' directory. * The filename of asset modules as relative path inside the 'output.path' directory.
*/ */
assetModuleFilename?: AssetModuleFilename; assetModuleFilename?: AssetModuleFilename;
/**
* Enable/disable creating async chunks that are loaded on demand.
*/
asyncChunks?: boolean;
/** /**
* Add a comment in the UMD wrapper. * Add a comment in the UMD wrapper.
*/ */
@ -2688,6 +2696,10 @@ export interface EmptyParserOptions {}
* An object with entry point description. * An object with entry point description.
*/ */
export interface EntryDescriptionNormalized { export interface EntryDescriptionNormalized {
/**
* Enable/disable creating async chunks that are loaded on demand.
*/
asyncChunks?: boolean;
/** /**
* The method of loading chunks (methods included by default are 'jsonp' (web), 'import' (ESM), 'importScripts' (WebWorker), 'require' (sync node.js), 'async-node' (async node.js), but others might be added by plugins). * The method of loading chunks (methods included by default are 'jsonp' (web), 'import' (ESM), 'importScripts' (WebWorker), 'require' (sync node.js), 'async-node' (async node.js), but others might be added by plugins).
*/ */
@ -3052,6 +3064,10 @@ export interface OutputNormalized {
* The filename of asset modules as relative path inside the 'output.path' directory. * The filename of asset modules as relative path inside the 'output.path' directory.
*/ */
assetModuleFilename?: AssetModuleFilename; assetModuleFilename?: AssetModuleFilename;
/**
* Enable/disable creating async chunks that are loaded on demand.
*/
asyncChunks?: boolean;
/** /**
* Add charset attribute for script tag. * Add charset attribute for script tag.
*/ */

View File

@ -64,6 +64,7 @@ class EntryOptionPlugin {
dependOn: desc.dependOn, dependOn: desc.dependOn,
publicPath: desc.publicPath, publicPath: desc.publicPath,
chunkLoading: desc.chunkLoading, chunkLoading: desc.chunkLoading,
asyncChunks: desc.asyncChunks,
wasmLoading: desc.wasmLoading, wasmLoading: desc.wasmLoading,
library: desc.library library: desc.library
}; };

View File

@ -50,7 +50,8 @@ const { getEntryRuntime, mergeRuntime } = require("./util/runtime");
* @property {Set<ChunkGroupInfo>} availableChildren set of chunk groups which depend on the this chunk group as availableSource * @property {Set<ChunkGroupInfo>} availableChildren set of chunk groups which depend on the this chunk group as availableSource
* @property {number} preOrderIndex next pre order index * @property {number} preOrderIndex next pre order index
* @property {number} postOrderIndex next post order index * @property {number} postOrderIndex next post order index
* @property {boolean} asyncChunkLoading create async chunks * @property {boolean} chunkLoading has a chunk loading mechanism
* @property {boolean} asyncChunks create async chunks
*/ */
/** /**
@ -306,10 +307,14 @@ const visitModules = (
availableChildren: undefined, availableChildren: undefined,
preOrderIndex: 0, preOrderIndex: 0,
postOrderIndex: 0, postOrderIndex: 0,
asyncChunkLoading: chunkLoading:
chunkGroup.options.chunkLoading === false chunkGroup.options.chunkLoading !== undefined
? false ? chunkGroup.options.chunkLoading !== false
: compilation.outputOptions.chunkLoading !== false : compilation.outputOptions.chunkLoading !== false,
asyncChunks:
chunkGroup.options.asyncChunks !== undefined
? chunkGroup.options.asyncChunks
: compilation.outputOptions.asyncChunks !== false
}; };
chunkGroup.index = nextChunkGroupIndex++; chunkGroup.index = nextChunkGroupIndex++;
if (chunkGroup.getNumberOfParents() > 0) { if (chunkGroup.getNumberOfParents() > 0) {
@ -424,10 +429,14 @@ const visitModules = (
availableChildren: undefined, availableChildren: undefined,
preOrderIndex: 0, preOrderIndex: 0,
postOrderIndex: 0, postOrderIndex: 0,
asyncChunkLoading: chunkLoading:
entryOptions.chunkLoading !== undefined entryOptions.chunkLoading !== undefined
? entryOptions.chunkLoading !== false ? entryOptions.chunkLoading !== false
: chunkGroupInfo.asyncChunkLoading : chunkGroupInfo.chunkLoading,
asyncChunks:
entryOptions.asyncChunks !== undefined
? entryOptions.asyncChunks
: chunkGroupInfo.asyncChunks
}; };
chunkGroupInfoMap.set(entrypoint, cgi); chunkGroupInfoMap.set(entrypoint, cgi);
@ -451,7 +460,7 @@ const visitModules = (
chunkGroup: entrypoint, chunkGroup: entrypoint,
chunkGroupInfo: cgi chunkGroupInfo: cgi
}); });
} else if (!chunkGroupInfo.asyncChunkLoading) { } else if (!chunkGroupInfo.asyncChunks || !chunkGroupInfo.chunkLoading) {
// Just queue the block into the current chunk group // Just queue the block into the current chunk group
queue.push({ queue.push({
action: PROCESS_BLOCK, action: PROCESS_BLOCK,
@ -484,7 +493,8 @@ const visitModules = (
availableChildren: undefined, availableChildren: undefined,
preOrderIndex: 0, preOrderIndex: 0,
postOrderIndex: 0, postOrderIndex: 0,
asyncChunkLoading: chunkGroupInfo.asyncChunkLoading chunkLoading: chunkGroupInfo.chunkLoading,
asyncChunks: chunkGroupInfo.asyncChunks
}; };
allCreatedChunkGroups.add(c); allCreatedChunkGroups.add(c);
chunkGroupInfoMap.set(c, cgi); chunkGroupInfoMap.set(c, cgi);

View File

@ -744,6 +744,7 @@ const applyOutputDefaults = (
"Chunk format can't be selected by default when no target is specified" "Chunk format can't be selected by default when no target is specified"
); );
}); });
D(output, "asyncChunks", true);
F(output, "chunkLoading", () => { F(output, "chunkLoading", () => {
if (tp) { if (tp) {
switch (output.chunkFormat) { switch (output.chunkFormat) {

View File

@ -290,6 +290,7 @@ const getNormalizedWebpackOptions = config => {
/** @type {OutputNormalized} */ /** @type {OutputNormalized} */
const result = { const result = {
assetModuleFilename: output.assetModuleFilename, assetModuleFilename: output.assetModuleFilename,
asyncChunks: output.asyncChunks,
charset: output.charset, charset: output.charset,
chunkFilename: output.chunkFilename, chunkFilename: output.chunkFilename,
chunkFormat: output.chunkFormat, chunkFormat: output.chunkFormat,
@ -484,6 +485,7 @@ const getNormalizedEntryStatic = entry => {
runtime: value.runtime, runtime: value.runtime,
publicPath: value.publicPath, publicPath: value.publicPath,
chunkLoading: value.chunkLoading, chunkLoading: value.chunkLoading,
asyncChunks: value.asyncChunks,
wasmLoading: value.wasmLoading, wasmLoading: value.wasmLoading,
dependOn: dependOn:
value.dependOn && value.dependOn &&

File diff suppressed because one or more lines are too long

View File

@ -434,6 +434,10 @@
"type": "object", "type": "object",
"additionalProperties": false, "additionalProperties": false,
"properties": { "properties": {
"asyncChunks": {
"description": "Enable/disable creating async chunks that are loaded on demand.",
"type": "boolean"
},
"chunkLoading": { "chunkLoading": {
"$ref": "#/definitions/ChunkLoading" "$ref": "#/definitions/ChunkLoading"
}, },
@ -487,6 +491,10 @@
"type": "object", "type": "object",
"additionalProperties": false, "additionalProperties": false,
"properties": { "properties": {
"asyncChunks": {
"description": "Enable/disable creating async chunks that are loaded on demand.",
"type": "boolean"
},
"chunkLoading": { "chunkLoading": {
"$ref": "#/definitions/ChunkLoading" "$ref": "#/definitions/ChunkLoading"
}, },
@ -2891,6 +2899,10 @@
"assetModuleFilename": { "assetModuleFilename": {
"$ref": "#/definitions/AssetModuleFilename" "$ref": "#/definitions/AssetModuleFilename"
}, },
"asyncChunks": {
"description": "Enable/disable creating async chunks that are loaded on demand.",
"type": "boolean"
},
"auxiliaryComment": { "auxiliaryComment": {
"cli": { "cli": {
"exclude": true "exclude": true
@ -3090,6 +3102,10 @@
"assetModuleFilename": { "assetModuleFilename": {
"$ref": "#/definitions/AssetModuleFilename" "$ref": "#/definitions/AssetModuleFilename"
}, },
"asyncChunks": {
"description": "Enable/disable creating async chunks that are loaded on demand.",
"type": "boolean"
},
"charset": { "charset": {
"$ref": "#/definitions/Charset" "$ref": "#/definitions/Charset"
}, },

View File

@ -296,6 +296,7 @@ describe("Defaults", () => {
}, },
"output": Object { "output": Object {
"assetModuleFilename": "[hash][ext][query]", "assetModuleFilename": "[hash][ext][query]",
"asyncChunks": true,
"charset": true, "charset": true,
"chunkFilename": "[name].js", "chunkFilename": "[name].js",
"chunkFormat": "array-push", "chunkFormat": "array-push",

View File

@ -497,7 +497,7 @@ describe("Validation", () => {
expect(msg).toMatchInlineSnapshot(` expect(msg).toMatchInlineSnapshot(`
"Invalid configuration object. Webpack has been initialized using a configuration object that does not match the API schema. "Invalid configuration object. Webpack has been initialized using a configuration object that does not match the API schema.
- configuration.output has an unknown property 'ecmaVersion'. These properties are valid: - configuration.output has an unknown property 'ecmaVersion'. These properties are valid:
object { assetModuleFilename?, auxiliaryComment?, charset?, chunkFilename?, chunkFormat?, chunkLoadTimeout?, chunkLoading?, chunkLoadingGlobal?, clean?, compareBeforeEmit?, crossOriginLoading?, devtoolFallbackModuleFilenameTemplate?, devtoolModuleFilenameTemplate?, devtoolNamespace?, enabledChunkLoadingTypes?, enabledLibraryTypes?, enabledWasmLoadingTypes?, environment?, filename?, globalObject?, hashDigest?, hashDigestLength?, hashFunction?, hashSalt?, hotUpdateChunkFilename?, hotUpdateGlobal?, hotUpdateMainFilename?, iife?, importFunctionName?, importMetaName?, library?, libraryExport?, libraryTarget?, module?, path?, pathinfo?, publicPath?, scriptType?, sourceMapFilename?, sourcePrefix?, strictModuleErrorHandling?, strictModuleExceptionHandling?, trustedTypes?, umdNamedDefine?, uniqueName?, wasmLoading?, webassemblyModuleFilename?, workerChunkLoading?, workerWasmLoading? } object { assetModuleFilename?, asyncChunks?, auxiliaryComment?, charset?, chunkFilename?, chunkFormat?, chunkLoadTimeout?, chunkLoading?, chunkLoadingGlobal?, clean?, compareBeforeEmit?, crossOriginLoading?, devtoolFallbackModuleFilenameTemplate?, devtoolModuleFilenameTemplate?, devtoolNamespace?, enabledChunkLoadingTypes?, enabledLibraryTypes?, enabledWasmLoadingTypes?, environment?, filename?, globalObject?, hashDigest?, hashDigestLength?, hashFunction?, hashSalt?, hotUpdateChunkFilename?, hotUpdateGlobal?, hotUpdateMainFilename?, iife?, importFunctionName?, importMetaName?, library?, libraryExport?, libraryTarget?, module?, path?, pathinfo?, publicPath?, scriptType?, sourceMapFilename?, sourcePrefix?, strictModuleErrorHandling?, strictModuleExceptionHandling?, trustedTypes?, umdNamedDefine?, uniqueName?, wasmLoading?, webassemblyModuleFilename?, workerChunkLoading?, workerWasmLoading? }
-> Options affecting the output of the compilation. \`output\` options tell webpack how to write the compiled files to disk. -> Options affecting the output of the compilation. \`output\` options tell webpack how to write the compiled files to disk.
Did you mean output.environment (output.ecmaVersion was a temporary configuration option during webpack 5 beta)?" Did you mean output.environment (output.ecmaVersion was a temporary configuration option during webpack 5 beta)?"
`) `)

View File

@ -4974,6 +4974,19 @@ Object {
"multiple": false, "multiple": false,
"simpleType": "string", "simpleType": "string",
}, },
"output-async-chunks": Object {
"configs": Array [
Object {
"description": "Enable/disable creating async chunks that are loaded on demand.",
"multiple": false,
"path": "output.asyncChunks",
"type": "boolean",
},
],
"description": "Enable/disable creating async chunks that are loaded on demand.",
"multiple": false,
"simpleType": "boolean",
},
"output-charset": Object { "output-charset": Object {
"configs": Array [ "configs": Array [
Object { Object {

View File

@ -1,5 +1,5 @@
module.exports = { module.exports = {
findBundle: function (i, options) { findBundle: function (i, options) {
return ["./a.js", "./b.js"]; return ["./a.js", "./b.js", "./c.js", "./runtime.js", "./d.js"];
} }
}; };

View File

@ -5,9 +5,25 @@ module.exports = {
b: { b: {
import: "./b.js", import: "./b.js",
chunkLoading: false chunkLoading: false
},
c: {
import: "./b.js",
asyncChunks: false
},
d: {
import: "./b.js",
asyncChunks: false,
runtime: "runtime"
} }
}, },
output: { output: {
filename: "[name].js" filename: "[name].js"
},
target: "web",
externals: {
fs: "commonjs fs"
},
node: {
__filename: false
} }
}; };

20
types.d.ts vendored
View File

@ -3024,6 +3024,11 @@ declare abstract class EntryDependency extends ModuleDependency {}
* An object with entry point description. * An object with entry point description.
*/ */
declare interface EntryDescription { declare interface EntryDescription {
/**
* Enable/disable creating async chunks that are loaded on demand.
*/
asyncChunks?: boolean;
/** /**
* The method of loading chunks (methods included by default are 'jsonp' (web), 'import' (ESM), 'importScripts' (WebWorker), 'require' (sync node.js), 'async-node' (async node.js), but others might be added by plugins). * The method of loading chunks (methods included by default are 'jsonp' (web), 'import' (ESM), 'importScripts' (WebWorker), 'require' (sync node.js), 'async-node' (async node.js), but others might be added by plugins).
*/ */
@ -3074,6 +3079,11 @@ declare interface EntryDescription {
* An object with entry point description. * An object with entry point description.
*/ */
declare interface EntryDescriptionNormalized { declare interface EntryDescriptionNormalized {
/**
* Enable/disable creating async chunks that are loaded on demand.
*/
asyncChunks?: boolean;
/** /**
* The method of loading chunks (methods included by default are 'jsonp' (web), 'import' (ESM), 'importScripts' (WebWorker), 'require' (sync node.js), 'async-node' (async node.js), but others might be added by plugins). * The method of loading chunks (methods included by default are 'jsonp' (web), 'import' (ESM), 'importScripts' (WebWorker), 'require' (sync node.js), 'async-node' (async node.js), but others might be added by plugins).
*/ */
@ -8062,6 +8072,11 @@ declare interface Output {
| string | string
| ((pathData: PathData, assetInfo?: AssetInfo) => string); | ((pathData: PathData, assetInfo?: AssetInfo) => string);
/**
* Enable/disable creating async chunks that are loaded on demand.
*/
asyncChunks?: boolean;
/** /**
* Add a comment in the UMD wrapper. * Add a comment in the UMD wrapper.
*/ */
@ -8353,6 +8368,11 @@ declare interface OutputNormalized {
| string | string
| ((pathData: PathData, assetInfo?: AssetInfo) => string); | ((pathData: PathData, assetInfo?: AssetInfo) => string);
/**
* Enable/disable creating async chunks that are loaded on demand.
*/
asyncChunks?: boolean;
/** /**
* Add charset attribute for script tag. * Add charset attribute for script tag.
*/ */