Merge branch 'main' into fix-12408
This commit is contained in:
commit
07242beec5
|
@ -1436,7 +1436,7 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
|
|||
* @returns {void}
|
||||
*/
|
||||
_processModuleDependencies(module, callback) {
|
||||
/** @type {Array<{factory: ModuleFactory, dependencies: Dependency[], originModule: Module|null}>} */
|
||||
/** @type {Array<{factory: ModuleFactory, dependencies: Dependency[], context: string|undefined, originModule: Module|null}>} */
|
||||
const sortedDependencies = [];
|
||||
|
||||
/** @type {DependenciesBlock} */
|
||||
|
@ -1668,6 +1668,7 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
|
|||
sortedDependencies.push({
|
||||
factory: factoryCacheKey2,
|
||||
dependencies: list,
|
||||
context: dep.getContext(),
|
||||
originModule: module
|
||||
});
|
||||
}
|
||||
|
|
|
@ -545,8 +545,21 @@ class Compiler {
|
|||
*/
|
||||
runAsChild(callback) {
|
||||
const startTime = Date.now();
|
||||
|
||||
const finalCallback = (err, entries, compilation) => {
|
||||
try {
|
||||
callback(err, entries, compilation);
|
||||
} catch (e) {
|
||||
const err = new WebpackError(
|
||||
`compiler.runAsChild callback error: ${e}`
|
||||
);
|
||||
err.details = e.stack;
|
||||
this.parentCompilation.errors.push(err);
|
||||
}
|
||||
};
|
||||
|
||||
this.compile((err, compilation) => {
|
||||
if (err) return callback(err);
|
||||
if (err) return finalCallback(err);
|
||||
|
||||
this.parentCompilation.children.push(compilation);
|
||||
for (const { name, source, info } of compilation.getAssets()) {
|
||||
|
@ -561,7 +574,7 @@ class Compiler {
|
|||
compilation.startTime = startTime;
|
||||
compilation.endTime = Date.now();
|
||||
|
||||
return callback(null, entries, compilation);
|
||||
return finalCallback(null, entries, compilation);
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
@ -1104,9 +1104,13 @@ module.exports = webpackEmptyAsyncContext;`;
|
|||
)
|
||||
);
|
||||
const set = new Set();
|
||||
const allDeps = /** @type {ContextElementDependency[]} */ (
|
||||
this.dependencies.concat(this.blocks.map(b => b.dependencies[0]))
|
||||
);
|
||||
const allDeps =
|
||||
this.dependencies.length > 0
|
||||
? /** @type {ContextElementDependency[]} */ (this.dependencies).slice()
|
||||
: [];
|
||||
for (const block of this.blocks)
|
||||
for (const dep of block.dependencies)
|
||||
allDeps.push(/** @type {ContextElementDependency} */ (dep));
|
||||
set.add(RuntimeGlobals.module);
|
||||
set.add(RuntimeGlobals.hasOwnProperty);
|
||||
if (allDeps.length > 0) {
|
||||
|
|
|
@ -292,7 +292,6 @@ module.exports = class ContextModuleFactory extends ModuleFactory {
|
|||
} = options;
|
||||
if (!regExp || !resource) return callback(null, []);
|
||||
|
||||
let severalContexts = false;
|
||||
const addDirectoryChecked = (ctx, directory, visited, callback) => {
|
||||
fs.realpath(directory, (err, realPath) => {
|
||||
if (err) return callback(err);
|
||||
|
@ -359,15 +358,13 @@ module.exports = class ContextModuleFactory extends ModuleFactory {
|
|||
alternatives = alternatives
|
||||
.filter(obj => regExp.test(obj.request))
|
||||
.map(obj => {
|
||||
const request = severalContexts
|
||||
? join(fs, obj.context, obj.request)
|
||||
: obj.request;
|
||||
const dep = new ContextElementDependency(
|
||||
request + resourceQuery + resourceFragment,
|
||||
`${obj.request}${resourceQuery}${resourceFragment}`,
|
||||
obj.request,
|
||||
typePrefix,
|
||||
category,
|
||||
referencedExports
|
||||
referencedExports,
|
||||
obj.context
|
||||
);
|
||||
dep.optional = true;
|
||||
return dep;
|
||||
|
@ -414,7 +411,6 @@ module.exports = class ContextModuleFactory extends ModuleFactory {
|
|||
if (typeof resource === "string") {
|
||||
visitResource(resource, callback);
|
||||
} else {
|
||||
severalContexts = true;
|
||||
asyncLib.map(resource, visitResource, (err, result) => {
|
||||
if (err) return callback(err);
|
||||
|
||||
|
|
|
@ -182,6 +182,13 @@ class Dependency {
|
|||
this._loc = undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {string | undefined} a request context
|
||||
*/
|
||||
getContext() {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {string | null} an identifier to merge equal requests
|
||||
*/
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
"use strict";
|
||||
|
||||
const { create: createResolver } = require("enhanced-resolve");
|
||||
const nodeModule = require("module");
|
||||
const asyncLib = require("neo-async");
|
||||
const AsyncQueue = require("./util/AsyncQueue");
|
||||
const StackedCacheMap = require("./util/StackedCacheMap");
|
||||
|
@ -22,6 +23,8 @@ const processAsyncTree = require("./util/processAsyncTree");
|
|||
|
||||
const supportsEsm = +process.versions.modules >= 83;
|
||||
|
||||
const builtinModules = new Set(nodeModule.builtinModules);
|
||||
|
||||
let FS_ACCURACY = 2000;
|
||||
|
||||
const EMPTY_SET = new Set();
|
||||
|
@ -1673,6 +1676,11 @@ class FileSystemInfo {
|
|||
// e.g. import.meta
|
||||
continue;
|
||||
}
|
||||
|
||||
// we should not track Node.js build dependencies
|
||||
if (dependency.startsWith("node:")) continue;
|
||||
if (builtinModules.has(dependency)) continue;
|
||||
|
||||
push({
|
||||
type: RBDT_RESOLVE_ESM_FILE,
|
||||
context,
|
||||
|
|
|
@ -639,10 +639,14 @@ class PackContentItems {
|
|||
} catch (e) {
|
||||
rollback(s);
|
||||
if (e === NOT_SERIALIZABLE) continue;
|
||||
logger.warn(
|
||||
`Skipped not serializable cache item '${key}': ${e.message}`
|
||||
);
|
||||
logger.debug(e.stack);
|
||||
const msg = "Skipped not serializable cache item";
|
||||
if (e.message.includes("ModuleBuildError")) {
|
||||
logger.log(`${msg} (in build error): ${e.message}`);
|
||||
logger.debug(`${msg} '${key}' (in build error): ${e.stack}`);
|
||||
} else {
|
||||
logger.warn(`${msg}: ${e.message}`);
|
||||
logger.debug(`${msg} '${key}': ${e.stack}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
write(null);
|
||||
|
|
|
@ -14,11 +14,27 @@ const ModuleDependency = require("./ModuleDependency");
|
|||
/** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */
|
||||
|
||||
class ContextElementDependency extends ModuleDependency {
|
||||
constructor(request, userRequest, typePrefix, category, referencedExports) {
|
||||
/**
|
||||
* @param {string} request request
|
||||
* @param {string|undefined} userRequest user request
|
||||
* @param {string} typePrefix type prefix
|
||||
* @param {string} category category
|
||||
* @param {string[][]=} referencedExports referenced exports
|
||||
* @param {string=} context context
|
||||
*/
|
||||
constructor(
|
||||
request,
|
||||
userRequest,
|
||||
typePrefix,
|
||||
category,
|
||||
referencedExports,
|
||||
context
|
||||
) {
|
||||
super(request);
|
||||
this.referencedExports = referencedExports;
|
||||
this._typePrefix = typePrefix;
|
||||
this._category = category;
|
||||
this._context = context || undefined;
|
||||
|
||||
if (userRequest) {
|
||||
this.userRequest = userRequest;
|
||||
|
@ -33,6 +49,20 @@ class ContextElementDependency extends ModuleDependency {
|
|||
return "context element";
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {string | undefined} a request context
|
||||
*/
|
||||
getContext() {
|
||||
return this._context;
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns {string | null} an identifier to merge equal requests
|
||||
*/
|
||||
getResourceIdentifier() {
|
||||
return `context${this._context || ""}|${super.getResourceIdentifier()}`;
|
||||
}
|
||||
|
||||
get category() {
|
||||
return this._category;
|
||||
}
|
||||
|
@ -56,6 +86,7 @@ class ContextElementDependency extends ModuleDependency {
|
|||
const { write } = context;
|
||||
write(this._typePrefix);
|
||||
write(this._category);
|
||||
write(this._context);
|
||||
write(this.referencedExports);
|
||||
super.serialize(context);
|
||||
}
|
||||
|
@ -64,6 +95,7 @@ class ContextElementDependency extends ModuleDependency {
|
|||
const { read } = context;
|
||||
this._typePrefix = read();
|
||||
this._category = read();
|
||||
this._context = read();
|
||||
this.referencedExports = read();
|
||||
super.deserialize(context);
|
||||
}
|
||||
|
|
|
@ -28,7 +28,8 @@ module.exports = function () {
|
|||
var currentStatus = "idle";
|
||||
|
||||
// while downloading
|
||||
var blockingPromises;
|
||||
var blockingPromises = 0;
|
||||
var blockingPromisesWaiting = [];
|
||||
|
||||
// The update info
|
||||
var currentUpdateApplyHandlers;
|
||||
|
@ -218,17 +219,28 @@ module.exports = function () {
|
|||
return Promise.all(results);
|
||||
}
|
||||
|
||||
function unblock() {
|
||||
if (--blockingPromises === 0) {
|
||||
setStatus("ready").then(function () {
|
||||
if (blockingPromises === 0) {
|
||||
var list = blockingPromisesWaiting;
|
||||
blockingPromisesWaiting = [];
|
||||
for (var i = 0; i < list.length; i++) {
|
||||
list[i]();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function trackBlockingPromise(promise) {
|
||||
switch (currentStatus) {
|
||||
case "ready":
|
||||
setStatus("prepare");
|
||||
blockingPromises.push(promise);
|
||||
waitForBlockingPromises(function () {
|
||||
return setStatus("ready");
|
||||
});
|
||||
return promise;
|
||||
/* fallthrough */
|
||||
case "prepare":
|
||||
blockingPromises.push(promise);
|
||||
blockingPromises++;
|
||||
promise.then(unblock, unblock);
|
||||
return promise;
|
||||
default:
|
||||
return promise;
|
||||
|
@ -236,11 +248,11 @@ module.exports = function () {
|
|||
}
|
||||
|
||||
function waitForBlockingPromises(fn) {
|
||||
if (blockingPromises.length === 0) return fn();
|
||||
var blocker = blockingPromises;
|
||||
blockingPromises = [];
|
||||
return Promise.all(blocker).then(function () {
|
||||
return waitForBlockingPromises(fn);
|
||||
if (blockingPromises === 0) return fn();
|
||||
return new Promise(function (resolve) {
|
||||
blockingPromisesWaiting.push(function () {
|
||||
resolve(fn());
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -261,7 +273,6 @@ module.exports = function () {
|
|||
|
||||
return setStatus("prepare").then(function () {
|
||||
var updatedModules = [];
|
||||
blockingPromises = [];
|
||||
currentUpdateApplyHandlers = [];
|
||||
|
||||
return Promise.all(
|
||||
|
@ -298,7 +309,11 @@ module.exports = function () {
|
|||
function hotApply(options) {
|
||||
if (currentStatus !== "ready") {
|
||||
return Promise.resolve().then(function () {
|
||||
throw new Error("apply() is only allowed in ready status");
|
||||
throw new Error(
|
||||
"apply() is only allowed in ready status (state: " +
|
||||
currentStatus +
|
||||
")"
|
||||
);
|
||||
});
|
||||
}
|
||||
return internalApply(options);
|
||||
|
|
|
@ -443,15 +443,16 @@ module.exports = function () {
|
|||
) {
|
||||
promises.push($loadUpdateChunk$(chunkId, updatedModulesList));
|
||||
currentUpdateChunks[chunkId] = true;
|
||||
} else {
|
||||
currentUpdateChunks[chunkId] = false;
|
||||
}
|
||||
});
|
||||
if ($ensureChunkHandlers$) {
|
||||
$ensureChunkHandlers$.$key$Hmr = function (chunkId, promises) {
|
||||
if (
|
||||
currentUpdateChunks &&
|
||||
!$hasOwnProperty$(currentUpdateChunks, chunkId) &&
|
||||
$hasOwnProperty$($installedChunks$, chunkId) &&
|
||||
$installedChunks$[chunkId] !== undefined
|
||||
$hasOwnProperty$(currentUpdateChunks, chunkId) &&
|
||||
!currentUpdateChunks[chunkId]
|
||||
) {
|
||||
promises.push($loadUpdateChunk$(chunkId));
|
||||
currentUpdateChunks[chunkId] = true;
|
||||
|
|
|
@ -310,9 +310,11 @@ class UmdLibraryPlugin extends AbstractLibraryPlugin {
|
|||
: " var a = factory();\n") +
|
||||
" for(var i in a) (typeof exports === 'object' ? exports : root)[i] = a[i];\n" +
|
||||
" }\n") +
|
||||
`})(${
|
||||
runtimeTemplate.outputOptions.globalObject
|
||||
}, function(${externalsArguments(externals)}) {\nreturn `,
|
||||
`})(${runtimeTemplate.outputOptions.globalObject}, ${
|
||||
runtimeTemplate.supportsArrowFunction()
|
||||
? `(${externalsArguments(externals)}) =>`
|
||||
: `function(${externalsArguments(externals)})`
|
||||
} {\nreturn `,
|
||||
"webpack/universalModuleDefinition"
|
||||
),
|
||||
source,
|
||||
|
|
|
@ -288,7 +288,7 @@ class JsonpChunkLoadingRuntimeModule extends RuntimeModule {
|
|||
"var waitingUpdateResolves = {};",
|
||||
"function loadUpdateChunk(chunkId, updatedModulesList) {",
|
||||
Template.indent([
|
||||
`if (updatedModulesList) currentUpdatedModulesList = updatedModulesList;`,
|
||||
"currentUpdatedModulesList = updatedModulesList;",
|
||||
`return new Promise(${runtimeTemplate.basicFunction(
|
||||
"resolve, reject",
|
||||
[
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "webpack",
|
||||
"version": "5.70.0",
|
||||
"version": "5.71.0",
|
||||
"author": "Tobias Koppers @sokra",
|
||||
"description": "Packs CommonJs/AMD modules for the browser. Allows to split your codebase into multiple bundles, which can be loaded on demand. Support loaders to preprocess files, i.e. json, jsx, es7, css, less, ... and your custom stuff.",
|
||||
"license": "MIT",
|
||||
|
|
|
@ -133,7 +133,7 @@ describe("BuildDependencies", () => {
|
|||
);
|
||||
fs.writeFileSync(
|
||||
path.resolve(inputDirectory, "esm-async-dependency.mjs"),
|
||||
"export default 0;"
|
||||
'import path from "node:path"; import vm from "vm"; export default 0;'
|
||||
);
|
||||
await exec("0", {
|
||||
invalidBuildDependencies: true,
|
||||
|
|
|
@ -619,7 +619,12 @@ const describeCases = config => {
|
|||
const fn = runInNewContext
|
||||
? vm.runInNewContext(code, globalContext, p)
|
||||
: vm.runInThisContext(code, p);
|
||||
fn.call(m.exports, ...argValues);
|
||||
fn.call(
|
||||
testConfig.nonEsmThis
|
||||
? testConfig.nonEsmThis(module)
|
||||
: m.exports,
|
||||
...argValues
|
||||
);
|
||||
document.currentScript = oldCurrentScript;
|
||||
return m.exports;
|
||||
}
|
||||
|
|
|
@ -148,9 +148,10 @@ describe("ContextModuleFactory", () => {
|
|||
expect(res).not.toStrictEqual([]);
|
||||
expect(Array.isArray(res)).toBe(true);
|
||||
expect(res.map(r => r.request)).toEqual([
|
||||
"/a/B/a?query#hash",
|
||||
"/b/A/b?query#hash"
|
||||
"./B/a?query#hash",
|
||||
"./A/b?query#hash"
|
||||
]);
|
||||
expect(res.map(r => r.getContext())).toEqual(["/a", "/b"]);
|
||||
expect(res.map(r => r.userRequest)).toEqual(["./B/a", "./A/b"]);
|
||||
done();
|
||||
}
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
export const log = 1;
|
|
@ -0,0 +1,13 @@
|
|||
async function dynamic_import(dir, name) {
|
||||
if (dir === "a") {
|
||||
return import(
|
||||
/* webpackChunkName: "a" */
|
||||
/* webpackMode: "lazy-once" */
|
||||
`./dynamic_a/${name}.js`);
|
||||
}
|
||||
throw new Error();
|
||||
}
|
||||
|
||||
it("should compile and run", async () => {
|
||||
await dynamic_import("a", "module_a1");
|
||||
});
|
|
@ -0,0 +1,19 @@
|
|||
const locales = import.meta.webpackContext('./locales', {
|
||||
recursive: false,
|
||||
regExp: /(en|hu)\.json$/i,
|
||||
});
|
||||
const vuetify = import.meta.webpackContext('vuetify/lib/locale', {
|
||||
recursive: false,
|
||||
regExp: /(en|hu)\.json$/i,
|
||||
});
|
||||
|
||||
it('should resolve "./locales"', () => {
|
||||
expect(locales("./en.json")).toEqual({});
|
||||
expect(() => locales("./hu.json")).toThrow();
|
||||
});
|
||||
|
||||
it('should resolve "vuetify"', () => {
|
||||
expect(vuetify("./en.json")).toEqual({});
|
||||
expect(vuetify("./hu.json")).toEqual({});
|
||||
expect(() => vuetify("./ru.json")).toThrow();
|
||||
});
|
|
@ -0,0 +1 @@
|
|||
{}
|
1
test/configCases/resolve/issue-15580/node_modules/vuetify/lib/locale/en.json
generated
vendored
Normal file
1
test/configCases/resolve/issue-15580/node_modules/vuetify/lib/locale/en.json
generated
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
{}
|
1
test/configCases/resolve/issue-15580/node_modules/vuetify/lib/locale/hu.json
generated
vendored
Normal file
1
test/configCases/resolve/issue-15580/node_modules/vuetify/lib/locale/hu.json
generated
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
{}
|
1
test/configCases/resolve/issue-15580/node_modules/vuetify/lib/locale/ru.json
generated
vendored
Normal file
1
test/configCases/resolve/issue-15580/node_modules/vuetify/lib/locale/ru.json
generated
vendored
Normal file
|
@ -0,0 +1 @@
|
|||
{}
|
4
test/configCases/resolve/issue-15580/node_modules/vuetify/package.json
generated
vendored
Normal file
4
test/configCases/resolve/issue-15580/node_modules/vuetify/package.json
generated
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"name": "vuetify",
|
||||
"version": "1.0.0"
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
const path = require("path");
|
||||
|
||||
/** @type {import("../../../../").Configuration} */
|
||||
module.exports = {
|
||||
resolve: {
|
||||
modules: ["node_modules", path.resolve(__dirname, "./node_modules")]
|
||||
}
|
||||
};
|
|
@ -0,0 +1,5 @@
|
|||
it("should compile and run", () => {
|
||||
expect(hello()).toBe("hello");
|
||||
});
|
||||
|
||||
export function hello() { return "hello"; }
|
|
@ -0,0 +1,9 @@
|
|||
const CONTEXT = {};
|
||||
module.exports = {
|
||||
nonEsmThis(module) {
|
||||
return CONTEXT;
|
||||
},
|
||||
findBundle() {
|
||||
return ["./runtime.js", "./main.js"];
|
||||
}
|
||||
};
|
|
@ -0,0 +1,19 @@
|
|||
/** @type {import("../../../../").Configuration} */
|
||||
module.exports = {
|
||||
mode: "production",
|
||||
entry: {
|
||||
main: "./index.js"
|
||||
},
|
||||
output: {
|
||||
filename: "[name].js",
|
||||
library: "MyLibrary",
|
||||
libraryTarget: "umd",
|
||||
chunkLoading: "jsonp",
|
||||
chunkFormat: "array-push",
|
||||
globalObject: "this"
|
||||
},
|
||||
optimization: {
|
||||
minimize: false,
|
||||
runtimeChunk: "single"
|
||||
}
|
||||
};
|
|
@ -5,22 +5,27 @@ module.hot.accept("./file");
|
|||
const asyncNext = () => {
|
||||
return new Promise((resolve, reject) => {
|
||||
NEXT((err, stats) => {
|
||||
if(err) return reject(err);
|
||||
if (err) return reject(err);
|
||||
resolve(stats);
|
||||
});
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
it("should download the missing update chunk on import", () => {
|
||||
expect(value).toBe(1);
|
||||
return asyncNext().then(() => {
|
||||
return module.hot.check().then(() => {
|
||||
return import("./chunk").then(chunk => {
|
||||
return Promise.all([
|
||||
import("./chunk"),
|
||||
import("./unaffected-chunk")
|
||||
]).then(([chunk, unaffectedChunk]) => {
|
||||
expect(value).toBe(1);
|
||||
expect(chunk.default).toBe(10);
|
||||
expect(unaffectedChunk.default).toBe(10);
|
||||
return module.hot.apply().then(() => {
|
||||
expect(value).toBe(2);
|
||||
expect(chunk.default).toBe(20);
|
||||
expect(unaffectedChunk.default).toBe(10);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
import value from "./unaffected-inner";
|
||||
|
||||
module.hot.accept("./unaffected-inner");
|
||||
|
||||
export { value as default };
|
|
@ -0,0 +1 @@
|
|||
export default 10;
|
|
@ -2462,7 +2462,7 @@ declare interface ContainerReferencePluginOptions {
|
|||
shareScope?: string;
|
||||
}
|
||||
declare abstract class ContextElementDependency extends ModuleDependency {
|
||||
referencedExports: any;
|
||||
referencedExports?: string[][];
|
||||
}
|
||||
declare class ContextExclusionPlugin {
|
||||
constructor(negativeMatcher: RegExp);
|
||||
|
@ -2645,6 +2645,7 @@ declare class Dependency {
|
|||
endLine?: any,
|
||||
endColumn?: any
|
||||
): void;
|
||||
getContext(): undefined | string;
|
||||
getResourceIdentifier(): null | string;
|
||||
couldAffectReferencingModule(): boolean | typeof TRANSITIVE;
|
||||
|
||||
|
|
Loading…
Reference in New Issue