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.
*/
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).
*/
@ -1928,6 +1932,10 @@ export interface Output {
* The filename of asset modules as relative path inside the 'output.path' directory.
*/
assetModuleFilename?: AssetModuleFilename;
/**
* Enable/disable creating async chunks that are loaded on demand.
*/
asyncChunks?: boolean;
/**
* Add a comment in the UMD wrapper.
*/
@ -2688,6 +2696,10 @@ export interface EmptyParserOptions {}
* An object with entry point description.
*/
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).
*/
@ -3052,6 +3064,10 @@ export interface OutputNormalized {
* The filename of asset modules as relative path inside the 'output.path' directory.
*/
assetModuleFilename?: AssetModuleFilename;
/**
* Enable/disable creating async chunks that are loaded on demand.
*/
asyncChunks?: boolean;
/**
* Add charset attribute for script tag.
*/

View File

@ -64,6 +64,7 @@ class EntryOptionPlugin {
dependOn: desc.dependOn,
publicPath: desc.publicPath,
chunkLoading: desc.chunkLoading,
asyncChunks: desc.asyncChunks,
wasmLoading: desc.wasmLoading,
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 {number} preOrderIndex next pre 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,
preOrderIndex: 0,
postOrderIndex: 0,
asyncChunkLoading:
chunkGroup.options.chunkLoading === false
? false
: compilation.outputOptions.chunkLoading !== false
chunkLoading:
chunkGroup.options.chunkLoading !== undefined
? chunkGroup.options.chunkLoading !== false
: compilation.outputOptions.chunkLoading !== false,
asyncChunks:
chunkGroup.options.asyncChunks !== undefined
? chunkGroup.options.asyncChunks
: compilation.outputOptions.asyncChunks !== false
};
chunkGroup.index = nextChunkGroupIndex++;
if (chunkGroup.getNumberOfParents() > 0) {
@ -424,10 +429,14 @@ const visitModules = (
availableChildren: undefined,
preOrderIndex: 0,
postOrderIndex: 0,
asyncChunkLoading:
chunkLoading:
entryOptions.chunkLoading !== undefined
? entryOptions.chunkLoading !== false
: chunkGroupInfo.asyncChunkLoading
: chunkGroupInfo.chunkLoading,
asyncChunks:
entryOptions.asyncChunks !== undefined
? entryOptions.asyncChunks
: chunkGroupInfo.asyncChunks
};
chunkGroupInfoMap.set(entrypoint, cgi);
@ -451,7 +460,7 @@ const visitModules = (
chunkGroup: entrypoint,
chunkGroupInfo: cgi
});
} else if (!chunkGroupInfo.asyncChunkLoading) {
} else if (!chunkGroupInfo.asyncChunks || !chunkGroupInfo.chunkLoading) {
// Just queue the block into the current chunk group
queue.push({
action: PROCESS_BLOCK,
@ -484,7 +493,8 @@ const visitModules = (
availableChildren: undefined,
preOrderIndex: 0,
postOrderIndex: 0,
asyncChunkLoading: chunkGroupInfo.asyncChunkLoading
chunkLoading: chunkGroupInfo.chunkLoading,
asyncChunks: chunkGroupInfo.asyncChunks
};
allCreatedChunkGroups.add(c);
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"
);
});
D(output, "asyncChunks", true);
F(output, "chunkLoading", () => {
if (tp) {
switch (output.chunkFormat) {

View File

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

File diff suppressed because one or more lines are too long

View File

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

View File

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

View File

@ -453,18 +453,18 @@ describe("Validation", () => {
},
msg =>
expect(msg).toMatchInlineSnapshot(`
"Invalid configuration object. Webpack has been initialized using a configuration object that does not match the API schema.
- configuration.optimization.splitChunks.cacheGroups should not be object { test, }.
-> Using the cacheGroup shorthand syntax with a cache group named 'test' is a potential config error
Did you intent to define a cache group with a test instead?
cacheGroups: {
<name>: {
test: ...
}
}.
object { <key>: false | RegExp | string | function | object { automaticNameDelimiter?, chunks?, enforce?, enforceSizeThreshold?, filename?, idHint?, layer?, maxAsyncRequests?, maxAsyncSize?, maxInitialRequests?, maxInitialSize?, maxSize?, minChunks?, minRemainingSize?, minSize?, minSizeReduction?, name?, priority?, reuseExistingChunk?, test?, type?, usedExports? } }
-> Assign modules to a cache group (modules from different cache groups are tried to keep in separate chunks, default categories: 'default', 'defaultVendors')."
`)
"Invalid configuration object. Webpack has been initialized using a configuration object that does not match the API schema.
- configuration.optimization.splitChunks.cacheGroups should not be object { test, }.
-> Using the cacheGroup shorthand syntax with a cache group named 'test' is a potential config error
Did you intent to define a cache group with a test instead?
cacheGroups: {
<name>: {
test: ...
}
}.
object { <key>: false | RegExp | string | function | object { automaticNameDelimiter?, chunks?, enforce?, enforceSizeThreshold?, filename?, idHint?, layer?, maxAsyncRequests?, maxAsyncSize?, maxInitialRequests?, maxInitialSize?, maxSize?, minChunks?, minRemainingSize?, minSize?, minSizeReduction?, name?, priority?, reuseExistingChunk?, test?, type?, usedExports? } }
-> Assign modules to a cache group (modules from different cache groups are tried to keep in separate chunks, default categories: 'default', 'defaultVendors')."
`)
);
createTestCase(
@ -497,7 +497,7 @@ describe("Validation", () => {
expect(msg).toMatchInlineSnapshot(`
"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:
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.
Did you mean output.environment (output.ecmaVersion was a temporary configuration option during webpack 5 beta)?"
`)
@ -661,11 +661,11 @@ describe("Validation", () => {
},
msg =>
expect(msg).toMatchInlineSnapshot(`
"Invalid configuration object. Webpack has been initialized using a configuration object that does not match the API schema.
- configuration.optimization.splitChunks has an unknown property 'automaticNamePrefix'. These properties are valid:
object { automaticNameDelimiter?, cacheGroups?, chunks?, defaultSizeTypes?, enforceSizeThreshold?, fallbackCacheGroup?, filename?, hidePathInfo?, maxAsyncRequests?, maxAsyncSize?, maxInitialRequests?, maxInitialSize?, maxSize?, minChunks?, minRemainingSize?, minSize?, minSizeReduction?, name?, usedExports? }
-> Options object for splitting chunks into smaller chunks."
`)
"Invalid configuration object. Webpack has been initialized using a configuration object that does not match the API schema.
- configuration.optimization.splitChunks has an unknown property 'automaticNamePrefix'. These properties are valid:
object { automaticNameDelimiter?, cacheGroups?, chunks?, defaultSizeTypes?, enforceSizeThreshold?, fallbackCacheGroup?, filename?, hidePathInfo?, maxAsyncRequests?, maxAsyncSize?, maxInitialRequests?, maxInitialSize?, maxSize?, minChunks?, minRemainingSize?, minSize?, minSizeReduction?, name?, usedExports? }
-> Options object for splitting chunks into smaller chunks."
`)
);
});
});

View File

@ -4974,6 +4974,19 @@ Object {
"multiple": false,
"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 {
"configs": Array [
Object {

View File

@ -1,5 +1,5 @@
module.exports = {
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: {
import: "./b.js",
chunkLoading: false
},
c: {
import: "./b.js",
asyncChunks: false
},
d: {
import: "./b.js",
asyncChunks: false,
runtime: "runtime"
}
},
output: {
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.
*/
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).
*/
@ -3074,6 +3079,11 @@ declare interface EntryDescription {
* An object with entry point description.
*/
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).
*/
@ -8062,6 +8072,11 @@ declare interface Output {
| 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.
*/
@ -8353,6 +8368,11 @@ declare interface OutputNormalized {
| string
| ((pathData: PathData, assetInfo?: AssetInfo) => string);
/**
* Enable/disable creating async chunks that are loaded on demand.
*/
asyncChunks?: boolean;
/**
* Add charset attribute for script tag.
*/