Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

handle several resources in ContextModule #15332

Merged
merged 3 commits into from Feb 10, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
101 changes: 77 additions & 24 deletions lib/ContextModule.js
Expand Up @@ -61,7 +61,7 @@ const makeSerializable = require("./util/makeSerializable");

/**
* @typedef {Object} ContextModuleOptionsExtras
* @property {string} resource
* @property {string|string[]} resource
* @property {string=} resourceQuery
* @property {string=} resourceFragment
* @property {TODO} resolveOptions
Expand Down Expand Up @@ -92,23 +92,34 @@ class ContextModule extends Module {
* @param {ContextModuleOptions} options options object
*/
constructor(resolveDependencies, options) {
const parsed = parseResource(options ? options.resource : "");
const resource = parsed.path;
const resourceQuery = (options && options.resourceQuery) || parsed.query;
const resourceFragment =
(options && options.resourceFragment) || parsed.fragment;

super("javascript/dynamic", resource);
if (typeof options.resource !== "string") {
super("javascript/dynamic");
/** @type {ContextModuleOptions} */
this.options = {
...options,
resource: options.resource,
resourceQuery: options.resourceQuery || "",
resourceFragment: options.resourceFragment || ""
};
} else {
const parsed = parseResource(options.resource);
const resource = parsed.path;
const resourceQuery = (options && options.resourceQuery) || parsed.query;
const resourceFragment =
(options && options.resourceFragment) || parsed.fragment;

super("javascript/dynamic", resource);
/** @type {ContextModuleOptions} */
this.options = {
...options,
resource,
resourceQuery,
resourceFragment
};
}

// Info from Factory
this.resolveDependencies = resolveDependencies;
/** @type {ContextModuleOptions} */
this.options = {
...options,
resource,
resourceQuery,
resourceFragment
};
if (options && options.resolveOptions !== undefined) {
this.resolveOptions = options.resolveOptions;
}
Expand Down Expand Up @@ -155,7 +166,11 @@ class ContextModule extends Module {
}

_createIdentifier() {
let identifier = this.context;
let identifier =
this.context ||
(typeof this.options.resource === "string"
? this.options.resource
: this.options.resource.join("|"));
if (this.options.resourceQuery) {
identifier += `|${this.options.resourceQuery}`;
}
Expand Down Expand Up @@ -220,7 +235,16 @@ class ContextModule extends Module {
* @returns {string} a user readable identifier of the module
*/
readableIdentifier(requestShortener) {
let identifier = requestShortener.shorten(this.context) + "/";
let identifier;
if (this.context) {
identifier = requestShortener.shorten(this.context) + "/";
} else if (typeof this.options.resource === "string") {
identifier = requestShortener.shorten(this.options.resource) + "/";
} else {
identifier =
this.options.resource.map(r => requestShortener.shorten(r)).join("/") +
"/";
vankop marked this conversation as resolved.
Show resolved Hide resolved
}
if (this.options.resourceQuery) {
identifier += ` ${this.options.resourceQuery}`;
}
Expand Down Expand Up @@ -270,11 +294,30 @@ class ContextModule extends Module {
* @returns {string | null} an identifier for library inclusion
*/
libIdent(options) {
let identifier = contextify(
options.context,
this.context,
options.associatedObjectForCache
);
let identifier;

if (this.context) {
identifier = contextify(
options.context,
this.context,
options.associatedObjectForCache
);
} else if (typeof this.options.resource === "string") {
identifier = contextify(
options.context,
this.options.resource,
options.associatedObjectForCache
);
} else {
const arr = [];
for (const res of this.options.resource) {
arr.push(
contextify(options.context, res, options.associatedObjectForCache)
);
}
identifier = arr.join("|");
vankop marked this conversation as resolved.
Show resolved Hide resolved
}

if (this.layer) identifier = `(${this.layer})/${identifier}`;
if (this.options.mode) {
identifier += ` ${this.options.mode}`;
Expand Down Expand Up @@ -442,7 +485,11 @@ class ContextModule extends Module {
compilation.fileSystemInfo.createSnapshot(
startTime,
null,
[this.context],
this.context
? [this.context]
: typeof this.options.resource === "string"
? [this.options.resource]
: this.options.resource,
null,
SNAPSHOT_OPTIONS,
(err, snapshot) => {
Expand All @@ -466,7 +513,13 @@ class ContextModule extends Module {
missingDependencies,
buildDependencies
) {
contextDependencies.add(this.context);
if (this.context) {
contextDependencies.add(this.context);
} else if (typeof this.options.resource === "string") {
contextDependencies.add(this.options.resource);
} else {
for (const res of this.options.resource) contextDependencies.add(res);
}
}

/**
Expand Down
75 changes: 56 additions & 19 deletions lib/ContextModuleFactory.js
Expand Up @@ -167,18 +167,22 @@ module.exports = class ContextModuleFactory extends ModuleFactory {
asyncLib.parallel(
[
callback => {
const results = [];
const yield_ = obj => results.push(obj);

contextResolver.resolve(
{},
context,
resource,
{
fileDependencies,
missingDependencies,
contextDependencies
contextDependencies,
yield: yield_
},
(err, result) => {
err => {
if (err) return callback(err);
callback(null, result);
callback(null, results);
}
);
},
Expand Down Expand Up @@ -213,14 +217,17 @@ module.exports = class ContextModuleFactory extends ModuleFactory {
contextDependencies
});
}

const [contextResult, loaderResult] = result;
this.hooks.afterResolve.callAsync(
{
addon:
loadersPrefix +
result[1].join("!") +
(result[1].length > 0 ? "!" : ""),
resource: result[0],
loaderResult.join("!") +
(loaderResult.length > 0 ? "!" : ""),
resource:
contextResult.length > 1
? contextResult.map(r => r.path)
: contextResult[0].path,
resolveDependencies: this.resolveDependencies.bind(this),
...beforeResolveResult
},
Expand Down Expand Up @@ -278,26 +285,28 @@ module.exports = class ContextModuleFactory extends ModuleFactory {
} = options;
if (!regExp || !resource) return callback(null, []);

const addDirectoryChecked = (directory, visited, callback) => {
let severalContexts = false;
const addDirectoryChecked = (ctx, directory, visited, callback) => {
fs.realpath(directory, (err, realPath) => {
if (err) return callback(err);
if (visited.has(realPath)) return callback(null, []);
let recursionStack;
addDirectory(
ctx,
directory,
(dir, callback) => {
if (recursionStack === undefined) {
recursionStack = new Set(visited);
recursionStack.add(realPath);
}
addDirectoryChecked(dir, recursionStack, callback);
addDirectoryChecked(ctx, dir, recursionStack, callback);
},
callback
);
});
};

const addDirectory = (directory, addSubDirectory, callback) => {
const addDirectory = (ctx, directory, addSubDirectory, callback) => {
fs.readdir(directory, (err, files) => {
if (err) return callback(err);
const processedFiles = cmf.hooks.contextModuleFiles.call(
Expand Down Expand Up @@ -330,10 +339,9 @@ module.exports = class ContextModuleFactory extends ModuleFactory {
(!include || subResource.match(include))
) {
const obj = {
context: resource,
context: ctx,
request:
"." +
subResource.substr(resource.length).replace(/\\/g, "/")
"." + subResource.substr(ctx.length).replace(/\\/g, "/")
};

this.hooks.alternativeRequests.callAsync(
Expand All @@ -344,8 +352,11 @@ 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(
obj.request + resourceQuery + resourceFragment,
request + resourceQuery + resourceFragment,
obj.request,
typePrefix,
category,
Expand Down Expand Up @@ -382,12 +393,38 @@ module.exports = class ContextModuleFactory extends ModuleFactory {
});
};

if (typeof fs.realpath === "function") {
addDirectoryChecked(resource, new Set(), callback);
const addSubDirectory = (ctx, dir, callback) =>
addDirectory(ctx, dir, addSubDirectory, callback);

const visitResource = (resource, callback) => {
if (typeof fs.realpath === "function") {
addDirectoryChecked(resource, new Set(), callback);
} else {
addDirectory(resource, resource, addSubDirectory, callback);
}
};

if (typeof resource === "string") {
visitResource(resource, callback);
} else {
const addSubDirectory = (dir, callback) =>
addDirectory(dir, addSubDirectory, callback);
addDirectory(resource, addSubDirectory, callback);
severalContexts = true;
asyncLib.map(resource, visitResource, (err, result) => {
if (err) return callback(err);

// result dependencies should have unique userRequest
// ordered by resolve result
const temp = new Set();
const res = [];
for (let i = 0; i < result.length; i++) {
const inner = result[i];
for (const el of inner) {
if (temp.has(el.userRequest)) continue;
res.push(el);
temp.add(el.userRequest);
}
}
callback(null, res);
});
}
}
};
2 changes: 1 addition & 1 deletion package.json
Expand Up @@ -14,7 +14,7 @@
"acorn-import-assertions": "^1.7.6",
"browserslist": "^4.14.5",
"chrome-trace-event": "^1.0.2",
"enhanced-resolve": "^5.8.3",
"enhanced-resolve": "^5.9.0",
"es-module-lexer": "^0.9.0",
"eslint-scope": "5.1.1",
"events": "^3.2.0",
Expand Down
18 changes: 18 additions & 0 deletions test/configCases/resolve/issue-11335-context-module/index.js
@@ -0,0 +1,18 @@
import a from "app/widgets/a";
import b from "app/widgets/b";
import c from "app/widgets/c";


it("static imports order", () => {
expect(a).toBe("main/widgets/a");
expect(b).toBe("main/widgets/b");
expect(c).toBe("foo/widgets/c");
});

const load = id => import(/* webpackMode: "eager" */ `app/widgets/${id}?query#hash`);

it("dynamic imports order", async () => {
expect((await load("a")).default).toBe("main/widgets/a");
expect((await load("b")).default).toBe("main/widgets/b");
expect((await load("c")).default).toBe("foo/widgets/c");
});
@@ -0,0 +1 @@
export default "foo/widgets/b";
@@ -0,0 +1 @@
export default "foo/widgets/c";
@@ -0,0 +1 @@
export default "main/widgets/a";
@@ -0,0 +1 @@
export default "main/widgets/b";
@@ -0,0 +1,10 @@
const path = require("path");

/** @type {import("../../../../").Configuration} */
module.exports = {
resolve: {
alias: {
app: [path.join(__dirname, "src/main"), path.join(__dirname, "src/foo")]
}
}
};
9 changes: 7 additions & 2 deletions types.d.ts
Expand Up @@ -2519,7 +2519,7 @@ declare interface ContextModuleOptions {
* exports referenced from modules (won't be mangled)
*/
referencedExports?: string[][];
resource: string;
resource: string | string[];
resourceQuery?: string;
resourceFragment?: string;
resolveOptions: any;
Expand Down Expand Up @@ -9389,6 +9389,11 @@ declare interface ResolveContext {
* log function
*/
log?: (arg0: string) => void;

/**
* yield result, if provided plugins can return several results
*/
yield?: (arg0: ResolveRequest) => void;
}
declare interface ResolveData {
contextInfo: ModuleFactoryCreateDataContextInfo;
Expand Down Expand Up @@ -11835,7 +11840,7 @@ declare interface UserResolveOptions {
restrictions?: (string | RegExp)[];

/**
* Use only the sync constiants of the file system calls
* Use only the sync constraints of the file system calls
*/
useSyncFileSystemCalls?: boolean;

Expand Down
8 changes: 4 additions & 4 deletions yarn.lock
Expand Up @@ -2256,10 +2256,10 @@ enhanced-resolve@^4.0.0:
memory-fs "^0.5.0"
tapable "^1.0.0"

enhanced-resolve@^5.8.3:
version "5.8.3"
resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.8.3.tgz#6d552d465cce0423f5b3d718511ea53826a7b2f0"
integrity sha512-EGAbGvH7j7Xt2nc0E7D99La1OiEs8LnyimkRgwExpUMScN6O+3x9tIWs7PLQZVNx4YD+00skHXPXi1yQHpAmZA==
enhanced-resolve@^5.9.0:
version "5.9.0"
resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-5.9.0.tgz#49ac24953ac8452ed8fed2ef1340fc8e043667ee"
integrity sha512-weDYmzbBygL7HzGGS26M3hGQx68vehdEg6VUmqSOaFzXExFqlnKuSvsEJCVGQHScS8CQMbrAqftT+AzzHNt/YA==
dependencies:
graceful-fs "^4.2.4"
tapable "^2.2.0"
Expand Down