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} * @returns {void}
*/ */
_processModuleDependencies(module, callback) { _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 = []; const sortedDependencies = [];
/** @type {DependenciesBlock} */ /** @type {DependenciesBlock} */
@ -1668,6 +1668,7 @@ BREAKING CHANGE: Asset processing hooks in Compilation has been merged into a si
sortedDependencies.push({ sortedDependencies.push({
factory: factoryCacheKey2, factory: factoryCacheKey2,
dependencies: list, dependencies: list,
context: dep.getContext(),
originModule: module originModule: module
}); });
} }

View File

@ -292,7 +292,6 @@ module.exports = class ContextModuleFactory extends ModuleFactory {
} = options; } = options;
if (!regExp || !resource) return callback(null, []); if (!regExp || !resource) return callback(null, []);
let severalContexts = false;
const addDirectoryChecked = (ctx, directory, visited, callback) => { const addDirectoryChecked = (ctx, directory, visited, callback) => {
fs.realpath(directory, (err, realPath) => { fs.realpath(directory, (err, realPath) => {
if (err) return callback(err); if (err) return callback(err);
@ -359,15 +358,13 @@ module.exports = class ContextModuleFactory extends ModuleFactory {
alternatives = alternatives alternatives = alternatives
.filter(obj => regExp.test(obj.request)) .filter(obj => regExp.test(obj.request))
.map(obj => { .map(obj => {
const request = severalContexts
? join(fs, obj.context, obj.request)
: obj.request;
const dep = new ContextElementDependency( const dep = new ContextElementDependency(
request + resourceQuery + resourceFragment, `${obj.request}${resourceQuery}${resourceFragment}`,
obj.request, obj.request,
typePrefix, typePrefix,
category, category,
referencedExports referencedExports,
obj.context
); );
dep.optional = true; dep.optional = true;
return dep; return dep;
@ -414,7 +411,6 @@ module.exports = class ContextModuleFactory extends ModuleFactory {
if (typeof resource === "string") { if (typeof resource === "string") {
visitResource(resource, callback); visitResource(resource, callback);
} else { } else {
severalContexts = true;
asyncLib.map(resource, visitResource, (err, result) => { asyncLib.map(resource, visitResource, (err, result) => {
if (err) return callback(err); if (err) return callback(err);

View File

@ -182,6 +182,13 @@ class Dependency {
this._loc = undefined; this._loc = undefined;
} }
/**
* @returns {string | undefined} a request context
*/
getContext() {
return undefined;
}
/** /**
* @returns {string | null} an identifier to merge equal requests * @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 */ /** @typedef {import("../util/runtime").RuntimeSpec} RuntimeSpec */
class ContextElementDependency extends ModuleDependency { 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); super(request);
this.referencedExports = referencedExports; this.referencedExports = referencedExports;
this._typePrefix = typePrefix; this._typePrefix = typePrefix;
this._category = category; this._category = category;
this._context = context || undefined;
if (userRequest) { if (userRequest) {
this.userRequest = userRequest; this.userRequest = userRequest;
@ -33,6 +49,17 @@ class ContextElementDependency extends ModuleDependency {
return "context element"; return "context element";
} }
/**
* @returns {string | undefined} a request context
*/
getContext() {
return this._context;
}
getResourceIdentifier() {
return `context${this._context || ""}|${super.getResourceIdentifier()}`;
}
get category() { get category() {
return this._category; return this._category;
} }
@ -56,6 +83,7 @@ class ContextElementDependency extends ModuleDependency {
const { write } = context; const { write } = context;
write(this._typePrefix); write(this._typePrefix);
write(this._category); write(this._category);
write(this._context);
write(this.referencedExports); write(this.referencedExports);
super.serialize(context); super.serialize(context);
} }
@ -64,6 +92,7 @@ class ContextElementDependency extends ModuleDependency {
const { read } = context; const { read } = context;
this._typePrefix = read(); this._typePrefix = read();
this._category = read(); this._category = read();
this._context = read();
this.referencedExports = read(); this.referencedExports = read();
super.deserialize(context); super.deserialize(context);
} }

View File

@ -148,9 +148,10 @@ describe("ContextModuleFactory", () => {
expect(res).not.toStrictEqual([]); expect(res).not.toStrictEqual([]);
expect(Array.isArray(res)).toBe(true); expect(Array.isArray(res)).toBe(true);
expect(res.map(r => r.request)).toEqual([ expect(res.map(r => r.request)).toEqual([
"/a/B/a?query#hash", "./B/a?query#hash",
"/b/A/b?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"]); expect(res.map(r => r.userRequest)).toEqual(["./B/a", "./A/b"]);
done(); done();
} }

3
types.d.ts vendored
View File

@ -2462,7 +2462,7 @@ declare interface ContainerReferencePluginOptions {
shareScope?: string; shareScope?: string;
} }
declare abstract class ContextElementDependency extends ModuleDependency { declare abstract class ContextElementDependency extends ModuleDependency {
referencedExports: any; referencedExports?: string[][];
} }
declare class ContextExclusionPlugin { declare class ContextExclusionPlugin {
constructor(negativeMatcher: RegExp); constructor(negativeMatcher: RegExp);
@ -2645,6 +2645,7 @@ declare class Dependency {
endLine?: any, endLine?: any,
endColumn?: any endColumn?: any
): void; ): void;
getContext(): undefined | string;
getResourceIdentifier(): null | string; getResourceIdentifier(): null | string;
couldAffectReferencingModule(): boolean | typeof TRANSITIVE; couldAffectReferencingModule(): boolean | typeof TRANSITIVE;