mirror of https://github.com/webpack/webpack.git
feat: added the `deferImport` option to parser options (#19737)
This commit is contained in:
parent
92304dfe07
commit
36a976b084
|
@ -3287,6 +3287,10 @@ export interface JavascriptParserOptions {
|
|||
* Enable/disable parsing "import { createRequire } from "module"" and evaluating createRequire().
|
||||
*/
|
||||
createRequire?: boolean | string;
|
||||
/**
|
||||
* Enable experimental tc39 proposal https://github.com/tc39/proposal-defer-import-eval. This allows to defer execution of a module until it's first use.
|
||||
*/
|
||||
deferImport?: boolean;
|
||||
/**
|
||||
* Specifies global fetchPriority for dynamic import.
|
||||
*/
|
||||
|
|
|
@ -829,13 +829,6 @@ class RuntimeTemplate {
|
|||
];
|
||||
}
|
||||
|
||||
defer = defer && (module.buildMeta ? !module.buildMeta.async : true);
|
||||
|
||||
/** @type {Set<Module>} */
|
||||
const outgoingAsyncModules = defer
|
||||
? getOutgoingAsyncModules(moduleGraph, module)
|
||||
: new Set();
|
||||
|
||||
if (chunkGraph.getModuleId(module) === null) {
|
||||
if (weak) {
|
||||
// only weak referenced modules don't get an id
|
||||
|
@ -872,7 +865,10 @@ class RuntimeTemplate {
|
|||
);
|
||||
runtimeRequirements.add(RuntimeGlobals.require);
|
||||
let importContent;
|
||||
if (defer) {
|
||||
if (defer && !(/** @type {BuildMeta} */ (module.buildMeta).async)) {
|
||||
/** @type {Set<Module>} */
|
||||
const outgoingAsyncModules = getOutgoingAsyncModules(moduleGraph, module);
|
||||
|
||||
importContent = `/* deferred harmony import */ ${optDeclaration}${importVar} = ${getOptimizedDeferredModule(
|
||||
this,
|
||||
exportsType,
|
||||
|
@ -936,8 +932,6 @@ class RuntimeTemplate {
|
|||
request
|
||||
});
|
||||
}
|
||||
|
||||
defer = defer && (module.buildMeta ? !module.buildMeta.async : true);
|
||||
if (!Array.isArray(exportName)) {
|
||||
exportName = exportName ? [exportName] : [];
|
||||
}
|
||||
|
@ -947,10 +941,13 @@ class RuntimeTemplate {
|
|||
(originModule.buildMeta).strictHarmonyModule
|
||||
);
|
||||
|
||||
const isDeferred =
|
||||
defer && !(/** @type {BuildMeta} */ (module.buildMeta).async);
|
||||
|
||||
if (defaultInterop) {
|
||||
// when the defaultInterop is used (when a ESM imports a CJS module),
|
||||
if (exportName.length > 0 && exportName[0] === "default") {
|
||||
if (defer && exportsType !== "namespace") {
|
||||
if (isDeferred && exportsType !== "namespace") {
|
||||
const access = `${importVar}.a${propertyAccess(exportName, 1)}`;
|
||||
if (isCall || asiSafe === undefined) {
|
||||
return access;
|
||||
|
@ -995,7 +992,7 @@ class RuntimeTemplate {
|
|||
) {
|
||||
return "/* __esModule */true";
|
||||
}
|
||||
} else if (defer) {
|
||||
} else if (isDeferred) {
|
||||
// now exportName.length is 0
|
||||
// fall through to the end of this function, create the namespace there.
|
||||
} else if (
|
||||
|
@ -1038,7 +1035,7 @@ class RuntimeTemplate {
|
|||
? ""
|
||||
: `${Template.toNormalComment(propertyAccess(exportName))} `;
|
||||
const access = `${importVar}${
|
||||
defer ? ".a" : ""
|
||||
isDeferred ? ".a" : ""
|
||||
}${comment}${propertyAccess(used)}`;
|
||||
if (isCall && callContext === false) {
|
||||
return asiSafe
|
||||
|
@ -1049,7 +1046,7 @@ class RuntimeTemplate {
|
|||
}
|
||||
return access;
|
||||
}
|
||||
if (defer) {
|
||||
if (isDeferred) {
|
||||
initFragments.push(
|
||||
new InitFragment(
|
||||
`var ${importVar}_deferred_namespace_cache;\n`,
|
||||
|
|
|
@ -265,6 +265,9 @@ const applyWebpackOptionsDefaults = (options, compilerIndex) => {
|
|||
css:
|
||||
/** @type {NonNullable<ExperimentsNormalized["css"]>} */
|
||||
(options.experiments.css),
|
||||
deferImport:
|
||||
/** @type {NonNullable<ExperimentsNormalized["deferImport"]>} */
|
||||
(options.experiments.deferImport),
|
||||
futureDefaults,
|
||||
isNode: targetProperties && targetProperties.node === true,
|
||||
uniqueName: /** @type {string} */ (options.output.uniqueName),
|
||||
|
@ -562,12 +565,13 @@ const applySnapshotDefaults = (snapshot, { production, futureDefaults }) => {
|
|||
* @param {JavascriptParserOptions} parserOptions parser options
|
||||
* @param {object} options options
|
||||
* @param {boolean} options.futureDefaults is future defaults enabled
|
||||
* @param {boolean} options.deferImport is defer import enabled
|
||||
* @param {boolean} options.isNode is node target platform
|
||||
* @returns {void}
|
||||
*/
|
||||
const applyJavascriptParserOptionsDefaults = (
|
||||
parserOptions,
|
||||
{ futureDefaults, isNode }
|
||||
{ futureDefaults, deferImport, isNode }
|
||||
) => {
|
||||
D(parserOptions, "unknownContextRequest", ".");
|
||||
D(parserOptions, "unknownContextRegExp", false);
|
||||
|
@ -588,6 +592,7 @@ const applyJavascriptParserOptionsDefaults = (
|
|||
D(parserOptions, "dynamicImportFetchPriority", false);
|
||||
D(parserOptions, "createRequire", isNode);
|
||||
D(parserOptions, "dynamicUrl", true);
|
||||
D(parserOptions, "deferImport", deferImport);
|
||||
if (futureDefaults) D(parserOptions, "exportsPresence", "error");
|
||||
};
|
||||
|
||||
|
@ -627,6 +632,7 @@ const applyCssGeneratorOptionsDefaults = (
|
|||
* @param {boolean} options.futureDefaults is future defaults enabled
|
||||
* @param {string} options.uniqueName the unique name
|
||||
* @param {boolean} options.isNode is node target platform
|
||||
* @param {boolean} options.deferImport is defer import enabled
|
||||
* @param {TargetProperties | false} options.targetProperties target properties
|
||||
* @param {Mode | undefined} options.mode mode
|
||||
* @returns {void}
|
||||
|
@ -642,7 +648,8 @@ const applyModuleDefaults = (
|
|||
isNode,
|
||||
uniqueName,
|
||||
targetProperties,
|
||||
mode
|
||||
mode,
|
||||
deferImport
|
||||
}
|
||||
) => {
|
||||
if (cache) {
|
||||
|
@ -700,6 +707,7 @@ const applyModuleDefaults = (
|
|||
(module.parser.javascript),
|
||||
{
|
||||
futureDefaults,
|
||||
deferImport,
|
||||
isNode
|
||||
}
|
||||
);
|
||||
|
|
|
@ -33,9 +33,8 @@ const PLUGIN_NAME = "HarmonyExportDependencyParserPlugin";
|
|||
module.exports = class HarmonyExportDependencyParserPlugin {
|
||||
/**
|
||||
* @param {import("../../declarations/WebpackOptions").JavascriptParserOptions} options options
|
||||
* @param {boolean=} deferImport defer import enabled
|
||||
*/
|
||||
constructor(options, deferImport) {
|
||||
constructor(options) {
|
||||
this.exportPresenceMode =
|
||||
options.reexportExportsPresence !== undefined
|
||||
? ExportPresenceModes.fromUserOption(options.reexportExportsPresence)
|
||||
|
@ -44,7 +43,7 @@ module.exports = class HarmonyExportDependencyParserPlugin {
|
|||
: options.strictExportPresence
|
||||
? ExportPresenceModes.ERROR
|
||||
: ExportPresenceModes.AUTO;
|
||||
this.deferImport = deferImport;
|
||||
this.deferImport = options.deferImport;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -378,7 +378,7 @@ class HarmonyExportImportedSpecifierDependency extends HarmonyImportDependency {
|
|||
* @param {ExportPresenceMode} exportPresenceMode mode of checking export names
|
||||
* @param {HarmonyStarExportsList | null} allStarExports all star exports in the module
|
||||
* @param {ImportAttributes=} attributes import attributes
|
||||
* @param {boolean=} deferEvaluation defer evaluation
|
||||
* @param {boolean=} defer is defer phase
|
||||
*/
|
||||
constructor(
|
||||
request,
|
||||
|
@ -390,9 +390,9 @@ class HarmonyExportImportedSpecifierDependency extends HarmonyImportDependency {
|
|||
exportPresenceMode,
|
||||
allStarExports,
|
||||
attributes,
|
||||
deferEvaluation
|
||||
defer
|
||||
) {
|
||||
super(request, sourceOrder, attributes);
|
||||
super(request, sourceOrder, attributes, defer);
|
||||
|
||||
this.ids = ids;
|
||||
this.name = name;
|
||||
|
@ -400,7 +400,6 @@ class HarmonyExportImportedSpecifierDependency extends HarmonyImportDependency {
|
|||
this.otherStarExports = otherStarExports;
|
||||
this.exportPresenceMode = exportPresenceMode;
|
||||
this.allStarExports = allStarExports;
|
||||
this.defer = deferEvaluation;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -64,11 +64,13 @@ class HarmonyImportDependency extends ModuleDependency {
|
|||
* @param {string} request request string
|
||||
* @param {number} sourceOrder source order
|
||||
* @param {ImportAttributes=} attributes import attributes
|
||||
* @param {boolean=} defer import attributes
|
||||
*/
|
||||
constructor(request, sourceOrder, attributes) {
|
||||
constructor(request, sourceOrder, attributes, defer) {
|
||||
super(request);
|
||||
this.sourceOrder = sourceOrder;
|
||||
this.assertions = attributes;
|
||||
this.defer = defer;
|
||||
}
|
||||
|
||||
get category() {
|
||||
|
|
|
@ -59,9 +59,8 @@ const PLUGIN_NAME = "HarmonyImportDependencyParserPlugin";
|
|||
module.exports = class HarmonyImportDependencyParserPlugin {
|
||||
/**
|
||||
* @param {JavascriptParserOptions} options options
|
||||
* @param {boolean | undefined} deferImport defer import enabled
|
||||
*/
|
||||
constructor(options, deferImport) {
|
||||
constructor(options) {
|
||||
this.exportPresenceMode =
|
||||
options.importExportsPresence !== undefined
|
||||
? ExportPresenceModes.fromUserOption(options.importExportsPresence)
|
||||
|
@ -71,7 +70,7 @@ module.exports = class HarmonyImportDependencyParserPlugin {
|
|||
? ExportPresenceModes.ERROR
|
||||
: ExportPresenceModes.AUTO;
|
||||
this.strictThisContextOnImports = options.strictThisContextOnImports;
|
||||
this.deferImport = deferImport;
|
||||
this.deferImport = options.deferImport;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -26,11 +26,10 @@ class HarmonyImportSideEffectDependency extends HarmonyImportDependency {
|
|||
* @param {string} request the request string
|
||||
* @param {number} sourceOrder source order
|
||||
* @param {ImportAttributes=} attributes import attributes
|
||||
* @param {boolean=} deferred deferred
|
||||
* @param {boolean=} defer is defer phase
|
||||
*/
|
||||
constructor(request, sourceOrder, attributes, deferred) {
|
||||
super(request, sourceOrder, attributes);
|
||||
this.defer = deferred;
|
||||
constructor(request, sourceOrder, attributes, defer) {
|
||||
super(request, sourceOrder, attributes, defer);
|
||||
}
|
||||
|
||||
get type() {
|
||||
|
|
|
@ -51,7 +51,7 @@ class HarmonyImportSpecifierDependency extends HarmonyImportDependency {
|
|||
* @param {ExportPresenceMode} exportPresenceMode export presence mode
|
||||
* @param {ImportAttributes | undefined} attributes import attributes
|
||||
* @param {Range[] | undefined} idRanges ranges for members of ids; the two arrays are right-aligned
|
||||
* @param {boolean=} deferred deferred
|
||||
* @param {boolean=} defer is defer phase
|
||||
*/
|
||||
constructor(
|
||||
request,
|
||||
|
@ -62,9 +62,9 @@ class HarmonyImportSpecifierDependency extends HarmonyImportDependency {
|
|||
exportPresenceMode,
|
||||
attributes,
|
||||
idRanges, // TODO webpack 6 make this non-optional. It must always be set to properly trim ids.
|
||||
deferred
|
||||
defer
|
||||
) {
|
||||
super(request, sourceOrder, attributes);
|
||||
super(request, sourceOrder, attributes, defer);
|
||||
this.ids = ids;
|
||||
this.name = name;
|
||||
this.range = range;
|
||||
|
@ -79,7 +79,6 @@ class HarmonyImportSpecifierDependency extends HarmonyImportDependency {
|
|||
this.usedByExports = undefined;
|
||||
/** @type {Set<DestructuringAssignmentProperty> | undefined} */
|
||||
this.referencedPropertiesInDestructuring = undefined;
|
||||
this.defer = deferred;
|
||||
}
|
||||
|
||||
// TODO webpack 6 remove
|
||||
|
|
|
@ -135,14 +135,8 @@ class HarmonyModulesPlugin {
|
|||
}
|
||||
|
||||
new HarmonyDetectionParserPlugin(this.options).apply(parser);
|
||||
new HarmonyImportDependencyParserPlugin(
|
||||
parserOptions,
|
||||
this.options.deferImport
|
||||
).apply(parser);
|
||||
new HarmonyExportDependencyParserPlugin(
|
||||
parserOptions,
|
||||
this.options.deferImport
|
||||
).apply(parser);
|
||||
new HarmonyImportDependencyParserPlugin(parserOptions).apply(parser);
|
||||
new HarmonyExportDependencyParserPlugin(parserOptions).apply(parser);
|
||||
new HarmonyTopLevelThisParserPlugin().apply(parser);
|
||||
};
|
||||
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -1874,6 +1874,10 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
"deferImport": {
|
||||
"description": "Enable experimental tc39 proposal https://github.com/tc39/proposal-defer-import-eval. This allows to defer execution of a module until it's first use.",
|
||||
"type": "boolean"
|
||||
},
|
||||
"dynamicImportFetchPriority": {
|
||||
"description": "Specifies global fetchPriority for dynamic import.",
|
||||
"enum": ["low", "high", "auto", false]
|
||||
|
|
|
@ -243,6 +243,7 @@ describe("snapshots", () => {
|
|||
},
|
||||
"javascript": Object {
|
||||
"createRequire": false,
|
||||
"deferImport": false,
|
||||
"dynamicImportFetchPriority": false,
|
||||
"dynamicImportMode": "lazy",
|
||||
"dynamicImportPrefetch": false,
|
||||
|
|
|
@ -1989,6 +1989,19 @@ Object {
|
|||
"multiple": false,
|
||||
"simpleType": "string",
|
||||
},
|
||||
"module-parser-javascript-auto-defer-import": Object {
|
||||
"configs": Array [
|
||||
Object {
|
||||
"description": "Enable experimental tc39 proposal https://github.com/tc39/proposal-defer-import-eval. This allows to defer execution of a module until it's first use.",
|
||||
"multiple": false,
|
||||
"path": "module.parser.javascript/auto.deferImport",
|
||||
"type": "boolean",
|
||||
},
|
||||
],
|
||||
"description": "Enable experimental tc39 proposal https://github.com/tc39/proposal-defer-import-eval. This allows to defer execution of a module until it's first use.",
|
||||
"multiple": false,
|
||||
"simpleType": "boolean",
|
||||
},
|
||||
"module-parser-javascript-auto-dynamic-import-fetch-priority": Object {
|
||||
"configs": Array [
|
||||
Object {
|
||||
|
@ -2638,6 +2651,19 @@ Object {
|
|||
"multiple": false,
|
||||
"simpleType": "string",
|
||||
},
|
||||
"module-parser-javascript-defer-import": Object {
|
||||
"configs": Array [
|
||||
Object {
|
||||
"description": "Enable experimental tc39 proposal https://github.com/tc39/proposal-defer-import-eval. This allows to defer execution of a module until it's first use.",
|
||||
"multiple": false,
|
||||
"path": "module.parser.javascript.deferImport",
|
||||
"type": "boolean",
|
||||
},
|
||||
],
|
||||
"description": "Enable experimental tc39 proposal https://github.com/tc39/proposal-defer-import-eval. This allows to defer execution of a module until it's first use.",
|
||||
"multiple": false,
|
||||
"simpleType": "boolean",
|
||||
},
|
||||
"module-parser-javascript-dynamic-amd": Object {
|
||||
"configs": Array [
|
||||
Object {
|
||||
|
@ -2712,6 +2738,19 @@ Object {
|
|||
"multiple": false,
|
||||
"simpleType": "string",
|
||||
},
|
||||
"module-parser-javascript-dynamic-defer-import": Object {
|
||||
"configs": Array [
|
||||
Object {
|
||||
"description": "Enable experimental tc39 proposal https://github.com/tc39/proposal-defer-import-eval. This allows to defer execution of a module until it's first use.",
|
||||
"multiple": false,
|
||||
"path": "module.parser.javascript/dynamic.deferImport",
|
||||
"type": "boolean",
|
||||
},
|
||||
],
|
||||
"description": "Enable experimental tc39 proposal https://github.com/tc39/proposal-defer-import-eval. This allows to defer execution of a module until it's first use.",
|
||||
"multiple": false,
|
||||
"simpleType": "boolean",
|
||||
},
|
||||
"module-parser-javascript-dynamic-dynamic-import-fetch-priority": Object {
|
||||
"configs": Array [
|
||||
Object {
|
||||
|
@ -3459,6 +3498,19 @@ Object {
|
|||
"multiple": false,
|
||||
"simpleType": "string",
|
||||
},
|
||||
"module-parser-javascript-esm-defer-import": Object {
|
||||
"configs": Array [
|
||||
Object {
|
||||
"description": "Enable experimental tc39 proposal https://github.com/tc39/proposal-defer-import-eval. This allows to defer execution of a module until it's first use.",
|
||||
"multiple": false,
|
||||
"path": "module.parser.javascript/esm.deferImport",
|
||||
"type": "boolean",
|
||||
},
|
||||
],
|
||||
"description": "Enable experimental tc39 proposal https://github.com/tc39/proposal-defer-import-eval. This allows to defer execution of a module until it's first use.",
|
||||
"multiple": false,
|
||||
"simpleType": "boolean",
|
||||
},
|
||||
"module-parser-javascript-esm-dynamic-import-fetch-priority": Object {
|
||||
"configs": Array [
|
||||
Object {
|
||||
|
|
|
@ -5967,7 +5967,8 @@ declare class HarmonyImportDependency extends ModuleDependency {
|
|||
constructor(
|
||||
request: string,
|
||||
sourceOrder: number,
|
||||
attributes?: ImportAttributes
|
||||
attributes?: ImportAttributes,
|
||||
defer?: boolean
|
||||
);
|
||||
sourceOrder: number;
|
||||
getImportVar(moduleGraph: ModuleGraph): string;
|
||||
|
@ -7878,6 +7879,11 @@ declare interface JavascriptParserOptions {
|
|||
*/
|
||||
createRequire?: string | boolean;
|
||||
|
||||
/**
|
||||
* Enable experimental tc39 proposal https://github.com/tc39/proposal-defer-import-eval. This allows to defer execution of a module until it's first use.
|
||||
*/
|
||||
deferImport?: boolean;
|
||||
|
||||
/**
|
||||
* Specifies global fetchPriority for dynamic import.
|
||||
*/
|
||||
|
|
Loading…
Reference in New Issue