Skip to content

Commit

Permalink
Merge pull request #14701 from webpack/feature/no-async-chunk-loading
Browse files Browse the repository at this point in the history
add `asyncChunks: boolean` option to disable creation of async chunks
  • Loading branch information
sokra committed Nov 10, 2021
2 parents 970b368 + 9bb5651 commit ac7bd40
Show file tree
Hide file tree
Showing 13 changed files with 125 additions and 29 deletions.
16 changes: 16 additions & 0 deletions declarations/WebpackOptions.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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).
*/
Expand Down Expand Up @@ -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.
*/
Expand Down Expand Up @@ -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).
*/
Expand Down Expand Up @@ -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.
*/
Expand Down
1 change: 1 addition & 0 deletions lib/EntryOptionPlugin.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ class EntryOptionPlugin {
dependOn: desc.dependOn,
publicPath: desc.publicPath,
chunkLoading: desc.chunkLoading,
asyncChunks: desc.asyncChunks,
wasmLoading: desc.wasmLoading,
library: desc.library
};
Expand Down
28 changes: 19 additions & 9 deletions lib/buildChunkGraph.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
*/

/**
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -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);

Expand All @@ -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,
Expand Down Expand Up @@ -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);
Expand Down
1 change: 1 addition & 0 deletions lib/config/defaults.js
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
2 changes: 2 additions & 0 deletions lib/config/normalization.js
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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 &&
Expand Down
2 changes: 1 addition & 1 deletion schemas/WebpackOptions.check.js

Large diffs are not rendered by default.

16 changes: 16 additions & 0 deletions schemas/WebpackOptions.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
},
Expand Down Expand Up @@ -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"
},
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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"
},
Expand Down
1 change: 1 addition & 0 deletions test/Defaults.unittest.js
Original file line number Diff line number Diff line change
Expand Up @@ -296,6 +296,7 @@ describe("Defaults", () => {
},
"output": Object {
"assetModuleFilename": "[hash][ext][query]",
"asyncChunks": true,
"charset": true,
"chunkFilename": "[name].js",
"chunkFormat": "array-push",
Expand Down
36 changes: 18 additions & 18 deletions test/Validation.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down Expand Up @@ -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)?"
`)
Expand Down Expand Up @@ -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."
`)
);
});
});
13 changes: 13 additions & 0 deletions test/__snapshots__/Cli.basictest.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
2 changes: 1 addition & 1 deletion test/configCases/entry/no-chunking/test.config.js
Original file line number Diff line number Diff line change
@@ -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"];
}
};
16 changes: 16 additions & 0 deletions test/configCases/entry/no-chunking/webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 changes: 20 additions & 0 deletions types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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).
*/
Expand Down Expand Up @@ -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).
*/
Expand Down Expand Up @@ -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.
*/
Expand Down Expand Up @@ -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.
*/
Expand Down

0 comments on commit ac7bd40

Please sign in to comment.