Compare commits

...

28 Commits

Author SHA1 Message Date
Ryuya ec806be71c
Merge a8d39c0cdf into e1afcd4cc2 2025-10-03 23:39:10 +03:00
Alexander Akait e1afcd4cc2
test: stability and avoid extra output (#19974)
Github Actions / lint (push) Has been cancelled Details
Github Actions / validate-legacy-node (push) Has been cancelled Details
Github Actions / benchmark (1/4) (push) Has been cancelled Details
Github Actions / benchmark (2/4) (push) Has been cancelled Details
Github Actions / benchmark (3/4) (push) Has been cancelled Details
Github Actions / benchmark (4/4) (push) Has been cancelled Details
Github Actions / basic (push) Has been cancelled Details
Github Actions / unit (push) Has been cancelled Details
Github Actions / integration (10.x, macos-latest, a) (push) Has been cancelled Details
Github Actions / integration (10.x, macos-latest, b) (push) Has been cancelled Details
Github Actions / integration (10.x, ubuntu-latest, a) (push) Has been cancelled Details
Github Actions / integration (10.x, ubuntu-latest, b) (push) Has been cancelled Details
Github Actions / integration (10.x, windows-latest, a) (push) Has been cancelled Details
Github Actions / integration (10.x, windows-latest, b) (push) Has been cancelled Details
Github Actions / integration (12.x, ubuntu-latest, a) (push) Has been cancelled Details
Github Actions / integration (14.x, ubuntu-latest, a) (push) Has been cancelled Details
Github Actions / integration (16.x, ubuntu-latest, a) (push) Has been cancelled Details
Github Actions / integration (18.x, ubuntu-latest, a) (push) Has been cancelled Details
Github Actions / integration (20.x, macos-latest, a) (push) Has been cancelled Details
Github Actions / integration (20.x, macos-latest, b) (push) Has been cancelled Details
Github Actions / integration (20.x, ubuntu-latest, a) (push) Has been cancelled Details
Github Actions / integration (20.x, ubuntu-latest, b) (push) Has been cancelled Details
Github Actions / integration (20.x, windows-latest, a) (push) Has been cancelled Details
Github Actions / integration (20.x, windows-latest, b) (push) Has been cancelled Details
Github Actions / integration (22.x, macos-latest, a) (push) Has been cancelled Details
Github Actions / integration (22.x, macos-latest, b) (push) Has been cancelled Details
Github Actions / integration (22.x, ubuntu-latest, a) (push) Has been cancelled Details
Github Actions / integration (22.x, ubuntu-latest, b) (push) Has been cancelled Details
Github Actions / integration (22.x, windows-latest, a) (push) Has been cancelled Details
Github Actions / integration (22.x, windows-latest, b) (push) Has been cancelled Details
Github Actions / integration (24.x, macos-latest, a) (push) Has been cancelled Details
Github Actions / integration (24.x, macos-latest, b) (push) Has been cancelled Details
Github Actions / integration (24.x, ubuntu-latest, a) (push) Has been cancelled Details
Github Actions / integration (24.x, ubuntu-latest, b) (push) Has been cancelled Details
Github Actions / integration (24.x, windows-latest, a) (push) Has been cancelled Details
Github Actions / integration (24.x, windows-latest, b) (push) Has been cancelled Details
Github Actions / integration (lts/*, ubuntu-latest, a, 1) (push) Has been cancelled Details
Github Actions / integration (lts/*, ubuntu-latest, b, 1) (push) Has been cancelled Details
2025-10-02 21:55:56 +03:00
Alexander Akait d45073a2b3
fix: dynamic import support in workers using browserslist (#19972) 2025-10-02 19:19:35 +03:00
Alexander Akait 568bb1d789
fix: types (#19971) 2025-10-02 18:26:16 +03:00
fregante 11144e4eec
fix: support web workers loading for jsonp format 2025-10-02 17:00:39 +03:00
Ryuya a8d39c0cdf refactor: simplify `webpackPreloadAs` validation and update warnings 2025-09-15 07:14:12 -07:00
Ryuya 57bb97cbb5 refactor 2025-09-15 06:43:01 -07:00
Ryuya 9e28ba7a71 tests: add test cases for invalid `webpackPreloadAs`, `webpackPreloadType`, and `webpackPreloadMedia` values. 2025-09-15 06:25:44 -07:00
Ryuya 3c30c24d8f feat: add preload options for enhanced asset loading
- Introduced `preloadAs`, `preloadType`, and `preloadMedia` properties to `URLDependency` for better control over asset preloading.
2025-09-15 06:24:36 -07:00
Ryuya 37632364c5 feat(runtime): improve asset prefetch/preload for universal target 2025-09-02 18:22:45 -07:00
Ryuya 719e2b13ca refactor: move asset type determination logic from util module to URLDependency class 2025-09-02 18:02:44 -07:00
Ryuya 0e3dfa1a38 refactor: replace `AssetResourcePrefetchRuntimeModule` with `ResourcePrefetchRuntimeModule` 2025-09-02 17:43:02 -07:00
Ryuya e7c0382087 fix: only enable URL asset prefetch/preload hints for web targets 2025-08-10 12:07:56 -07:00
Ryuya e97ae49459 refactor: simplify asset prefetch/preload implementation
- Consolidate multiple runtime modules into unified AssetResourcePrefetchPlugin
- Remove complex startup prefetch mechanism in favor of simpler inline approach
2025-08-10 12:01:59 -07:00
Ryuya a47f4443d1 chore: comments 2025-08-09 19:38:13 -07:00
Ryuya c94b2e9a1b refactor: extract asset type determination logic into util module 2025-08-09 19:38:13 -07:00
Ryuya 4aaaf13071 fix: resolve cache invalidation issues in asset prefetch implementation 2025-08-09 19:38:13 -07:00
Ryuya 43e8a85399 fix: move asset prefetch/preload execution from inline to startup time 2025-08-09 19:38:13 -07:00
Ryuya 9532eea79c feat: add webpackPreloadType support for new URL() syntax 2025-08-09 19:38:13 -07:00
Ryuya fb8bd910f0 test: clean up tests and remove outdated functionality 2025-08-09 19:38:13 -07:00
Ryuya 9c1e12dc02 refactor: extract asset type determination logic into separate function 2025-08-09 19:38:13 -07:00
Ryuya 5c9de0cd72 refactor: remove prefetch/preload conflict warning and use RuntimeGlobals.scriptNonce 2025-08-09 19:38:13 -07:00
Ryuya ceac24b37f fix: resolve linting errors in test files 2025-08-09 19:38:13 -07:00
Ryuya 42b9e8462f feat: implement webpackPrefetch/webpackPreload/webpackFetchPriority support for new URL() syntax 2025-08-09 19:38:13 -07:00
Ryuya 5d233d5389 feat: implement URL-based prefetch/preload support with runtime modules 2025-08-09 19:38:13 -07:00
Ryuya 4cab6a07d5 refactor: move prefetch/preload support from Worker to new URL() syntax 2025-08-09 19:38:10 -07:00
Ryuya 979b7f81e0 test: update Worker magic comment tests to follow webpack conventions 2025-08-09 19:36:42 -07:00
Ryuya 1e70bf7d49 feat: add webpackPrefetch/webpackPreload/webpackFetchPriority support for Worker syntax 2025-08-09 19:36:42 -07:00
58 changed files with 1601 additions and 236 deletions

View File

@ -90,6 +90,7 @@
"externref", "externref",
"fetchpriority", "fetchpriority",
"filebase", "filebase",
"flac",
"fileoverview", "fileoverview",
"filepath", "filepath",
"finalizer", "finalizer",
@ -314,7 +315,8 @@
"Kumar", "Kumar",
"spacek", "spacek",
"thelarkinn", "thelarkinn",
"behaviour" "behaviour",
"WHATWG"
], ],
"ignoreRegExpList": [ "ignoreRegExpList": [
"/Author.+/", "/Author.+/",

View File

@ -114,6 +114,7 @@ const {
/** @typedef {import("./ModuleTypeConstants").ASSET_MODULE_TYPE_INLINE} ASSET_MODULE_TYPE_INLINE */ /** @typedef {import("./ModuleTypeConstants").ASSET_MODULE_TYPE_INLINE} ASSET_MODULE_TYPE_INLINE */
/** @typedef {import("./ModuleTypeConstants").ASSET_MODULE_TYPE_RESOURCE} ASSET_MODULE_TYPE_RESOURCE */ /** @typedef {import("./ModuleTypeConstants").ASSET_MODULE_TYPE_RESOURCE} ASSET_MODULE_TYPE_RESOURCE */
/** @typedef {import("./ModuleTypeConstants").ASSET_MODULE_TYPE_SOURCE} ASSET_MODULE_TYPE_SOURCE */ /** @typedef {import("./ModuleTypeConstants").ASSET_MODULE_TYPE_SOURCE} ASSET_MODULE_TYPE_SOURCE */
/** @typedef {import("./ModuleTypeConstants").ASSET_MODULE_TYPE_BYTES} ASSET_MODULE_TYPE_BYTES */
/** @typedef {import("./ModuleTypeConstants").WEBASSEMBLY_MODULE_TYPE_ASYNC} WEBASSEMBLY_MODULE_TYPE_ASYNC */ /** @typedef {import("./ModuleTypeConstants").WEBASSEMBLY_MODULE_TYPE_ASYNC} WEBASSEMBLY_MODULE_TYPE_ASYNC */
/** @typedef {import("./ModuleTypeConstants").WEBASSEMBLY_MODULE_TYPE_SYNC} WEBASSEMBLY_MODULE_TYPE_SYNC */ /** @typedef {import("./ModuleTypeConstants").WEBASSEMBLY_MODULE_TYPE_SYNC} WEBASSEMBLY_MODULE_TYPE_SYNC */
/** @typedef {import("./ModuleTypeConstants").CSS_MODULE_TYPE} CSS_MODULE_TYPE */ /** @typedef {import("./ModuleTypeConstants").CSS_MODULE_TYPE} CSS_MODULE_TYPE */
@ -268,6 +269,76 @@ const ruleSetCompiler = new RuleSetCompiler([
new UseEffectRulePlugin() new UseEffectRulePlugin()
]); ]);
/** @typedef {import("./javascript/JavascriptParser")} JavascriptParser */
/** @typedef {import("../declarations/WebpackOptions").JavascriptParserOptions} JavascriptParserOptions */
/** @typedef {import("./javascript/JavascriptGenerator")} JavascriptGenerator */
/** @typedef {import("../declarations/WebpackOptions").EmptyGeneratorOptions} EmptyGeneratorOptions */
/** @typedef {import("./json/JsonParser")} JsonParser */
/** @typedef {import("../declarations/WebpackOptions").JsonParserOptions} JsonParserOptions */
/** @typedef {import("./json/JsonGenerator")} JsonGenerator */
/** @typedef {import("../declarations/WebpackOptions").JsonGeneratorOptions} JsonGeneratorOptions */
/** @typedef {import("./asset/AssetParser")} AssetParser */
/** @typedef {import("./asset/AssetSourceParser")} AssetSourceParser */
/** @typedef {import("./asset/AssetBytesParser")} AssetBytesParser */
/** @typedef {import("../declarations/WebpackOptions").AssetParserOptions} AssetParserOptions */
/** @typedef {import("../declarations/WebpackOptions").EmptyParserOptions} EmptyParserOptions */
/** @typedef {import("./asset/AssetGenerator")} AssetGenerator */
/** @typedef {import("../declarations/WebpackOptions").AssetGeneratorOptions} AssetGeneratorOptions */
/** @typedef {import("../declarations/WebpackOptions").AssetInlineGeneratorOptions} AssetInlineGeneratorOptions */
/** @typedef {import("../declarations/WebpackOptions").AssetResourceGeneratorOptions} AssetResourceGeneratorOptions */
/** @typedef {import("./asset/AssetSourceGenerator")} AssetSourceGenerator */
/** @typedef {import("./asset/AssetBytesGenerator")} AssetBytesGenerator */
/** @typedef {import("./wasm-async/AsyncWebAssemblyParser")} AsyncWebAssemblyParser */
/** @typedef {import("./wasm-sync/WebAssemblyParser")} WebAssemblyParser */
/** @typedef {import("./css/CssParser")} CssParser */
/** @typedef {import("../declarations/WebpackOptions").CssParserOptions} CssParserOptions */
/** @typedef {import("../declarations/WebpackOptions").CssAutoParserOptions} CssAutoParserOptions */
/** @typedef {import("../declarations/WebpackOptions").CssGlobalParserOptions} CssGlobalParserOptions */
/** @typedef {import("../declarations/WebpackOptions").CssModuleParserOptions} CssModuleParserOptions */
/** @typedef {import("./css/CssGenerator")} CssGenerator */
/** @typedef {import("../declarations/WebpackOptions").CssGeneratorOptions} CssGeneratorOptions */
/** @typedef {import("../declarations/WebpackOptions").CssGlobalGeneratorOptions} CssGlobalGeneratorOptions */
/** @typedef {import("../declarations/WebpackOptions").CssModuleGeneratorOptions} CssModuleGeneratorOptions */
/** @typedef {import("../declarations/WebpackOptions").CssAutoGeneratorOptions} CssAutoGeneratorOptions */
/**
* @typedef {[
* [JAVASCRIPT_MODULE_TYPE_AUTO, JavascriptParser, JavascriptParserOptions, JavascriptGenerator, EmptyGeneratorOptions],
* [JAVASCRIPT_MODULE_TYPE_DYNAMIC, JavascriptParser, JavascriptParserOptions, JavascriptGenerator, EmptyGeneratorOptions],
* [JAVASCRIPT_MODULE_TYPE_ESM, JavascriptParser, JavascriptParserOptions, JavascriptGenerator, EmptyGeneratorOptions],
* [JSON_MODULE_TYPE, JsonParser, JsonParserOptions, JsonGenerator, JsonGeneratorOptions],
* [ASSET_MODULE_TYPE, AssetParser, AssetParserOptions, AssetGenerator, AssetGeneratorOptions],
* [ASSET_MODULE_TYPE_INLINE, AssetParser, EmptyParserOptions, AssetGenerator, AssetGeneratorOptions],
* [ASSET_MODULE_TYPE_RESOURCE, AssetParser, EmptyParserOptions, AssetGenerator, AssetGeneratorOptions],
* [ASSET_MODULE_TYPE_SOURCE, AssetSourceParser, EmptyParserOptions, AssetSourceGenerator, EmptyGeneratorOptions],
* [ASSET_MODULE_TYPE_BYTES, AssetBytesParser, EmptyParserOptions, AssetBytesGenerator, EmptyGeneratorOptions],
* [WEBASSEMBLY_MODULE_TYPE_ASYNC, AsyncWebAssemblyParser, EmptyParserOptions, Generator, EmptyParserOptions],
* [WEBASSEMBLY_MODULE_TYPE_SYNC, WebAssemblyParser, EmptyParserOptions, Generator, EmptyParserOptions],
* [CSS_MODULE_TYPE, CssParser, CssParserOptions, CssGenerator, CssGeneratorOptions],
* [CSS_MODULE_TYPE_AUTO, CssParser, CssAutoParserOptions, CssGenerator, CssAutoGeneratorOptions],
* [CSS_MODULE_TYPE_MODULE, CssParser, CssModuleParserOptions, CssGenerator, CssModuleGeneratorOptions],
* [CSS_MODULE_TYPE_GLOBAL, CssParser, CssGlobalParserOptions, CssGenerator, CssGlobalGeneratorOptions],
* [string, Parser, ParserOptions, Generator, GeneratorOptions],
* ]} ParsersAndGeneratorsByTypes
*/
/**
* @template {unknown[]} T
* @template {number[]} I
* @typedef {{ [K in keyof I]: K extends keyof I ? I[K] extends keyof T ? T[I[K]] : never : never }} ExtractTupleElements
*/
/**
* @template {unknown[]} T
* @template {number[]} A
* @template [R=void]
* @typedef {T extends [infer Head extends [string, ...unknown[]], ...infer Tail extends [string, ...unknown[]][]] ? Record<Head[0], SyncBailHook<ExtractTupleElements<Head, A>, R extends number ? Head[R] : R>> & RecordFactoryFromTuple<Tail, A, R> : unknown } RecordFactoryFromTuple
*/
class NormalModuleFactory extends ModuleFactory { class NormalModuleFactory extends ModuleFactory {
/** /**
* @param {object} param params * @param {object} param params
@ -306,15 +377,15 @@ class NormalModuleFactory extends ModuleFactory {
createModule: new AsyncSeriesBailHook(["createData", "resolveData"]), createModule: new AsyncSeriesBailHook(["createData", "resolveData"]),
/** @type {SyncWaterfallHook<[Module, CreateData, ResolveData]>} */ /** @type {SyncWaterfallHook<[Module, CreateData, ResolveData]>} */
module: new SyncWaterfallHook(["module", "createData", "resolveData"]), module: new SyncWaterfallHook(["module", "createData", "resolveData"]),
/** @type {HookMap<SyncBailHook<[ParserOptions], Parser | void>>} */ /** @type {import("tapable").TypedHookMap<RecordFactoryFromTuple<ParsersAndGeneratorsByTypes, [2], 1>>} */
createParser: new HookMap(() => new SyncBailHook(["parserOptions"])), createParser: new HookMap(() => new SyncBailHook(["parserOptions"])),
/** @type {HookMap<SyncBailHook<[EXPECTED_ANY, ParserOptions], void>>} */ /** @type {import("tapable").TypedHookMap<RecordFactoryFromTuple<ParsersAndGeneratorsByTypes, [1, 2]>>} */
parser: new HookMap(() => new SyncHook(["parser", "parserOptions"])), parser: new HookMap(() => new SyncHook(["parser", "parserOptions"])),
/** @type {HookMap<SyncBailHook<[GeneratorOptions], Generator | void>>} */ /** @type {import("tapable").TypedHookMap<RecordFactoryFromTuple<ParsersAndGeneratorsByTypes, [4], 3>>} */
createGenerator: new HookMap( createGenerator: new HookMap(
() => new SyncBailHook(["generatorOptions"]) () => new SyncBailHook(["generatorOptions"])
), ),
/** @type {HookMap<SyncBailHook<[EXPECTED_ANY, GeneratorOptions], void>>} */ /** @type {import("tapable").TypedHookMap<RecordFactoryFromTuple<ParsersAndGeneratorsByTypes, [3, 4]>>} */
generator: new HookMap( generator: new HookMap(
() => new SyncHook(["generator", "generatorOptions"]) () => new SyncHook(["generator", "generatorOptions"])
), ),

View File

@ -312,6 +312,11 @@ module.exports.nodeModuleDecorator = "__webpack_require__.nmd";
*/ */
module.exports.onChunksLoaded = "__webpack_require__.O"; module.exports.onChunksLoaded = "__webpack_require__.O";
/**
* the asset prefetch function
*/
module.exports.prefetchAsset = "__webpack_require__.PA";
/** /**
* the chunk prefetch function * the chunk prefetch function
*/ */
@ -322,6 +327,11 @@ module.exports.prefetchChunk = "__webpack_require__.E";
*/ */
module.exports.prefetchChunkHandlers = "__webpack_require__.F"; module.exports.prefetchChunkHandlers = "__webpack_require__.F";
/**
* the asset preload function
*/
module.exports.preloadAsset = "__webpack_require__.LA";
/** /**
* the chunk preload function * the chunk preload function
*/ */

View File

@ -34,6 +34,8 @@ const WebpackIsIncludedPlugin = require("./WebpackIsIncludedPlugin");
const AssetModulesPlugin = require("./asset/AssetModulesPlugin"); const AssetModulesPlugin = require("./asset/AssetModulesPlugin");
const AssetResourcePrefetchPlugin = require("./asset/AssetResourcePrefetchPlugin");
const InferAsyncModulesPlugin = require("./async-modules/InferAsyncModulesPlugin"); const InferAsyncModulesPlugin = require("./async-modules/InferAsyncModulesPlugin");
const ResolverCachePlugin = require("./cache/ResolverCachePlugin"); const ResolverCachePlugin = require("./cache/ResolverCachePlugin");
@ -200,6 +202,21 @@ class WebpackOptionsApply extends OptionsApply {
new ChunkPrefetchPreloadPlugin().apply(compiler); new ChunkPrefetchPreloadPlugin().apply(compiler);
// Apply AssetResourcePrefetchPlugin only for web targets or universal targets
// Check if we're targeting web environment
const externalsPresets = options.externalsPresets || {};
const isTargetingWeb = Boolean(
externalsPresets.web ||
externalsPresets.webAsync ||
externalsPresets.electronRenderer
);
// Apply the plugin if we're targeting web environment
// For universal targets (["web", "node"]), the runtime module will handle platform detection using isNeutralPlatform
if (isTargetingWeb || !externalsPresets.node) {
new AssetResourcePrefetchPlugin().apply(compiler);
}
if (typeof options.output.chunkFormat === "string") { if (typeof options.output.chunkFormat === "string") {
switch (options.output.chunkFormat) { switch (options.output.chunkFormat) {
case "array-push": { case "array-push": {

View File

@ -0,0 +1,55 @@
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
"use strict";
const RuntimeGlobals = require("../RuntimeGlobals");
const ResourcePrefetchRuntimeModule = require("../prefetch/ResourcePrefetchRuntimeModule");
/** @typedef {import("../Compiler")} Compiler */
const PLUGIN_NAME = "AssetResourcePrefetchPlugin";
class AssetResourcePrefetchPlugin {
/**
* @param {Compiler} compiler the compiler
* @returns {void}
*/
apply(compiler) {
compiler.hooks.compilation.tap(PLUGIN_NAME, (compilation) => {
// prefetchAsset
compilation.hooks.runtimeRequirementInTree
.for(RuntimeGlobals.prefetchAsset)
.tap(PLUGIN_NAME, (chunk, set) => {
set.add(RuntimeGlobals.publicPath);
set.add(RuntimeGlobals.require);
set.add(RuntimeGlobals.baseURI);
set.add(RuntimeGlobals.relativeUrl);
compilation.addRuntimeModule(
chunk,
new ResourcePrefetchRuntimeModule("prefetch")
);
return true;
});
// preloadAsset
compilation.hooks.runtimeRequirementInTree
.for(RuntimeGlobals.preloadAsset)
.tap(PLUGIN_NAME, (chunk, set) => {
set.add(RuntimeGlobals.publicPath);
set.add(RuntimeGlobals.require);
set.add(RuntimeGlobals.baseURI);
set.add(RuntimeGlobals.relativeUrl);
compilation.addRuntimeModule(
chunk,
new ResourcePrefetchRuntimeModule("preload")
);
return true;
});
});
}
}
module.exports = AssetResourcePrefetchPlugin;

View File

@ -91,28 +91,6 @@ const resolve = (browsers) => {
const anyBrowser = browsers.some((b) => /^(?!node)/.test(b)); const anyBrowser = browsers.some((b) => /^(?!node)/.test(b));
const browserProperty = !anyBrowser ? false : anyNode ? null : true; const browserProperty = !anyBrowser ? false : anyNode ? null : true;
const nodeProperty = !anyNode ? false : anyBrowser ? null : true; const nodeProperty = !anyNode ? false : anyBrowser ? null : true;
// Internet Explorer Mobile, Blackberry browser and Opera Mini are very old browsers, they do not support new features
const es6DynamicImport = rawChecker({
/* eslint-disable camelcase */
chrome: 63,
and_chr: 63,
edge: 79,
firefox: 67,
and_ff: 67,
// ie: Not supported
opera: 50,
op_mob: 46,
safari: [11, 1],
ios_saf: [11, 3],
samsung: [8, 2],
android: 63,
and_qq: [10, 4],
baidu: [13, 18],
and_uc: [15, 5],
kaios: [3, 0],
node: [12, 17]
/* eslint-enable camelcase */
});
return { return {
/* eslint-disable camelcase */ /* eslint-disable camelcase */
@ -175,9 +153,9 @@ const resolve = (browsers) => {
ios_saf: 7, ios_saf: 7,
samsung: [3, 0], samsung: [3, 0],
android: 38, android: 38,
// and_qq: Unknown support and_qq: [10, 4],
// baidu: Unknown support // baidu: Unknown support
// and_uc: Unknown support and_uc: [12, 12],
kaios: [3, 0], kaios: [3, 0],
node: [0, 12] node: [0, 12]
}), }),
@ -194,9 +172,9 @@ const resolve = (browsers) => {
ios_saf: 8, ios_saf: 8,
samsung: [5, 0], samsung: [5, 0],
android: 49, android: 49,
// and_qq: Unknown support and_qq: [10, 4],
// baidu: Unknown support // baidu: Unknown support
// and_uc: Unknown support and_uc: [12, 12],
kaios: [2, 5], kaios: [2, 5],
node: [6, 0] node: [6, 0]
}), }),
@ -240,8 +218,44 @@ const resolve = (browsers) => {
kaios: [3, 0], kaios: [3, 0],
node: [12, 17] node: [12, 17]
}), }),
dynamicImport: es6DynamicImport, dynamicImport: rawChecker({
dynamicImportInWorker: es6DynamicImport && !anyNode, chrome: 63,
and_chr: 63,
edge: 79,
firefox: 67,
and_ff: 67,
// ie: Not supported
opera: 50,
op_mob: 46,
safari: [11, 1],
ios_saf: [11, 3],
samsung: [8, 2],
android: 63,
and_qq: [10, 4],
baidu: [13, 18],
and_uc: [15, 5],
kaios: [3, 0],
node: [12, 17]
}),
dynamicImportInWorker: rawChecker({
chrome: 80,
and_chr: 80,
edge: 80,
firefox: 114,
and_ff: 114,
// ie: Not supported
opera: 67,
op_mob: 57,
safari: [15, 0],
ios_saf: [15, 0],
samsung: [13, 0],
android: 80,
and_qq: [10, 4],
baidu: [13, 18],
and_uc: [15, 5],
kaios: [3, 0],
node: [12, 17]
}),
// browserslist does not have info about globalThis // browserslist does not have info about globalThis
// so this is based on mdn-browser-compat-data // so this is based on mdn-browser-compat-data
globalThis: rawChecker({ globalThis: rawChecker({
@ -257,9 +271,9 @@ const resolve = (browsers) => {
ios_saf: [12, 2], ios_saf: [12, 2],
samsung: [10, 1], samsung: [10, 1],
android: 71, android: 71,
// and_qq: Unknown support and_qq: [13, 1],
// baidu: Unknown support // baidu: Unknown support
// and_uc: Unknown support and_uc: [15, 5],
kaios: [3, 0], kaios: [3, 0],
node: 12 node: 12
}), }),
@ -276,9 +290,9 @@ const resolve = (browsers) => {
ios_saf: [13, 4], ios_saf: [13, 4],
samsung: 13, samsung: 13,
android: 80, android: 80,
// and_qq: Not supported and_qq: [13, 1],
// baidu: Not supported // baidu: Not supported
// and_uc: Not supported and_uc: [15, 5],
kaios: [3, 0], kaios: [3, 0],
node: 14 node: 14
}), }),
@ -314,9 +328,9 @@ const resolve = (browsers) => {
ios_saf: 11, ios_saf: 11,
samsung: [6, 2], samsung: [6, 2],
android: 55, android: 55,
and_qq: [13, 1], and_qq: [10, 4],
baidu: [13, 18], baidu: [13, 18],
and_uc: [15, 5], and_uc: [12, 12],
kaios: 3, kaios: 3,
node: [7, 6] node: [7, 6]
}), }),
@ -332,7 +346,7 @@ const resolve = (browsers) => {
fetchWasm: browserProperty, fetchWasm: browserProperty,
global: nodeProperty, global: nodeProperty,
importScripts: false, importScripts: false,
importScriptsInWorker: true, importScriptsInWorker: Boolean(browserProperty),
nodeBuiltins: nodeProperty, nodeBuiltins: nodeProperty,
nodePrefixForCoreModules: nodePrefixForCoreModules:
nodeProperty && nodeProperty &&

View File

@ -5,6 +5,7 @@
"use strict"; "use strict";
const InitFragment = require("../InitFragment");
const RuntimeGlobals = require("../RuntimeGlobals"); const RuntimeGlobals = require("../RuntimeGlobals");
const RawDataUrlModule = require("../asset/RawDataUrlModule"); const RawDataUrlModule = require("../asset/RawDataUrlModule");
const { const {
@ -43,6 +44,15 @@ class URLDependency extends ModuleDependency {
this.relative = relative || false; this.relative = relative || false;
/** @type {UsedByExports | undefined} */ /** @type {UsedByExports | undefined} */
this.usedByExports = undefined; this.usedByExports = undefined;
this.prefetch = undefined;
this.preload = undefined;
this.fetchPriority = undefined;
/** @type {string|undefined} */
this.preloadAs = undefined;
/** @type {string|undefined} */
this.preloadType = undefined;
/** @type {string|undefined} */
this.preloadMedia = undefined;
} }
get type() { get type() {
@ -81,6 +91,12 @@ class URLDependency extends ModuleDependency {
write(this.outerRange); write(this.outerRange);
write(this.relative); write(this.relative);
write(this.usedByExports); write(this.usedByExports);
write(this.prefetch);
write(this.preload);
write(this.fetchPriority);
write(this.preloadAs);
write(this.preloadType);
write(this.preloadMedia);
super.serialize(context); super.serialize(context);
} }
@ -92,6 +108,12 @@ class URLDependency extends ModuleDependency {
this.outerRange = read(); this.outerRange = read();
this.relative = read(); this.relative = read();
this.usedByExports = read(); this.usedByExports = read();
this.prefetch = read();
this.preload = read();
this.fetchPriority = read();
this.preloadAs = read();
this.preloadType = read();
this.preloadMedia = read();
super.deserialize(context); super.deserialize(context);
} }
} }
@ -99,6 +121,32 @@ class URLDependency extends ModuleDependency {
URLDependency.Template = class URLDependencyTemplate extends ( URLDependency.Template = class URLDependencyTemplate extends (
ModuleDependency.Template ModuleDependency.Template
) { ) {
/**
* Determines the 'as' attribute value for prefetch/preload based on file extension
* https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Attributes/rel/preload#what_types_of_content_can_be_preloaded
* @param {string} request module request string or filename
* @returns {string} asset type for link element 'as' attribute
*/
static _getAssetType(request) {
if (/\.(png|jpe?g|gif|svg|webp|avif|bmp|ico|tiff?)$/i.test(request)) {
return "image";
} else if (/\.(woff2?|ttf|otf|eot)$/i.test(request)) {
return "font";
} else if (/\.(js|mjs|jsx|ts|tsx)$/i.test(request)) {
return "script";
} else if (/\.css$/i.test(request)) {
return "style";
} else if (/\.vtt$/i.test(request)) {
return "track";
} else if (
/\.(mp4|webm|ogg|mp3|wav|flac|aac|m4a|avi|mov|wmv|mkv)$/i.test(request)
) {
// Audio/video files use 'fetch' as browser support varies
return "fetch";
}
return "fetch";
}
/** /**
* @param {Dependency} dependency the dependency for which the template should be applied * @param {Dependency} dependency the dependency for which the template should be applied
* @param {ReplaceSource} source the current replace source which can be modified * @param {ReplaceSource} source the current replace source which can be modified
@ -111,9 +159,12 @@ URLDependency.Template = class URLDependencyTemplate extends (
moduleGraph, moduleGraph,
runtimeRequirements, runtimeRequirements,
runtimeTemplate, runtimeTemplate,
runtime runtime,
initFragments
} = templateContext; } = templateContext;
const dep = /** @type {URLDependency} */ (dependency); const dep = /** @type {URLDependency} */ (dependency);
const module = moduleGraph.getModule(dep);
const connection = moduleGraph.getConnection(dep); const connection = moduleGraph.getConnection(dep);
// Skip rendering depending when dependency is conditional // Skip rendering depending when dependency is conditional
if (connection && !connection.isTargetActive(runtime)) { if (connection && !connection.isTargetActive(runtime)) {
@ -125,38 +176,87 @@ URLDependency.Template = class URLDependencyTemplate extends (
return; return;
} }
runtimeRequirements.add(RuntimeGlobals.require); // Standard URL generation
if (dep.relative) { if (dep.relative) {
runtimeRequirements.add(RuntimeGlobals.relativeUrl); runtimeRequirements.add(RuntimeGlobals.relativeUrl);
source.replace( source.replace(
dep.outerRange[0], dep.outerRange[0],
dep.outerRange[1] - 1, dep.outerRange[1] - 1,
`/* asset import */ new ${ `/* asset import */ new ${RuntimeGlobals.relativeUrl}(${runtimeTemplate.moduleRaw(
RuntimeGlobals.relativeUrl {
}(${runtimeTemplate.moduleRaw({ chunkGraph,
chunkGraph, module,
module: moduleGraph.getModule(dep), request: dep.request,
request: dep.request, runtimeRequirements,
runtimeRequirements, weak: false
weak: false }
})})` )})`
); );
} else { } else {
runtimeRequirements.add(RuntimeGlobals.baseURI); runtimeRequirements.add(RuntimeGlobals.baseURI);
source.replace( source.replace(
dep.range[0], dep.range[0],
dep.range[1] - 1, dep.range[1] - 1,
`/* asset import */ ${runtimeTemplate.moduleRaw({ `/* asset import */ ${runtimeTemplate.moduleRaw({
chunkGraph, chunkGraph,
module: moduleGraph.getModule(dep), module,
request: dep.request, request: dep.request,
runtimeRequirements, runtimeRequirements,
weak: false weak: false
})}, ${RuntimeGlobals.baseURI}` })}, ${RuntimeGlobals.baseURI}`
); );
} }
// Prefetch/Preload via InitFragment
if ((dep.prefetch || dep.preload) && module) {
const request = dep.request;
const detectedAssetType = URLDependencyTemplate._getAssetType(request);
const id = chunkGraph.getModuleId(module);
if (id !== null) {
const moduleId = runtimeTemplate.moduleId({
module,
chunkGraph,
request: dep.request,
weak: false
});
if (dep.preload) {
runtimeRequirements.add(RuntimeGlobals.preloadAsset);
const asArg = JSON.stringify(dep.preloadAs || detectedAssetType);
const fetchPriorityArg = dep.fetchPriority
? JSON.stringify(dep.fetchPriority)
: "undefined";
const typeArg = dep.preloadType
? JSON.stringify(dep.preloadType)
: "undefined";
const mediaArg = dep.preloadMedia
? JSON.stringify(dep.preloadMedia)
: "undefined";
initFragments.push(
new InitFragment(
`${RuntimeGlobals.preloadAsset}(${moduleId}, ${asArg}, ${fetchPriorityArg}, ${typeArg}, ${mediaArg}, ${dep.relative});\n`,
InitFragment.STAGE_CONSTANTS,
-10,
`asset_preload_${moduleId}`
)
);
} else if (dep.prefetch) {
runtimeRequirements.add(RuntimeGlobals.prefetchAsset);
const asArg = JSON.stringify(detectedAssetType);
const fetchPriorityArg = dep.fetchPriority
? JSON.stringify(dep.fetchPriority)
: "undefined";
initFragments.push(
new InitFragment(
`${RuntimeGlobals.prefetchAsset}(${moduleId}, ${asArg}, ${fetchPriorityArg}, undefined, undefined, ${dep.relative});\n`,
InitFragment.STAGE_CONSTANTS,
-5,
`asset_prefetch_${moduleId}`
)
);
}
}
}
} }
}; };

View File

@ -38,6 +38,7 @@ const WorkerDependency = require("./WorkerDependency");
/** @typedef {import("../../declarations/WebpackOptions").WasmLoading} WasmLoading */ /** @typedef {import("../../declarations/WebpackOptions").WasmLoading} WasmLoading */
/** @typedef {import("../../declarations/WebpackOptions").WorkerPublicPath} WorkerPublicPath */ /** @typedef {import("../../declarations/WebpackOptions").WorkerPublicPath} WorkerPublicPath */
/** @typedef {import("../Compiler")} Compiler */ /** @typedef {import("../Compiler")} Compiler */
/** @typedef {import("../ChunkGroup").RawChunkGroupOptions} RawChunkGroupOptions */
/** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */ /** @typedef {import("../Dependency").DependencyLocation} DependencyLocation */
/** @typedef {import("../Entrypoint").EntryOptions} EntryOptions */ /** @typedef {import("../Entrypoint").EntryOptions} EntryOptions */
/** @typedef {import("../NormalModule")} NormalModule */ /** @typedef {import("../NormalModule")} NormalModule */
@ -223,9 +224,12 @@ class WorkerPlugin {
} }
} }
const insertType = expr.properties.length > 0 ? "comma" : "single"; const insertType = expr.properties.length > 0 ? "comma" : "single";
const insertLocation = /** @type {Range} */ ( const insertLocation =
expr.properties[expr.properties.length - 1].range expr.properties.length > 0
)[1]; ? /** @type {Range} */ (
expr.properties[expr.properties.length - 1].range
)[1]
: /** @type {Range} */ (expr.range)[0] + 1;
return { return {
expressions, expressions,
otherElements, otherElements,
@ -299,6 +303,10 @@ class WorkerPlugin {
? /** @type {Range} */ (arg2.range) ? /** @type {Range} */ (arg2.range)
: /** @type {Range} */ (arg1.range)[1] : /** @type {Range} */ (arg1.range)[1]
}; };
/** @type {RawChunkGroupOptions} */
const groupOptions = {};
const { options: importOptions, errors: commentErrors } = const { options: importOptions, errors: commentErrors } =
parser.parseCommentOptions(/** @type {Range} */ (expr.range)); parser.parseCommentOptions(/** @type {Range} */ (expr.range));
@ -360,6 +368,60 @@ class WorkerPlugin {
entryOptions.name = importOptions.webpackChunkName; entryOptions.name = importOptions.webpackChunkName;
} }
} }
// Support webpackPrefetch (true | number)
if (importOptions.webpackPrefetch !== undefined) {
if (importOptions.webpackPrefetch === true) {
groupOptions.prefetchOrder = 0;
} else if (typeof importOptions.webpackPrefetch === "number") {
groupOptions.prefetchOrder = importOptions.webpackPrefetch;
} else {
parser.state.module.addWarning(
new UnsupportedFeatureWarning(
`\`webpackPrefetch\` expected true or a number, but received: ${importOptions.webpackPrefetch}.`,
/** @type {DependencyLocation} */ (expr.loc)
)
);
}
}
// Support webpackPreload (true | number)
if (importOptions.webpackPreload !== undefined) {
if (importOptions.webpackPreload === true) {
groupOptions.preloadOrder = 0;
} else if (typeof importOptions.webpackPreload === "number") {
groupOptions.preloadOrder = importOptions.webpackPreload;
} else {
parser.state.module.addWarning(
new UnsupportedFeatureWarning(
`\`webpackPreload\` expected true or a number, but received: ${importOptions.webpackPreload}.`,
/** @type {DependencyLocation} */ (expr.loc)
)
);
}
}
// Support webpackFetchPriority ("high" | "low" | "auto")
if (importOptions.webpackFetchPriority !== undefined) {
if (
typeof importOptions.webpackFetchPriority === "string" &&
["high", "low", "auto"].includes(
importOptions.webpackFetchPriority
)
) {
groupOptions.fetchPriority =
/** @type {"auto" | "high" | "low"} */ (
importOptions.webpackFetchPriority
);
} else {
parser.state.module.addWarning(
new UnsupportedFeatureWarning(
`\`webpackFetchPriority\` expected "low", "high" or "auto", but received: ${importOptions.webpackFetchPriority}.`,
/** @type {DependencyLocation} */ (expr.loc)
)
);
}
}
} }
if ( if (
@ -388,6 +450,7 @@ class WorkerPlugin {
} }
const block = new AsyncDependenciesBlock({ const block = new AsyncDependenciesBlock({
...groupOptions,
name: entryOptions.name, name: entryOptions.name,
entryOptions: { entryOptions: {
chunkLoading: this._chunkLoading, chunkLoading: this._chunkLoading,

View File

@ -106,7 +106,7 @@ const BasicEvaluatedExpression = require("./BasicEvaluatedExpression");
/** @typedef {Set<DestructuringAssignmentProperty>} DestructuringAssignmentProperties */ /** @typedef {Set<DestructuringAssignmentProperty>} DestructuringAssignmentProperties */
// TODO remove cast when @types/estree has been updated to import assertions // TODO remove cast when @types/estree has been updated to import assertions
/** @typedef {import("estree").ImportExpression & { options?: Expression | null, phase?: "defer" }} ImportExpression */ /** @typedef {import("estree").ImportExpression & { phase?: "defer" }} ImportExpression */
/** @type {string[]} */ /** @type {string[]} */
const EMPTY_ARRAY = []; const EMPTY_ARRAY = [];

View File

@ -0,0 +1,105 @@
/*
MIT License http://www.opensource.org/licenses/mit-license.php
Author Tobias Koppers @sokra
*/
"use strict";
const RuntimeGlobals = require("../RuntimeGlobals");
const RuntimeModule = require("../RuntimeModule");
const Template = require("../Template");
/** @typedef {import("../Compilation")} Compilation */
class ResourcePrefetchRuntimeModule extends RuntimeModule {
/**
* @param {string} type "prefetch" or "preload"
*/
constructor(type) {
super(`asset ${type}`, RuntimeModule.STAGE_ATTACH);
this._type = type;
}
/**
* @returns {string | null} runtime code
*/
generate() {
const { compilation } = this;
if (!compilation) return null;
const { runtimeTemplate, outputOptions } = compilation;
const fnName =
this._type === "prefetch"
? RuntimeGlobals.prefetchAsset
: RuntimeGlobals.preloadAsset;
const crossOriginLoading = outputOptions.crossOriginLoading;
const isNeutralPlatform = runtimeTemplate.isNeutralPlatform();
// For neutral platform (universal targets), generate code that checks for document at runtime
const code = [
"var url;",
"if (relative) {",
Template.indent([
`url = new ${RuntimeGlobals.relativeUrl}(${RuntimeGlobals.require}(moduleId));`
]),
"} else {",
Template.indent([
`url = new URL(${RuntimeGlobals.require}(moduleId), ${RuntimeGlobals.baseURI});`
]),
"}",
"",
"var link = document.createElement('link');",
`link.rel = '${this._type}';`,
"if (as) link.as = as;",
"link.href = url.href;",
"",
"if (fetchPriority) {",
Template.indent([
"link.fetchPriority = fetchPriority;",
"link.setAttribute('fetchpriority', fetchPriority);"
]),
"}",
"",
"if (type) link.type = type;",
"if (media) link.media = media;",
"",
crossOriginLoading
? Template.asString([
"if (link.href.indexOf(window.location.origin + '/') !== 0) {",
Template.indent([
`link.crossOrigin = ${JSON.stringify(crossOriginLoading)};`
]),
"}"
])
: "",
"",
"document.head.appendChild(link);"
];
// For neutral platform, wrap the code to check for document availability
if (isNeutralPlatform) {
return Template.asString([
`${fnName} = ${runtimeTemplate.basicFunction(
"moduleId, as, fetchPriority, type, media, relative",
[
"// Only execute in browser environment",
"if (typeof document !== 'undefined') {",
Template.indent(code),
"}"
]
)};`
]);
}
// For browser-only targets, generate code without the check
return Template.asString([
`${fnName} = ${runtimeTemplate.basicFunction(
"moduleId, as, fetchPriority, type, media, relative",
code
)};`
]);
}
}
module.exports = ResourcePrefetchRuntimeModule;

View File

@ -182,6 +182,91 @@ class URLParserPlugin {
relative relative
); );
dep.loc = /** @type {DependencyLocation} */ (expr.loc); dep.loc = /** @type {DependencyLocation} */ (expr.loc);
// Parse magic comments with simplified rules
if (importOptions) {
// Accept only boolean true for webpackPrefetch
if (importOptions.webpackPrefetch === true) {
dep.prefetch = true;
} else if (importOptions.webpackPrefetch !== undefined) {
parser.state.module.addWarning(
new UnsupportedFeatureWarning(
`\`webpackPrefetch\` expected true, but received: ${importOptions.webpackPrefetch}.`,
/** @type {DependencyLocation} */ (expr.loc)
)
);
}
// Accept only boolean true for webpackPreload
if (importOptions.webpackPreload === true) {
dep.preload = true;
} else if (importOptions.webpackPreload !== undefined) {
parser.state.module.addWarning(
new UnsupportedFeatureWarning(
`\`webpackPreload\` expected true, but received: ${importOptions.webpackPreload}.`,
/** @type {DependencyLocation} */ (expr.loc)
)
);
}
// webpackFetchPriority: "high" | "low" | "auto"
if (
typeof importOptions.webpackFetchPriority === "string" &&
["high", "low", "auto"].includes(importOptions.webpackFetchPriority)
) {
dep.fetchPriority = importOptions.webpackFetchPriority;
} else if (importOptions.webpackFetchPriority !== undefined) {
parser.state.module.addWarning(
new UnsupportedFeatureWarning(
`\`webpackFetchPriority\` expected "low", "high" or "auto", but received: ${importOptions.webpackFetchPriority}.`,
/** @type {DependencyLocation} */ (expr.loc)
)
);
}
// webpackPreloadAs: allow override of the "as" attribute for preload
if (importOptions.webpackPreloadAs !== undefined) {
if (typeof importOptions.webpackPreloadAs === "string") {
dep.preloadAs = importOptions.webpackPreloadAs;
} else {
parser.state.module.addWarning(
new UnsupportedFeatureWarning(
`\`webpackPreloadAs\` expected a string, but received: ${importOptions.webpackPreloadAs}.`,
/** @type {DependencyLocation} */ (expr.loc)
)
);
}
}
// webpackPreloadType: set link.type when provided
if (importOptions.webpackPreloadType !== undefined) {
if (typeof importOptions.webpackPreloadType === "string") {
dep.preloadType = importOptions.webpackPreloadType;
} else {
parser.state.module.addWarning(
new UnsupportedFeatureWarning(
`\`webpackPreloadType\` expected a string, but received: ${importOptions.webpackPreloadType}.`,
/** @type {DependencyLocation} */ (expr.loc)
)
);
}
}
// webpackPreloadMedia: set link.media when provided
if (importOptions.webpackPreloadMedia !== undefined) {
if (typeof importOptions.webpackPreloadMedia === "string") {
dep.preloadMedia = importOptions.webpackPreloadMedia;
} else {
parser.state.module.addWarning(
new UnsupportedFeatureWarning(
`\`webpackPreloadMedia\` expected a string, but received: ${importOptions.webpackPreloadMedia}.`,
/** @type {DependencyLocation} */ (expr.loc)
)
);
}
}
}
// Register the dependency
parser.state.current.addDependency(dep); parser.state.current.addDependency(dep);
InnerGraph.onUsage(parser.state, (e) => (dep.usedByExports = e)); InnerGraph.onUsage(parser.state, (e) => (dep.usedByExports = e));
return true; return true;

View File

@ -8,7 +8,7 @@
const memoize = require("./memoize"); const memoize = require("./memoize");
/** @typedef {import("schema-utils").Schema} Schema */ /** @typedef {import("schema-utils").Schema} Schema */
/** @typedef {import("schema-utils/declarations/validate").ValidationErrorConfiguration} ValidationErrorConfiguration */ /** @typedef {import("schema-utils").ValidationErrorConfiguration} ValidationErrorConfiguration */
const getValidate = memoize(() => require("schema-utils").validate); const getValidate = memoize(() => require("schema-utils").validate);

View File

@ -26,15 +26,6 @@ const decoderOpts = {
}; };
class WebAssemblyParser extends Parser { class WebAssemblyParser extends Parser {
/**
* @param {{}=} options parser options
*/
constructor(options) {
super();
this.hooks = Object.freeze({});
this.options = options;
}
/** /**
* @param {string | Buffer | PreparsedAst} source the source to parse * @param {string | Buffer | PreparsedAst} source the source to parse
* @param {ParserState} state the parser state * @param {ParserState} state the parser state

View File

@ -63,15 +63,6 @@ const decoderOpts = {
}; };
class WebAssemblyParser extends Parser { class WebAssemblyParser extends Parser {
/**
* @param {{}=} options parser options
*/
constructor(options) {
super();
this.hooks = Object.freeze({});
this.options = options;
}
/** /**
* @param {string | Buffer | PreparsedAst} source the source to parse * @param {string | Buffer | PreparsedAst} source the source to parse
* @param {ParserState} state the parser state * @param {ParserState} state the parser state

View File

@ -69,7 +69,7 @@ class JsonpChunkLoadingRuntimeModule extends RuntimeModule {
if (options && options.baseUri) { if (options && options.baseUri) {
return `${RuntimeGlobals.baseURI} = ${JSON.stringify(options.baseUri)};`; return `${RuntimeGlobals.baseURI} = ${JSON.stringify(options.baseUri)};`;
} }
return `${RuntimeGlobals.baseURI} = (document && document.baseURI) || self.location.href;`; return `${RuntimeGlobals.baseURI} = (typeof document !== 'undefined' && document.baseURI) || self.location.href;`;
} }
/** /**

View File

@ -101,8 +101,8 @@
"loader-runner": "^4.2.0", "loader-runner": "^4.2.0",
"mime-types": "^2.1.27", "mime-types": "^2.1.27",
"neo-async": "^2.6.2", "neo-async": "^2.6.2",
"schema-utils": "^4.3.2", "schema-utils": "^4.3.3",
"tapable": "^2.2.3", "tapable": "^2.3.0",
"terser-webpack-plugin": "^5.3.11", "terser-webpack-plugin": "^5.3.11",
"watchpack": "^2.4.4", "watchpack": "^2.4.4",
"webpack-sources": "^3.3.3" "webpack-sources": "^3.3.3"
@ -184,7 +184,7 @@
"toml": "^3.0.0", "toml": "^3.0.0",
"tooling": "webpack/tooling#v1.24.3", "tooling": "webpack/tooling#v1.24.3",
"ts-loader": "^9.5.1", "ts-loader": "^9.5.1",
"typescript": "^5.9.2", "typescript": "^5.9.3",
"url-loader": "^4.1.0", "url-loader": "^4.1.0",
"wast-loader": "^1.12.1", "wast-loader": "^1.12.1",
"webassembly-feature": "1.3.0", "webassembly-feature": "1.3.0",

View File

@ -2909,12 +2909,6 @@ describe("Targets", () => {
- Expected - Expected
+ Received + Received
@@ ... @@
- "dynamicImportInWorker": true,
+ "dynamicImportInWorker": false,
@@ ... @@
- "dynamicImportInWorker": true,
+ "dynamicImportInWorker": false,
@@ ... @@ @@ ... @@
- "target": "node12.17", - "target": "node12.17",
+ "target": "browserslist: node 12.17", + "target": "browserslist: node 12.17",

View File

@ -31,6 +31,37 @@ Object {
} }
`; `;
exports[`browserslist target ["and_chr 140","and_ff 142","and_qq 14.9","and_uc 15.5","android 140","chrome 140","chrome 139","chrome 138","chrome 137","chrome 112","chrome 109","chrome 105","edge 140","edge 139","edge 138","firefox 143","firefox 142","firefox 141","firefox 140","ios_saf 26.0","ios_saf 18.5-18.6","kaios 3.0-3.1","node 24.8.0","node 22.19.0","node 20.19.0","op_mob 80","opera 122","opera 121","opera 120","safari 26.0","safari 18.5-18.6","samsung 28","samsung 27"] 1`] = `
Object {
"arrowFunction": true,
"asyncFunction": true,
"bigIntLiteral": true,
"browser": null,
"const": true,
"destructuring": true,
"document": null,
"dynamicImport": true,
"dynamicImportInWorker": true,
"electron": false,
"fetchWasm": null,
"forOf": true,
"global": null,
"globalThis": true,
"importScripts": false,
"importScriptsInWorker": false,
"module": true,
"node": null,
"nodeBuiltins": null,
"nodePrefixForCoreModules": null,
"nwjs": false,
"optionalChaining": true,
"require": null,
"templateLiteral": true,
"web": null,
"webworker": false,
}
`;
exports[`browserslist target ["and_ff 68"] 1`] = ` exports[`browserslist target ["and_ff 68"] 1`] = `
Object { Object {
"arrowFunction": true, "arrowFunction": true,
@ -41,7 +72,7 @@ Object {
"destructuring": true, "destructuring": true,
"document": true, "document": true,
"dynamicImport": true, "dynamicImport": true,
"dynamicImportInWorker": true, "dynamicImportInWorker": false,
"electron": false, "electron": false,
"fetchWasm": true, "fetchWasm": true,
"forOf": true, "forOf": true,
@ -65,17 +96,17 @@ Object {
exports[`browserslist target ["and_qq 10.4"] 1`] = ` exports[`browserslist target ["and_qq 10.4"] 1`] = `
Object { Object {
"arrowFunction": true, "arrowFunction": true,
"asyncFunction": false, "asyncFunction": true,
"bigIntLiteral": false, "bigIntLiteral": false,
"browser": true, "browser": true,
"const": true, "const": true,
"destructuring": false, "destructuring": true,
"document": true, "document": true,
"dynamicImport": true, "dynamicImport": true,
"dynamicImportInWorker": true, "dynamicImportInWorker": true,
"electron": false, "electron": false,
"fetchWasm": true, "fetchWasm": true,
"forOf": false, "forOf": true,
"global": false, "global": false,
"globalThis": false, "globalThis": false,
"importScripts": false, "importScripts": false,
@ -93,37 +124,6 @@ Object {
} }
`; `;
exports[`browserslist target ["and_uc 12.12"] 1`] = `
Object {
"arrowFunction": true,
"asyncFunction": false,
"bigIntLiteral": false,
"browser": true,
"const": true,
"destructuring": false,
"document": true,
"dynamicImport": false,
"dynamicImportInWorker": false,
"electron": false,
"fetchWasm": true,
"forOf": false,
"global": false,
"globalThis": false,
"importScripts": false,
"importScriptsInWorker": true,
"module": false,
"node": false,
"nodeBuiltins": false,
"nodePrefixForCoreModules": false,
"nwjs": false,
"optionalChaining": false,
"require": false,
"templateLiteral": true,
"web": true,
"webworker": false,
}
`;
exports[`browserslist target ["android 4"] 1`] = ` exports[`browserslist target ["android 4"] 1`] = `
Object { Object {
"arrowFunction": false, "arrowFunction": false,
@ -320,14 +320,45 @@ Object {
"destructuring": true, "destructuring": true,
"document": null, "document": null,
"dynamicImport": true, "dynamicImport": true,
"dynamicImportInWorker": false, "dynamicImportInWorker": true,
"electron": false, "electron": false,
"fetchWasm": null, "fetchWasm": null,
"forOf": true, "forOf": true,
"global": null, "global": null,
"globalThis": true, "globalThis": true,
"importScripts": false, "importScripts": false,
"importScriptsInWorker": true, "importScriptsInWorker": false,
"module": true,
"node": null,
"nodeBuiltins": null,
"nodePrefixForCoreModules": null,
"nwjs": false,
"optionalChaining": false,
"require": null,
"templateLiteral": true,
"web": null,
"webworker": false,
}
`;
exports[`browserslist target ["chrome 80","node 13.12.0"] 1`] = `
Object {
"arrowFunction": true,
"asyncFunction": true,
"bigIntLiteral": true,
"browser": null,
"const": true,
"destructuring": true,
"document": null,
"dynamicImport": true,
"dynamicImportInWorker": true,
"electron": false,
"fetchWasm": null,
"forOf": true,
"global": null,
"globalThis": true,
"importScripts": false,
"importScriptsInWorker": false,
"module": true, "module": true,
"node": null, "node": null,
"nodeBuiltins": null, "nodeBuiltins": null,
@ -382,7 +413,7 @@ Object {
"destructuring": true, "destructuring": true,
"document": true, "document": true,
"dynamicImport": true, "dynamicImport": true,
"dynamicImportInWorker": true, "dynamicImportInWorker": false,
"electron": false, "electron": false,
"fetchWasm": true, "fetchWasm": true,
"forOf": true, "forOf": true,
@ -413,7 +444,7 @@ Object {
"destructuring": true, "destructuring": true,
"document": true, "document": true,
"dynamicImport": true, "dynamicImport": true,
"dynamicImportInWorker": true, "dynamicImportInWorker": false,
"electron": false, "electron": false,
"fetchWasm": true, "fetchWasm": true,
"forOf": true, "forOf": true,
@ -444,7 +475,7 @@ Object {
"destructuring": true, "destructuring": true,
"document": true, "document": true,
"dynamicImport": true, "dynamicImport": true,
"dynamicImportInWorker": true, "dynamicImportInWorker": false,
"electron": false, "electron": false,
"fetchWasm": true, "fetchWasm": true,
"forOf": true, "forOf": true,
@ -537,7 +568,7 @@ Object {
"destructuring": true, "destructuring": true,
"document": true, "document": true,
"dynamicImport": true, "dynamicImport": true,
"dynamicImportInWorker": true, "dynamicImportInWorker": false,
"electron": false, "electron": false,
"fetchWasm": true, "fetchWasm": true,
"forOf": true, "forOf": true,
@ -606,7 +637,7 @@ Object {
"global": true, "global": true,
"globalThis": false, "globalThis": false,
"importScripts": false, "importScripts": false,
"importScriptsInWorker": true, "importScriptsInWorker": false,
"module": false, "module": false,
"node": true, "node": true,
"nodeBuiltins": true, "nodeBuiltins": true,
@ -637,7 +668,7 @@ Object {
"global": true, "global": true,
"globalThis": false, "globalThis": false,
"importScripts": false, "importScripts": false,
"importScriptsInWorker": true, "importScriptsInWorker": false,
"module": false, "module": false,
"node": true, "node": true,
"nodeBuiltins": true, "nodeBuiltins": true,
@ -668,7 +699,7 @@ Object {
"global": true, "global": true,
"globalThis": false, "globalThis": false,
"importScripts": false, "importScripts": false,
"importScriptsInWorker": true, "importScriptsInWorker": false,
"module": false, "module": false,
"node": true, "node": true,
"nodeBuiltins": true, "nodeBuiltins": true,
@ -699,7 +730,7 @@ Object {
"global": true, "global": true,
"globalThis": false, "globalThis": false,
"importScripts": false, "importScripts": false,
"importScriptsInWorker": true, "importScriptsInWorker": false,
"module": false, "module": false,
"node": true, "node": true,
"nodeBuiltins": true, "nodeBuiltins": true,
@ -723,14 +754,45 @@ Object {
"destructuring": true, "destructuring": true,
"document": false, "document": false,
"dynamicImport": true, "dynamicImport": true,
"dynamicImportInWorker": false, "dynamicImportInWorker": true,
"electron": false, "electron": false,
"fetchWasm": false, "fetchWasm": false,
"forOf": true, "forOf": true,
"global": true, "global": true,
"globalThis": true, "globalThis": true,
"importScripts": false, "importScripts": false,
"importScriptsInWorker": true, "importScriptsInWorker": false,
"module": true,
"node": true,
"nodeBuiltins": true,
"nodePrefixForCoreModules": false,
"nwjs": false,
"optionalChaining": false,
"require": true,
"templateLiteral": true,
"web": false,
"webworker": false,
}
`;
exports[`browserslist target ["node 13.12.0"] 1`] = `
Object {
"arrowFunction": true,
"asyncFunction": true,
"bigIntLiteral": true,
"browser": false,
"const": true,
"destructuring": true,
"document": false,
"dynamicImport": true,
"dynamicImportInWorker": true,
"electron": false,
"fetchWasm": false,
"forOf": true,
"global": true,
"globalThis": true,
"importScripts": false,
"importScriptsInWorker": false,
"module": true, "module": true,
"node": true, "node": true,
"nodeBuiltins": true, "nodeBuiltins": true,
@ -785,7 +847,7 @@ Object {
"destructuring": true, "destructuring": true,
"document": true, "document": true,
"dynamicImport": true, "dynamicImport": true,
"dynamicImportInWorker": true, "dynamicImportInWorker": false,
"electron": false, "electron": false,
"fetchWasm": true, "fetchWasm": true,
"forOf": true, "forOf": true,
@ -816,7 +878,7 @@ Object {
"destructuring": true, "destructuring": true,
"document": true, "document": true,
"dynamicImport": true, "dynamicImport": true,
"dynamicImportInWorker": true, "dynamicImportInWorker": false,
"electron": false, "electron": false,
"fetchWasm": true, "fetchWasm": true,
"forOf": true, "forOf": true,
@ -909,7 +971,7 @@ Object {
"destructuring": true, "destructuring": true,
"document": true, "document": true,
"dynamicImport": true, "dynamicImport": true,
"dynamicImportInWorker": true, "dynamicImportInWorker": false,
"electron": false, "electron": false,
"fetchWasm": true, "fetchWasm": true,
"forOf": true, "forOf": true,
@ -940,7 +1002,7 @@ Object {
"destructuring": true, "destructuring": true,
"document": true, "document": true,
"dynamicImport": true, "dynamicImport": true,
"dynamicImportInWorker": true, "dynamicImportInWorker": false,
"electron": false, "electron": false,
"fetchWasm": true, "fetchWasm": true,
"forOf": true, "forOf": true,
@ -971,7 +1033,7 @@ Object {
"destructuring": true, "destructuring": true,
"document": true, "document": true,
"dynamicImport": true, "dynamicImport": true,
"dynamicImportInWorker": true, "dynamicImportInWorker": false,
"electron": false, "electron": false,
"fetchWasm": true, "fetchWasm": true,
"forOf": true, "forOf": true,
@ -1064,7 +1126,7 @@ Object {
"destructuring": true, "destructuring": true,
"document": true, "document": true,
"dynamicImport": true, "dynamicImport": true,
"dynamicImportInWorker": true, "dynamicImportInWorker": false,
"electron": false, "electron": false,
"fetchWasm": true, "fetchWasm": true,
"forOf": true, "forOf": true,
@ -1095,7 +1157,7 @@ Object {
"destructuring": true, "destructuring": true,
"document": true, "document": true,
"dynamicImport": true, "dynamicImport": true,
"dynamicImportInWorker": true, "dynamicImportInWorker": false,
"electron": false, "electron": false,
"fetchWasm": true, "fetchWasm": true,
"forOf": true, "forOf": true,

View File

@ -0,0 +1,3 @@
body {
background-color: #f0f0f0;
}

View File

@ -0,0 +1,4 @@
.typed-element {
color: #333;
font-size: 16px;
}

View File

@ -0,0 +1,30 @@
"use strict";
// This file is used to generate expected warnings during compilation
// Invalid fetchPriority value - should generate warning
const invalidPriorityUrl = new URL(/* webpackPrefetch: true */ /* webpackFetchPriority: "invalid" */ "./assets/images/priority-invalid.png", import.meta.url);
// Invalid preloadAs (non-string) - should generate warning
const invalidPreloadAs = new URL(
/* webpackPreload: true */
/* webpackPreloadAs: 123 */
"./assets/images/priority-invalid.png",
import.meta.url
);
// Invalid preloadType (non-string) - should generate warning
const invalidPreloadType = new URL(
/* webpackPreload: true */
/* webpackPreloadType: 123 */
"./assets/images/priority-invalid.png",
import.meta.url
);
// Invalid preloadMedia (non-string) - should generate warning
const invalidPreloadMedia = new URL(
/* webpackPreload: true */
/* webpackPreloadMedia: 456 */
"./assets/images/priority-invalid.png",
import.meta.url
);
export default {};

View File

@ -0,0 +1,178 @@
"use strict";
function verifyLink(link, expectations) {
expect(link._type).toBe("link");
expect(link.rel).toBe(expectations.rel);
if (expectations.as) {
expect(link.as).toBe(expectations.as);
}
if (expectations.type !== undefined) {
if (expectations.type) {
expect(link.type).toBe(expectations.type);
} else {
expect(link.type).toBeUndefined();
}
}
if (expectations.media !== undefined) {
if (expectations.media) {
expect(link.media).toBe(expectations.media);
} else {
expect(link.media).toBeUndefined();
}
}
if (expectations.fetchPriority !== undefined) {
if (expectations.fetchPriority) {
expect(link._attributes.fetchpriority).toBe(expectations.fetchPriority);
expect(link.fetchPriority).toBe(expectations.fetchPriority);
} else {
expect(link._attributes.fetchpriority).toBeUndefined();
expect(link.fetchPriority).toBeUndefined();
}
}
if (expectations.href) {
expect(link.href.toString()).toMatch(expectations.href);
}
}
it("should generate all prefetch and preload links", () => {
const urls = {
prefetchHigh: new URL(
/* webpackPrefetch: true */ /* webpackFetchPriority: "high" */
"./assets/images/priority-high.png",
import.meta.url
),
preloadLow: new URL(
/* webpackPreload: true */ /* webpackFetchPriority: "low" */
"./assets/styles/priority-low.css",
import.meta.url
),
prefetchAuto: new URL(
/* webpackPrefetch: true */ /* webpackFetchPriority: "auto" */
"./priority-auto.js",
import.meta.url
),
bothHints: new URL(
/* webpackPrefetch: true */ /* webpackPreload: true */ /* webpackFetchPriority: "high" */
"./assets/images/both-hints.png",
import.meta.url
),
noPriority: new URL(
/* webpackPrefetch: true */
"./assets/images/test.png",
import.meta.url
),
preloadFont: new URL(
/* webpackPreload: true */
"./assets/fonts/test.woff2",
import.meta.url
)
};
const prefetchHighLink = document.head._children.find(
link => link.href.includes("priority-high.png") && link.rel === "prefetch"
);
expect(prefetchHighLink).toBeTruthy();
verifyLink(prefetchHighLink, {
rel: "prefetch",
as: "image",
fetchPriority: "high",
href: /priority-high\.png$/
});
const preloadLowLink = document.head._children.find(
link => link.href.includes("priority-low.css") && link.rel === "preload"
);
expect(preloadLowLink).toBeTruthy();
verifyLink(preloadLowLink, {
rel: "preload",
as: "style",
fetchPriority: "low",
href: /priority-low\.css$/
});
const prefetchAutoLink = document.head._children.find(
link => link.href.includes("priority-auto.js") && link.rel === "prefetch"
);
expect(prefetchAutoLink).toBeTruthy();
verifyLink(prefetchAutoLink, {
rel: "prefetch",
as: "script",
fetchPriority: "auto"
});
const bothHintsLink = document.head._children.find(
link => link.href.includes("both-hints.png")
);
expect(bothHintsLink).toBeTruthy();
expect(bothHintsLink.rel).toBe("preload");
expect(bothHintsLink._attributes.fetchpriority).toBe("high");
const noPriorityLink = document.head._children.find(
link => link.href.includes("test.png") && link.rel === "prefetch" &&
!link._attributes.fetchpriority
);
expect(noPriorityLink).toBeTruthy();
verifyLink(noPriorityLink, {
rel: "prefetch",
as: "image",
fetchPriority: undefined
});
const fontPreloadLink = document.head._children.find(
link => link.href.includes("test.woff2") && link.rel === "preload"
);
expect(fontPreloadLink).toBeTruthy();
verifyLink(fontPreloadLink, {
rel: "preload",
as: "font",
href: /test\.woff2$/
});
});
it("should allow overriding as/type/media via magic comments", () => {
const override = new URL(
/* webpackPreload: true */
/* webpackPreloadAs: "font" */
/* webpackPreloadType: "font/woff2" */
/* webpackPreloadMedia: "(max-width: 600px)" */
"./assets/images/override.png",
import.meta.url
);
const link = document.head._children.find(
l => l.href.includes("override.png") && l.rel === "preload"
);
expect(link).toBeTruthy();
verifyLink(link, {
rel: "preload",
as: "font",
type: "font/woff2",
media: "(max-width: 600px)",
href: /override\.png$/
});
});
it("should accept additional as tokens from Fetch Standard (e.g., sharedworker)", () => {
const u = new URL(
/* webpackPreload: true */
/* webpackPreloadAs: "sharedworker" */
"./priority-auto.js",
import.meta.url
);
const link = document.head._children.find(
l => l.href.includes("priority-auto.js") && l.rel === "preload"
);
expect(link).toBeTruthy();
verifyLink(link, {
rel: "preload",
as: "sharedworker",
href: /priority-auto\.js$/
});
});

View File

@ -0,0 +1,4 @@
"use strict";
// Test asset file
console.log("priority-auto.js loaded");

View File

@ -0,0 +1,66 @@
"use strict";
// Mock document.head structure for testing
const mockCreateElement = (tagName) => {
const element = {
_type: tagName,
_attributes: {},
setAttribute(name, value) {
this._attributes[name] = value;
// Also set as property for fetchPriority
if (name === "fetchpriority") {
this.fetchPriority = value;
}
},
getAttribute(name) {
return this._attributes[name];
}
};
// Set properties based on tag type
if (tagName === "link") {
element.rel = "";
element.as = "";
element.href = "";
element.type = undefined;
element.media = undefined;
element.fetchPriority = undefined;
} else if (tagName === "script") {
element.src = "";
element.async = true;
element.fetchPriority = undefined;
}
return element;
};
module.exports = {
beforeExecute: () => {
// Mock document for browser environment
global.document = {
head: {
_children: [],
appendChild(element) {
this._children.push(element);
}
},
createElement: mockCreateElement
};
// Mock window for import.meta.url
global.window = {
location: {
href: "https://test.example.com/"
}
};
},
findBundle() {
return ["main.js"];
},
moduleScope(scope) {
// Make document available in the module scope
scope.document = global.document;
}
};

View File

@ -0,0 +1,4 @@
"use strict";
// Test JavaScript file
console.log("test.js loaded");

View File

@ -0,0 +1,14 @@
"use strict";
module.exports = [
// Invalid fetchPriority value warning
[
/`webpackFetchPriority` expected "low", "high" or "auto", but received: invalid\./
],
// Invalid preloadAs (non-string)
[/`webpackPreloadAs` expected a string, but received: 123\./],
// Invalid preloadType (non-string)
[/`webpackPreloadType` expected a string, but received: 123\./],
// Invalid preloadMedia (non-string)
[/`webpackPreloadMedia` expected a string, but received: 456\./]
];

View File

@ -0,0 +1,24 @@
"use strict";
/** @type {import("../../../../types").Configuration} */
module.exports = {
mode: "development",
entry: {
main: "./index.js",
warnings: "./generate-warnings.js"
},
output: {
filename: "[name].js",
assetModuleFilename: "[name][ext]",
publicPath: "/public/"
},
target: "web",
module: {
rules: [
{
test: /\.(png|jpg|css|woff2)$/,
type: "asset/resource"
}
]
}
};

View File

@ -15,7 +15,7 @@ module.exports = {
"destructuring": true, "destructuring": true,
"document": false, "document": false,
"dynamicImport": true, "dynamicImport": true,
"dynamicImportInWorker": false, "dynamicImportInWorker": true,
"forOf": true, "forOf": true,
"globalThis": true, "globalThis": true,
"module": true, "module": true,

View File

@ -15,7 +15,7 @@ module.exports = {
"destructuring": true, "destructuring": true,
"document": false, "document": false,
"dynamicImport": true, "dynamicImport": true,
"dynamicImportInWorker": false, "dynamicImportInWorker": true,
"forOf": true, "forOf": true,
"globalThis": true, "globalThis": true,
"module": true, "module": true,

View File

@ -3,7 +3,7 @@ import * as style from "./style.css";
import * as text1 from "./text-with-bom.txt"; import * as text1 from "./text-with-bom.txt";
import * as text2 from "./test-without-bom.text"; import * as text2 from "./test-without-bom.text";
it("should remove BOM", function() { it("should remove BOM", async function() {
const url = new URL("./resource-with-bom.ext", import.meta.url); const url = new URL("./resource-with-bom.ext", import.meta.url);
expect(mod).toBeDefined(); expect(mod).toBeDefined();
@ -13,7 +13,7 @@ it("should remove BOM", function() {
expect(url).toBeDefined(); expect(url).toBeDefined();
const module = "module.js" const module = "module.js"
const modules = import("./dir/" + module); const modules = await import("./dir/" + module);
expect(modules).toBeDefined(); expect(modules).toBeDefined();
}); });

View File

@ -4,6 +4,9 @@ const fs = require("fs");
const path = require("path"); const path = require("path");
module.exports = { module.exports = {
findBundle() {
return ["dir_module_js.bundle0.js", "bundle0.js"];
},
afterExecute(options) { afterExecute(options) {
const outputPath = options.output.path; const outputPath = options.output.path;
const files = fs.readdirSync(outputPath); const files = fs.readdirSync(outputPath);

View File

@ -6,6 +6,9 @@ module.exports = {
output: { output: {
assetModuleFilename: "[name][ext]" assetModuleFilename: "[name][ext]"
}, },
optimization: {
chunkIds: "named"
},
module: { module: {
rules: [ rules: [
{ {

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 B

View File

@ -0,0 +1,49 @@
// Test cases for new URL() prefetch/preload support
it("should prefetch an image asset", () => {
const url = new URL(
/* webpackPrefetch: true */
"./prefetch-image.png",
import.meta.url
);
expect(url.href).toMatch(/prefetch-image\.png$/);
});
it("should preload an image asset", () => {
const url = new URL(
/* webpackPreload: true */
"./preload-image.png",
import.meta.url
);
expect(url.href).toMatch(/preload-image\.png$/);
});
it("should preload with fetch priority", () => {
const url = new URL(
/* webpackPreload: true */
/* webpackFetchPriority: "high" */
"./priority-image.png",
import.meta.url
);
expect(url.href).toMatch(/priority-image\.png$/);
});
it("should handle invalid fetch priority", () => {
const url2 = new URL(
/* webpackPreload: true */
/* webpackFetchPriority: "invalid" */
"./invalid-priority-image.png",
import.meta.url
);
expect(url2.href).toMatch(/invalid-priority-image\.png$/);
});
it("should handle both prefetch and preload", () => {
const url3 = new URL(
/* webpackPrefetch: true */
/* webpackPreload: true */
"./both-hints-image.png",
import.meta.url
);
expect(url3.href).toMatch(/both-hints-image\.png$/);
});

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 B

View File

@ -0,0 +1,7 @@
"use strict";
module.exports = {
findBundle() {
return ["main.js"];
}
};

View File

@ -0,0 +1,5 @@
"use strict";
const supportsWorker = require("../../../helpers/supportsWorker");
module.exports = () => supportsWorker();

View File

@ -0,0 +1,8 @@
"use strict";
module.exports = [
// Invalid fetch priority
[
/`webpackFetchPriority` expected "low", "high" or "auto", but received: invalid\./
]
];

View File

@ -0,0 +1,18 @@
"use strict";
/** @type {import("../../../../types").Configuration} */
module.exports = {
output: {
filename: "[name].js",
assetModuleFilename: "[name][ext]"
},
target: "web",
module: {
rules: [
{
test: /\.png$/,
type: "asset/resource"
}
]
}
};

View File

@ -1,27 +1,39 @@
it("should set fetchPriority", () => { function abortable(fn) {
import(/* webpackFetchPriority: "high" */ "./a"); return new Promise((resolve) => {
const timeoutId = setTimeout(() => {
fn = undefined;
resolve('Promise resolved after delay');
clearTimeout(timeoutId);
}, 1000);
return fn();
});
}
it("should set fetchPriority", async () => {
abortable(() => import(/* webpackFetchPriority: "high" */ "./a"));
expect(document.head._children).toHaveLength(4); expect(document.head._children).toHaveLength(4);
const script1 = document.head._children[2]; const script1 = document.head._children[2];
expect(script1._attributes.fetchpriority).toBe("high"); expect(script1._attributes.fetchpriority).toBe("high");
import(/* webpackFetchPriority: "low" */ "./b"); abortable(() => import(/* webpackFetchPriority: "low" */ "./b"));
expect(document.head._children).toHaveLength(5); expect(document.head._children).toHaveLength(5);
const script2 = document.head._children[4]; const script2 = document.head._children[4];
expect(script2._attributes.fetchpriority).toBe("low"); expect(script2._attributes.fetchpriority).toBe("low");
import(/* webpackFetchPriority: "low" */ "./c"); abortable(() => import(/* webpackFetchPriority: "low" */ "./c"));
expect(document.head._children).toHaveLength(6); expect(document.head._children).toHaveLength(6);
const script3 = document.head._children[5]; const script3 = document.head._children[5];
expect(script3._attributes.fetchpriority).toBe("low"); expect(script3._attributes.fetchpriority).toBe("low");
import(/* webpackPrefetch: 20, webpackFetchPriority: "auto" */ "./c"); abortable(() => import(/* webpackPrefetch: 20, webpackFetchPriority: "auto" */ "./c"));
import("./d") abortable(() => import("./d"))
expect(document.head._children).toHaveLength(7); expect(document.head._children).toHaveLength(7);
const script4 = document.head._children[6]; const script4 = document.head._children[6];
expect(script4._attributes.fetchpriority).toBeUndefined(); expect(script4._attributes.fetchpriority).toBeUndefined();
import(/* webpackPrefetch: -20 */ "./d3"); abortable(() => import(/* webpackPrefetch: -20 */ "./d3"));
expect(document.head._children).toHaveLength(8); expect(document.head._children).toHaveLength(8);
const script5 = document.head._children[7]; const script5 = document.head._children[7];
expect(script5._attributes.fetchpriority).toBeUndefined(); expect(script5._attributes.fetchpriority).toBeUndefined();
@ -29,12 +41,12 @@ it("should set fetchPriority", () => {
const condition = true; const condition = true;
if (!condition) { if (!condition) {
import(/* webpackFetchPriority: "high", webpackChunkName: "one" */ "./e"); abortable( () => import(/* webpackFetchPriority: "high", webpackChunkName: "one" */ "./e"));
expect(document.head._children).toHaveLength(9); expect(document.head._children).toHaveLength(9);
const script6 = document.head._children[8]; const script6 = document.head._children[8];
expect(script6._attributes.fetchpriority).toBe("high"); expect(script6._attributes.fetchpriority).toBe("high");
} else { } else {
import(/* webpackFetchPriority: "low", webpackChunkName: "two" */ "./e"); abortable(() => import(/* webpackFetchPriority: "low", webpackChunkName: "two" */ "./e"));
expect(document.head._children).toHaveLength(9); expect(document.head._children).toHaveLength(9);
const script6 = document.head._children[8]; const script6 = document.head._children[8];
expect(script6._attributes.fetchpriority).toBe("low"); expect(script6._attributes.fetchpriority).toBe("low");

View File

@ -1,13 +1,25 @@
function abortable(fn) {
return new Promise((resolve) => {
const timeoutId = setTimeout(() => {
fn = undefined;
resolve('Promise resolved after delay');
clearTimeout(timeoutId);
}, 1000);
return fn();
});
}
it("should set fetchPriority", () => { it("should set fetchPriority", () => {
// Single Chunk // Single Chunk
import(/* webpackFetchPriority: "high" */ "./a"); abortable(() => import(/* webpackFetchPriority: "high" */ "./a"));
expect(document.head._children).toHaveLength(1); expect(document.head._children).toHaveLength(1);
const script1 = document.head._children[0]; const script1 = document.head._children[0];
expect(script1._attributes.fetchpriority).toBe("high"); expect(script1._attributes.fetchpriority).toBe("high");
// Multiple Chunks // Multiple Chunks
import(/* webpackFetchPriority: "high" */ "./b"); abortable(() => import(/* webpackFetchPriority: "high" */ "./b"));
import(/* webpackFetchPriority: "high" */ "./b2"); abortable(() => import(/* webpackFetchPriority: "high" */ "./b2"));
expect(document.head._children).toHaveLength(4); expect(document.head._children).toHaveLength(4);
const script2 = document.head._children[1]; const script2 = document.head._children[1];
const script3 = document.head._children[2]; const script3 = document.head._children[2];
@ -17,19 +29,19 @@ it("should set fetchPriority", () => {
expect(script4._attributes.fetchpriority).toBe("high"); expect(script4._attributes.fetchpriority).toBe("high");
// Single Chunk, low // Single Chunk, low
import(/* webpackFetchPriority: "low" */ "./c"); abortable(() => import(/* webpackFetchPriority: "low" */ "./c"));
expect(document.head._children).toHaveLength(5); expect(document.head._children).toHaveLength(5);
const script5 = document.head._children[4]; const script5 = document.head._children[4];
expect(script5._attributes.fetchpriority).toBe("low"); expect(script5._attributes.fetchpriority).toBe("low");
// Single Chunk, auto // Single Chunk, auto
import(/* webpackFetchPriority: "auto" */ "./d"); abortable(() => import(/* webpackFetchPriority: "auto" */ "./d"));
expect(document.head._children).toHaveLength(6); expect(document.head._children).toHaveLength(6);
const script6 = document.head._children[5]; const script6 = document.head._children[5];
expect(script6._attributes.fetchpriority).toBe("auto"); expect(script6._attributes.fetchpriority).toBe("auto");
// No fetch priority // No fetch priority
import("./e"); abortable(() => import("./e"));
expect(document.head._children).toHaveLength(7); expect(document.head._children).toHaveLength(7);
const script7 = document.head._children[6]; const script7 = document.head._children[6];
expect(script7._attributes.fetchpriority).toBeUndefined(); expect(script7._attributes.fetchpriority).toBeUndefined();
@ -44,49 +56,49 @@ it("should set fetchPriority", () => {
const script8 = document.head._children[7]; const script8 = document.head._children[7];
expect(script8._attributes.fetchpriority).toBeUndefined(); expect(script8._attributes.fetchpriority).toBeUndefined();
import(/* webpackFetchPriority: "auto" */ "./g"); abortable(() => import(/* webpackFetchPriority: "auto" */ "./g"));
expect(document.head._children).toHaveLength(9); expect(document.head._children).toHaveLength(9);
const script9 = document.head._children[8]; const script9 = document.head._children[8];
expect(script9._attributes.fetchpriority).toBe("auto"); expect(script9._attributes.fetchpriority).toBe("auto");
import(/* webpackFetchPriority: "unknown" */ "./h.js"); abortable(() => import(/* webpackFetchPriority: "unknown" */ "./h.js"));
expect(document.head._children).toHaveLength(10); expect(document.head._children).toHaveLength(10);
const script10 = document.head._children[9]; const script10 = document.head._children[9];
expect(script10._attributes.fetchpriority).toBeUndefined(); expect(script10._attributes.fetchpriority).toBeUndefined();
import(/* webpackFetchPriority: "high" */ "./i"); abortable(() => import(/* webpackFetchPriority: "high" */ "./i"));
import(/* webpackFetchPriority: "low" */ "./i"); abortable(() => import(/* webpackFetchPriority: "low" */ "./i"));
expect(document.head._children).toHaveLength(11); expect(document.head._children).toHaveLength(11);
const script11 = document.head._children[10]; const script11 = document.head._children[10];
expect(script11._attributes.fetchpriority).toBe("high"); expect(script11._attributes.fetchpriority).toBe("high");
import(/* webpackFetchPriority: "low" */ "./j"); abortable(() => import(/* webpackFetchPriority: "low" */ "./j"));
import(/* webpackFetchPriority: "high" */ "./j"); abortable(() => import(/* webpackFetchPriority: "high" */ "./j"));
expect(document.head._children).toHaveLength(12); expect(document.head._children).toHaveLength(12);
const script12 = document.head._children[11]; const script12 = document.head._children[11];
expect(script12._attributes.fetchpriority).toBe("low"); expect(script12._attributes.fetchpriority).toBe("low");
import(/* webpackFetchPriority: "low" */ "./k"); abortable(() => import(/* webpackFetchPriority: "low" */ "./k"));
import("./e"); abortable(() => import("./e"));
import(/* webpackFetchPriority: "high" */ "./k"); abortable(() => import(/* webpackFetchPriority: "high" */ "./k"));
expect(document.head._children).toHaveLength(13); abortable(() => expect(document.head._children).toHaveLength(13));
const script13 = document.head._children[12]; const script13 = document.head._children[12];
expect(script13._attributes.fetchpriority).toBe("low"); expect(script13._attributes.fetchpriority).toBe("low");
__non_webpack_require__("./125.js"); __non_webpack_require__("./125.js");
import(/* webpackFetchPriority: "high" */ "./style.css"); abortable(() => import(/* webpackFetchPriority: "high" */ "./style.css"));
expect(document.head._children).toHaveLength(14); expect(document.head._children).toHaveLength(14);
const link1 = document.head._children[13]; const link1 = document.head._children[13];
expect(link1._attributes.fetchpriority).toBe("high"); expect(link1._attributes.fetchpriority).toBe("high");
__non_webpack_require__("./499.js"); __non_webpack_require__("./499.js");
import("./style-1.css"); abortable(() => import("./style-1.css"));
expect(document.head._children).toHaveLength(15); expect(document.head._children).toHaveLength(15);
const link2 = document.head._children[14]; const link2 = document.head._children[14];
expect(link2._attributes.fetchpriority).toBeUndefined(); expect(link2._attributes.fetchpriority).toBeUndefined();
__non_webpack_require__("./616.js"); __non_webpack_require__("./616.js");
import(/* webpackFetchPriority: "low" */ "./style-2.css"); abortable(() => import(/* webpackFetchPriority: "low" */ "./style-2.css"));
expect(document.head._children).toHaveLength(16); expect(document.head._children).toHaveLength(16);
const link3 = document.head._children[15]; const link3 = document.head._children[15];
expect(link3._attributes.fetchpriority).toBe("low"); expect(link3._attributes.fetchpriority).toBe("low");

View File

@ -57,9 +57,7 @@ describe("browserslist target", () => {
["node 10.0.0"], ["node 10.0.0"],
["node 10.17.0"], ["node 10.17.0"],
["node 12.19.0"], ["node 12.19.0"],
["node 13.12.0"],
// UC browsers for Android
["and_uc 12.12"],
// QQ browser // QQ browser
["and_qq 10.4"], ["and_qq 10.4"],
@ -73,6 +71,45 @@ describe("browserslist target", () => {
// Multiple // Multiple
["firefox 80", "chrome 80"], ["firefox 80", "chrome 80"],
["chrome 80", "node 12.19.0"], ["chrome 80", "node 12.19.0"],
["chrome 80", "node 13.12.0"],
// defaults and fully supports es6-module
// maintained node versions
[
"and_chr 140",
"and_ff 142",
"and_qq 14.9",
"and_uc 15.5",
"android 140",
"chrome 140",
"chrome 139",
"chrome 138",
"chrome 137",
"chrome 112",
"chrome 109",
"chrome 105",
"edge 140",
"edge 139",
"edge 138",
"firefox 143",
"firefox 142",
"firefox 141",
"firefox 140",
"ios_saf 26.0",
"ios_saf 18.5-18.6",
"kaios 3.0-3.1",
"node 24.8.0",
"node 22.19.0",
"node 20.19.0",
"op_mob 80",
"opera 122",
"opera 121",
"opera 120",
"safari 26.0",
"safari 18.5-18.6",
"samsung 28",
"samsung 27"
],
// Unknown // Unknown
["unknown 50"] ["unknown 50"]

View File

@ -17,7 +17,7 @@ module.exports = {
] ]
}, },
plugins: [ plugins: [
new webpack.ProgressPlugin(), new webpack.ProgressPlugin(() => {}),
{ {
apply(compiler) { apply(compiler) {
compiler.hooks.done.tapPromise("CacheTest", async () => { compiler.hooks.done.tapPromise("CacheTest", async () => {

View File

@ -16,7 +16,7 @@ module.exports = {
] ]
}, },
plugins: [ plugins: [
new webpack.ProgressPlugin(), new webpack.ProgressPlugin(() => {}),
{ {
apply(compiler) { apply(compiler) {
compiler.hooks.done.tapPromise("CacheTest", async () => { compiler.hooks.done.tapPromise("CacheTest", async () => {

409
types.d.ts vendored
View File

@ -24,7 +24,7 @@ import {
ClassBody, ClassBody,
ClassDeclaration, ClassDeclaration,
ClassExpression, ClassExpression,
Comment, Comment as CommentImport,
ConditionalExpression, ConditionalExpression,
ContinueStatement, ContinueStatement,
DebuggerStatement, DebuggerStatement,
@ -99,9 +99,11 @@ import {
} from "inspector"; } from "inspector";
import { JSONSchema4, JSONSchema6, JSONSchema7 } from "json-schema"; import { JSONSchema4, JSONSchema6, JSONSchema7 } from "json-schema";
import { ListenOptions } from "net"; import { ListenOptions } from "net";
import { validate as validateFunction } from "schema-utils"; import {
ValidationErrorConfiguration,
validate as validateFunction
} from "schema-utils";
import { default as ValidationError } from "schema-utils/declarations/ValidationError"; import { default as ValidationError } from "schema-utils/declarations/ValidationError";
import { ValidationErrorConfiguration } from "schema-utils/declarations/validate";
import { import {
AsArray, AsArray,
AsyncParallelHook, AsyncParallelHook,
@ -114,7 +116,8 @@ import {
SyncBailHook, SyncBailHook,
SyncHook, SyncHook,
SyncWaterfallHook, SyncWaterfallHook,
TapOptions TapOptions,
TypedHookMap
} from "tapable"; } from "tapable";
import { SecureContextOptions, TlsOptions } from "tls"; import { SecureContextOptions, TlsOptions } from "tls";
import { URL } from "url"; import { URL } from "url";
@ -297,6 +300,14 @@ declare interface Asset {
*/ */
info: AssetInfo; info: AssetInfo;
} }
declare abstract class AssetBytesGenerator extends Generator {
generateError(
error: Error,
module: NormalModule,
generateContext: GenerateContext
): null | Source;
}
declare abstract class AssetBytesParser extends ParserClass {}
declare interface AssetDependencyMeta { declare interface AssetDependencyMeta {
sourceType: "css-url"; sourceType: "css-url";
} }
@ -311,6 +322,25 @@ type AssetFilterItemTypes =
| string | string
| RegExp | RegExp
| ((name: string, asset: StatsAsset) => boolean); | ((name: string, asset: StatsAsset) => boolean);
declare abstract class AssetGenerator extends Generator {
dataUrlOptions?:
| AssetGeneratorDataUrlOptions
| ((
source: string | Buffer,
context: { filename: string; module: Module }
) => string);
filename?: string | ((pathData: PathData, assetInfo?: AssetInfo) => string);
publicPath?: string | ((pathData: PathData, assetInfo?: AssetInfo) => string);
outputPath?: string | ((pathData: PathData, assetInfo?: AssetInfo) => string);
emit?: boolean;
getMimeType(module: NormalModule): string;
generateDataUri(module: NormalModule): string;
generateError(
error: Error,
module: NormalModule,
generateContext: GenerateContext
): null | Source;
}
/** /**
* Options object for data url generation. * Options object for data url generation.
@ -349,6 +379,15 @@ declare interface AssetInlineGeneratorOptions {
context: { filename: string; module: Module } context: { filename: string; module: Module }
) => string); ) => string);
} }
declare abstract class AssetParser extends ParserClass {
dataUrlCondition?:
| boolean
| AssetParserDataUrlOptions
| ((
source: string | Buffer,
context: { filename: string; module: Module }
) => boolean);
}
/** /**
* Options object for DataUrl condition. * Options object for DataUrl condition.
@ -404,6 +443,14 @@ declare interface AssetResourceGeneratorOptions {
*/ */
publicPath?: string | ((pathData: PathData, assetInfo?: AssetInfo) => string); publicPath?: string | ((pathData: PathData, assetInfo?: AssetInfo) => string);
} }
declare abstract class AssetSourceGenerator extends Generator {
generateError(
error: Error,
module: NormalModule,
generateContext: GenerateContext
): null | Source;
}
declare abstract class AssetSourceParser extends ParserClass {}
declare class AsyncDependenciesBlock extends DependenciesBlock { declare class AsyncDependenciesBlock extends DependenciesBlock {
constructor( constructor(
groupOptions: groupOptions:
@ -473,6 +520,7 @@ declare interface AsyncWebAssemblyModulesPluginOptions {
*/ */
mangleImports?: boolean; mangleImports?: boolean;
} }
declare abstract class AsyncWebAssemblyParser extends ParserClass {}
declare class AutomaticPrefetchPlugin { declare class AutomaticPrefetchPlugin {
constructor(); constructor();
@ -2044,6 +2092,11 @@ declare interface ColorsOptions {
*/ */
useColor?: boolean; useColor?: boolean;
} }
declare interface CommentCssParser {
value: string;
range: [number, number];
loc: { start: Position; end: Position };
}
declare interface CommonJsImportSettings { declare interface CommonJsImportSettings {
name?: string; name?: string;
context: string; context: string;
@ -3558,6 +3611,23 @@ declare interface CssData {
*/ */
exports: Map<string, string>; exports: Map<string, string>;
} }
declare abstract class CssGenerator extends Generator {
convention?:
| "as-is"
| "camel-case"
| "camel-case-only"
| "dashes"
| "dashes-only"
| ((name: string) => string);
localIdentName?: string;
exportsOnly?: boolean;
esModule?: boolean;
generateError(
error: Error,
module: NormalModule,
generateContext: GenerateContext
): null | Source;
}
/** /**
* Generator options for css modules. * Generator options for css modules.
@ -3753,6 +3823,19 @@ declare class CssModulesPlugin {
): TemplatePath; ): TemplatePath;
static chunkHasCss(chunk: Chunk, chunkGraph: ChunkGraph): boolean; static chunkHasCss(chunk: Chunk, chunkGraph: ChunkGraph): boolean;
} }
declare abstract class CssParser extends ParserClass {
defaultMode: "global" | "auto" | "pure" | "local";
import: boolean;
url: boolean;
namedExports: boolean;
comments?: CommentCssParser[];
magicCommentContext: Context;
getComments(range: [number, number]): CommentCssParser[];
parseCommentOptions(range: [number, number]): {
options: null | Record<string, any>;
errors: null | (Error & { comment: CommentCssParser })[];
};
}
/** /**
* Parser options for css modules. * Parser options for css modules.
@ -6380,35 +6463,6 @@ declare interface ImportDependencyMeta {
externalType?: "import" | "module"; externalType?: "import" | "module";
} }
type ImportExpressionJavascriptParser = ImportExpressionImport & { type ImportExpressionJavascriptParser = ImportExpressionImport & {
options?:
| null
| ImportExpressionImport
| UnaryExpression
| ArrayExpression
| ArrowFunctionExpression
| AssignmentExpression
| AwaitExpression
| BinaryExpression
| SimpleCallExpression
| NewExpression
| ChainExpression
| ClassExpression
| ConditionalExpression
| FunctionExpression
| Identifier
| SimpleLiteral
| RegExpLiteral
| BigIntLiteral
| LogicalExpression
| MemberExpression
| MetaProperty
| ObjectExpression
| SequenceExpression
| TaggedTemplateExpression
| TemplateLiteral
| ThisExpression
| UpdateExpression
| YieldExpression;
phase?: "defer"; phase?: "defer";
}; };
declare interface ImportModuleOptions { declare interface ImportModuleOptions {
@ -6623,6 +6677,33 @@ declare interface IteratorObject<T, TReturn = unknown, TNext = unknown>
[Symbol.iterator](): IteratorObject<T, TReturn, TNext>; [Symbol.iterator](): IteratorObject<T, TReturn, TNext>;
[Symbol.dispose](): void; [Symbol.dispose](): void;
} }
declare abstract class JavascriptGenerator extends Generator {
generateError(
error: Error,
module: NormalModule,
generateContext: GenerateContext
): null | Source;
sourceModule(
module: Module,
initFragments: InitFragment<GenerateContext>[],
source: ReplaceSource,
generateContext: GenerateContext
): void;
sourceBlock(
module: Module,
block: DependenciesBlock,
initFragments: InitFragment<GenerateContext>[],
source: ReplaceSource,
generateContext: GenerateContext
): void;
sourceDependency(
module: Module,
dependency: Dependency,
initFragments: InitFragment<GenerateContext>[],
source: ReplaceSource,
generateContext: GenerateContext
): void;
}
declare class JavascriptModulesPlugin { declare class JavascriptModulesPlugin {
constructor(options?: object); constructor(options?: object);
options: object; options: object;
@ -7107,15 +7188,15 @@ declare class JavascriptParser extends ParserClass {
[LogicalExpression], [LogicalExpression],
boolean | void boolean | void
>; >;
program: SyncBailHook<[Program, Comment[]], boolean | void>; program: SyncBailHook<[Program, CommentImport[]], boolean | void>;
terminate: SyncBailHook<[ReturnStatement | ThrowStatement], boolean | void>; terminate: SyncBailHook<[ReturnStatement | ThrowStatement], boolean | void>;
finish: SyncBailHook<[Program, Comment[]], boolean | void>; finish: SyncBailHook<[Program, CommentImport[]], boolean | void>;
unusedStatement: SyncBailHook<[Statement], boolean | void>; unusedStatement: SyncBailHook<[Statement], boolean | void>;
}>; }>;
sourceType: "module" | "auto" | "script"; sourceType: "module" | "auto" | "script";
scope: ScopeInfo; scope: ScopeInfo;
state: ParserState; state: ParserState;
comments?: Comment[]; comments?: CommentImport[];
semicolons?: Set<number>; semicolons?: Set<number>;
statementPath?: StatementPathItem[]; statementPath?: StatementPathItem[];
prevStatement?: prevStatement?:
@ -7939,7 +8020,7 @@ declare class JavascriptParser extends ParserClass {
| MaybeNamedClassDeclaration, | MaybeNamedClassDeclaration,
commentsStartPos: number commentsStartPos: number
): boolean; ): boolean;
getComments(range: [number, number]): Comment[]; getComments(range: [number, number]): CommentImport[];
isAsiPosition(pos: number): boolean; isAsiPosition(pos: number): boolean;
setAsiPosition(pos: number): void; setAsiPosition(pos: number): void;
unsetAsiPosition(pos: number): void; unsetAsiPosition(pos: number): void;
@ -7975,7 +8056,7 @@ declare class JavascriptParser extends ParserClass {
evaluatedVariable(tagInfo: TagInfo): VariableInfo; evaluatedVariable(tagInfo: TagInfo): VariableInfo;
parseCommentOptions(range: [number, number]): { parseCommentOptions(range: [number, number]): {
options: null | Record<string, any>; options: null | Record<string, any>;
errors: null | (Error & { comment: Comment })[]; errors: null | (Error & { comment: CommentImport })[];
}; };
extractMemberExpressionChain( extractMemberExpressionChain(
expression: expression:
@ -8327,6 +8408,14 @@ declare abstract class JsonData {
| JsonValueFs[]; | JsonValueFs[];
updateHash(hash: Hash): void; updateHash(hash: Hash): void;
} }
declare abstract class JsonGenerator extends Generator {
options: JsonGeneratorOptions;
generateError(
error: Error,
module: NormalModule,
generateContext: GenerateContext
): null | Source;
}
/** /**
* Generator options for json modules. * Generator options for json modules.
@ -8337,6 +8426,17 @@ declare interface JsonGeneratorOptions {
*/ */
JSONParse?: boolean; JSONParse?: boolean;
} }
declare interface JsonModulesPluginParserOptions {
/**
* The depth of json dependency flagged as `exportInfo`.
*/
exportsDepth?: number;
/**
* Function that executes for a module source string and should return json-compatible data.
*/
parse?: (input: string) => any;
}
declare interface JsonObjectFs { declare interface JsonObjectFs {
[index: string]: [index: string]:
| undefined | undefined
@ -8357,6 +8457,9 @@ declare interface JsonObjectTypes {
| JsonObjectTypes | JsonObjectTypes
| JsonValueTypes[]; | JsonValueTypes[];
} }
declare abstract class JsonParser extends ParserClass {
options: JsonModulesPluginParserOptions;
}
/** /**
* Parser options for JSON modules. * Parser options for JSON modules.
@ -11288,12 +11391,225 @@ declare abstract class NormalModuleFactory extends ModuleFactory {
], ],
Module Module
>; >;
createParser: HookMap<SyncBailHook<[ParserOptions], void | ParserClass>>; createParser: TypedHookMap<
parser: HookMap<SyncBailHook<[any, ParserOptions], void>>; Record<
createGenerator: HookMap< "javascript/auto",
SyncBailHook<[GeneratorOptions], void | Generator> SyncBailHook<[JavascriptParserOptions], JavascriptParser>
> &
Record<
"javascript/dynamic",
SyncBailHook<[JavascriptParserOptions], JavascriptParser>
> &
Record<
"javascript/esm",
SyncBailHook<[JavascriptParserOptions], JavascriptParser>
> &
Record<"json", SyncBailHook<[JsonParserOptions], JsonParser>> &
Record<"asset", SyncBailHook<[AssetParserOptions], AssetParser>> &
Record<
"asset/inline",
SyncBailHook<[EmptyParserOptions], AssetParser>
> &
Record<
"asset/resource",
SyncBailHook<[EmptyParserOptions], AssetParser>
> &
Record<
"asset/source",
SyncBailHook<[EmptyParserOptions], AssetSourceParser>
> &
Record<
"asset/bytes",
SyncBailHook<[EmptyParserOptions], AssetBytesParser>
> &
Record<
"webassembly/async",
SyncBailHook<[EmptyParserOptions], AsyncWebAssemblyParser>
> &
Record<
"webassembly/sync",
SyncBailHook<[EmptyParserOptions], WebAssemblyParser>
> &
Record<"css", SyncBailHook<[CssParserOptions], CssParser>> &
Record<"css/auto", SyncBailHook<[CssAutoParserOptions], CssParser>> &
Record<
"css/module",
SyncBailHook<[CssModuleParserOptions], CssParser>
> &
Record<
"css/global",
SyncBailHook<[CssGlobalParserOptions], CssParser>
> &
Record<string, SyncBailHook<[ParserOptions], ParserClass>>
>;
parser: TypedHookMap<
Record<
"javascript/auto",
SyncBailHook<[JavascriptParser, JavascriptParserOptions], void>
> &
Record<
"javascript/dynamic",
SyncBailHook<[JavascriptParser, JavascriptParserOptions], void>
> &
Record<
"javascript/esm",
SyncBailHook<[JavascriptParser, JavascriptParserOptions], void>
> &
Record<"json", SyncBailHook<[JsonParser, JsonParserOptions], void>> &
Record<"asset", SyncBailHook<[AssetParser, AssetParserOptions], void>> &
Record<
"asset/inline",
SyncBailHook<[AssetParser, EmptyParserOptions], void>
> &
Record<
"asset/resource",
SyncBailHook<[AssetParser, EmptyParserOptions], void>
> &
Record<
"asset/source",
SyncBailHook<[AssetSourceParser, EmptyParserOptions], void>
> &
Record<
"asset/bytes",
SyncBailHook<[AssetBytesParser, EmptyParserOptions], void>
> &
Record<
"webassembly/async",
SyncBailHook<[AsyncWebAssemblyParser, EmptyParserOptions], void>
> &
Record<
"webassembly/sync",
SyncBailHook<[WebAssemblyParser, EmptyParserOptions], void>
> &
Record<"css", SyncBailHook<[CssParser, CssParserOptions], void>> &
Record<
"css/auto",
SyncBailHook<[CssParser, CssAutoParserOptions], void>
> &
Record<
"css/module",
SyncBailHook<[CssParser, CssModuleParserOptions], void>
> &
Record<
"css/global",
SyncBailHook<[CssParser, CssGlobalParserOptions], void>
> &
Record<string, SyncBailHook<[ParserClass, ParserOptions], void>>
>;
createGenerator: TypedHookMap<
Record<
"javascript/auto",
SyncBailHook<[EmptyGeneratorOptions], JavascriptGenerator>
> &
Record<
"javascript/dynamic",
SyncBailHook<[EmptyGeneratorOptions], JavascriptGenerator>
> &
Record<
"javascript/esm",
SyncBailHook<[EmptyGeneratorOptions], JavascriptGenerator>
> &
Record<"json", SyncBailHook<[JsonGeneratorOptions], JsonGenerator>> &
Record<"asset", SyncBailHook<[AssetGeneratorOptions], AssetGenerator>> &
Record<
"asset/inline",
SyncBailHook<[AssetGeneratorOptions], AssetGenerator>
> &
Record<
"asset/resource",
SyncBailHook<[AssetGeneratorOptions], AssetGenerator>
> &
Record<
"asset/source",
SyncBailHook<[EmptyGeneratorOptions], AssetSourceGenerator>
> &
Record<
"asset/bytes",
SyncBailHook<[EmptyGeneratorOptions], AssetBytesGenerator>
> &
Record<
"webassembly/async",
SyncBailHook<[EmptyParserOptions], Generator>
> &
Record<
"webassembly/sync",
SyncBailHook<[EmptyParserOptions], Generator>
> &
Record<"css", SyncBailHook<[CssGeneratorOptions], CssGenerator>> &
Record<
"css/auto",
SyncBailHook<[CssAutoGeneratorOptions], CssGenerator>
> &
Record<
"css/module",
SyncBailHook<[CssModuleGeneratorOptions], CssGenerator>
> &
Record<
"css/global",
SyncBailHook<[CssGlobalGeneratorOptions], CssGenerator>
> &
Record<string, SyncBailHook<[GeneratorOptions], Generator>>
>;
generator: TypedHookMap<
Record<
"javascript/auto",
SyncBailHook<[JavascriptGenerator, EmptyGeneratorOptions], void>
> &
Record<
"javascript/dynamic",
SyncBailHook<[JavascriptGenerator, EmptyGeneratorOptions], void>
> &
Record<
"javascript/esm",
SyncBailHook<[JavascriptGenerator, EmptyGeneratorOptions], void>
> &
Record<
"json",
SyncBailHook<[JsonGenerator, JsonGeneratorOptions], void>
> &
Record<
"asset",
SyncBailHook<[AssetGenerator, AssetGeneratorOptions], void>
> &
Record<
"asset/inline",
SyncBailHook<[AssetGenerator, AssetGeneratorOptions], void>
> &
Record<
"asset/resource",
SyncBailHook<[AssetGenerator, AssetGeneratorOptions], void>
> &
Record<
"asset/source",
SyncBailHook<[AssetSourceGenerator, EmptyGeneratorOptions], void>
> &
Record<
"asset/bytes",
SyncBailHook<[AssetBytesGenerator, EmptyGeneratorOptions], void>
> &
Record<
"webassembly/async",
SyncBailHook<[Generator, EmptyParserOptions], void>
> &
Record<
"webassembly/sync",
SyncBailHook<[Generator, EmptyParserOptions], void>
> &
Record<"css", SyncBailHook<[CssGenerator, CssGeneratorOptions], void>> &
Record<
"css/auto",
SyncBailHook<[CssGenerator, CssAutoGeneratorOptions], void>
> &
Record<
"css/module",
SyncBailHook<[CssGenerator, CssModuleGeneratorOptions], void>
> &
Record<
"css/global",
SyncBailHook<[CssGenerator, CssGlobalGeneratorOptions], void>
> &
Record<string, SyncBailHook<[Generator, GeneratorOptions], void>>
>; >;
generator: HookMap<SyncBailHook<[any, GeneratorOptions], void>>;
createModuleClass: HookMap< createModuleClass: HookMap<
SyncBailHook< SyncBailHook<
[ [
@ -13166,6 +13482,10 @@ declare interface PnpApi {
options: { considerBuiltins: boolean } options: { considerBuiltins: boolean }
) => null | string; ) => null | string;
} }
declare interface Position {
line: number;
column: number;
}
declare class PrefetchPlugin { declare class PrefetchPlugin {
constructor(context: string, request?: string); constructor(context: string, request?: string);
context: null | string; context: null | string;
@ -17815,6 +18135,7 @@ declare abstract class WeakTupleMap<K extends any[], V> {
delete(...args: K): void; delete(...args: K): void;
clear(): void; clear(): void;
} }
declare abstract class WebAssemblyParser extends ParserClass {}
declare interface WebAssemblyRenderContext { declare interface WebAssemblyRenderContext {
/** /**
* the chunk * the chunk
@ -18448,8 +18769,10 @@ declare namespace exports {
export let moduleLoaded: "module.loaded"; export let moduleLoaded: "module.loaded";
export let nodeModuleDecorator: "__webpack_require__.nmd"; export let nodeModuleDecorator: "__webpack_require__.nmd";
export let onChunksLoaded: "__webpack_require__.O"; export let onChunksLoaded: "__webpack_require__.O";
export let prefetchAsset: "__webpack_require__.PA";
export let prefetchChunk: "__webpack_require__.E"; export let prefetchChunk: "__webpack_require__.E";
export let prefetchChunkHandlers: "__webpack_require__.F"; export let prefetchChunkHandlers: "__webpack_require__.F";
export let preloadAsset: "__webpack_require__.LA";
export let preloadChunk: "__webpack_require__.G"; export let preloadChunk: "__webpack_require__.G";
export let preloadChunkHandlers: "__webpack_require__.H"; export let preloadChunkHandlers: "__webpack_require__.H";
export let publicPath: "__webpack_require__.p"; export let publicPath: "__webpack_require__.p";

View File

@ -2393,7 +2393,7 @@ camelcase@^6.3.0:
resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-6.3.0.tgz#5685b95eb209ac9c0c177467778c9c84df58ba9a"
integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA== integrity sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==
caniuse-lite@^1.0.30001737, caniuse-lite@^1.0.30001746: caniuse-lite@^1.0.30001746:
version "1.0.30001746" version "1.0.30001746"
resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001746.tgz#199d20f04f5369825e00ff7067d45d5dfa03aee7" resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001746.tgz#199d20f04f5369825e00ff7067d45d5dfa03aee7"
integrity sha512-eA7Ys/DGw+pnkWWSE/id29f2IcPHVoE8wxtvE5JdvD2V28VTDPy1yEeo11Guz0sJ4ZeGRcm3uaTcAqK1LXaphA== integrity sha512-eA7Ys/DGw+pnkWWSE/id29f2IcPHVoE8wxtvE5JdvD2V28VTDPy1yEeo11Guz0sJ4ZeGRcm3uaTcAqK1LXaphA==
@ -3034,7 +3034,7 @@ eastasianwidth@^0.2.0:
resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb" resolved "https://registry.yarnpkg.com/eastasianwidth/-/eastasianwidth-0.2.0.tgz#696ce2ec0aa0e6ea93a397ffcf24aa7840c827cb"
integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA== integrity sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==
electron-to-chromium@^1.5.211, electron-to-chromium@^1.5.227: electron-to-chromium@^1.5.227:
version "1.5.228" version "1.5.228"
resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.228.tgz#38b849bc8714bd21fb64f5ad56bf8cfd8638e1e9" resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.5.228.tgz#38b849bc8714bd21fb64f5ad56bf8cfd8638e1e9"
integrity sha512-nxkiyuqAn4MJ1QbobwqJILiDtu/jk14hEAWaMiJmNPh1Z+jqoFlBFZjdXwLWGeVSeu9hGLg6+2G9yJaW8rBIFA== integrity sha512-nxkiyuqAn4MJ1QbobwqJILiDtu/jk14hEAWaMiJmNPh1Z+jqoFlBFZjdXwLWGeVSeu9hGLg6+2G9yJaW8rBIFA==
@ -6247,7 +6247,7 @@ node-preload@^0.2.1:
dependencies: dependencies:
process-on-spawn "^1.0.0" process-on-spawn "^1.0.0"
node-releases@^2.0.19, node-releases@^2.0.21: node-releases@^2.0.21:
version "2.0.21" version "2.0.21"
resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.21.tgz#f59b018bc0048044be2d4c4c04e4c8b18160894c" resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.21.tgz#f59b018bc0048044be2d4c4c04e4c8b18160894c"
integrity sha512-5b0pgg78U3hwXkCM8Z9b2FJdPZlr9Psr9V2gQPESdGHqbntyFJKFW4r5TeWGFzafGY3hzs1JC62VEQMbl1JFkw== integrity sha512-5b0pgg78U3hwXkCM8Z9b2FJdPZlr9Psr9V2gQPESdGHqbntyFJKFW4r5TeWGFzafGY3hzs1JC62VEQMbl1JFkw==
@ -7179,10 +7179,10 @@ schema-utils@^3.0.0, schema-utils@^3.1.1:
ajv "^6.12.5" ajv "^6.12.5"
ajv-keywords "^3.5.2" ajv-keywords "^3.5.2"
schema-utils@^4.0.0, schema-utils@^4.3.0, schema-utils@^4.3.2: schema-utils@^4.0.0, schema-utils@^4.3.0, schema-utils@^4.3.3:
version "4.3.2" version "4.3.3"
resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-4.3.2.tgz#0c10878bf4a73fd2b1dfd14b9462b26788c806ae" resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-4.3.3.tgz#5b1850912fa31df90716963d45d9121fdfc09f46"
integrity sha512-Gn/JaSk/Mt9gYubxTtSn/QCV4em9mpAPiR1rqy/Ocu19u/G9J5WWdNoUT4SiV6mFC3y6cxyFcFwdzPM3FgxGAQ== integrity sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA==
dependencies: dependencies:
"@types/json-schema" "^7.0.9" "@types/json-schema" "^7.0.9"
ajv "^8.9.0" ajv "^8.9.0"
@ -7685,10 +7685,10 @@ synckit@^0.11.7, synckit@^0.11.8:
dependencies: dependencies:
"@pkgr/core" "^0.2.4" "@pkgr/core" "^0.2.4"
tapable@^2.2.0, tapable@^2.2.1, tapable@^2.2.3: tapable@^2.2.0, tapable@^2.2.1, tapable@^2.3.0:
version "2.2.3" version "2.3.0"
resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.2.3.tgz#4b67b635b2d97578a06a2713d2f04800c237e99b" resolved "https://registry.yarnpkg.com/tapable/-/tapable-2.3.0.tgz#7e3ea6d5ca31ba8e078b560f0d83ce9a14aa8be6"
integrity sha512-ZL6DDuAlRlLGghwcfmSn9sK3Hr6ArtyudlSAiCqQ6IfE+b+HHbydbYDIG15IfS5do+7XQQBdBiubF/cV2dnDzg== integrity sha512-g9ljZiwki/LfxmQADO3dEY1CbpmXT5Hm2fJ+QaGKwSXUylMybePR7/67YW7jOrrvjEgL1Fmz5kzyAjWVWLlucg==
tar@^7.4.3: tar@^7.4.3:
version "7.4.3" version "7.4.3"
@ -7973,10 +7973,10 @@ typedarray-to-buffer@^3.1.5:
dependencies: dependencies:
is-typedarray "^1.0.0" is-typedarray "^1.0.0"
typescript@^5.9.2: typescript@^5.9.3:
version "5.9.2" version "5.9.3"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.9.2.tgz#d93450cddec5154a2d5cabe3b8102b83316fb2a6" resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.9.3.tgz#5b4f59e15310ab17a216f5d6cf53ee476ede670f"
integrity sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A== integrity sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==
uglify-js@^3.1.4: uglify-js@^3.1.4:
version "3.19.3" version "3.19.3"