support context in Dependency

This commit is contained in:
Ivan Kopeykin 2022-03-25 16:28:18 +03:00
parent 86a8bd9618
commit cf5fc90082
6 changed files with 47 additions and 12 deletions

View File

@ -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
});
}

View File

@ -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);

View File

@ -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
*/

View File

@ -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,17 @@ class ContextElementDependency extends ModuleDependency {
return "context element";
}
/**
* @returns {string | undefined} a request context
*/
getContext() {
return this._context;
}
getResourceIdentifier() {
return `context${this._context || ""}|${super.getResourceIdentifier()}`;
}
get category() {
return this._category;
}
@ -56,6 +83,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 +92,7 @@ class ContextElementDependency extends ModuleDependency {
const { read } = context;
this._typePrefix = read();
this._category = read();
this._context = read();
this.referencedExports = read();
super.deserialize(context);
}

View File

@ -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();
}

3
types.d.ts vendored
View File

@ -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;