Revert "Revert "Merge pull request #15332 from webpack/fix/context-resolve-issue-11335""
This reverts commit dd53923cd0
.
This commit is contained in:
parent
dfdc8b133d
commit
93d44847bd
|
@ -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
|
||||
|
@ -92,23 +92,36 @@ 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;
|
||||
if (!options || typeof options.resource === "string") {
|
||||
const parsed = parseResource(
|
||||
options ? /** @type {string} */ (options.resource) : ""
|
||||
);
|
||||
const resource = parsed.path;
|
||||
const resourceQuery = (options && options.resourceQuery) || parsed.query;
|
||||
const resourceFragment =
|
||||
(options && options.resourceFragment) || parsed.fragment;
|
||||
|
||||
super("javascript/dynamic", resource);
|
||||
super("javascript/dynamic", resource);
|
||||
/** @type {ContextModuleOptions} */
|
||||
this.options = {
|
||||
...options,
|
||||
resource,
|
||||
resourceQuery,
|
||||
resourceFragment
|
||||
};
|
||||
} else {
|
||||
super("javascript/dynamic");
|
||||
/** @type {ContextModuleOptions} */
|
||||
this.options = {
|
||||
...options,
|
||||
resource: options.resource,
|
||||
resourceQuery: options.resourceQuery || "",
|
||||
resourceFragment: options.resourceFragment || ""
|
||||
};
|
||||
}
|
||||
|
||||
// Info from Factory
|
||||
this.resolveDependencies = resolveDependencies;
|
||||
/** @type {ContextModuleOptions} */
|
||||
this.options = {
|
||||
...options,
|
||||
resource,
|
||||
resourceQuery,
|
||||
resourceFragment
|
||||
};
|
||||
if (options && options.resolveOptions !== undefined) {
|
||||
this.resolveOptions = options.resolveOptions;
|
||||
}
|
||||
|
@ -155,7 +168,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}`;
|
||||
}
|
||||
|
@ -220,7 +237,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(" ");
|
||||
}
|
||||
if (this.options.resourceQuery) {
|
||||
identifier += ` ${this.options.resourceQuery}`;
|
||||
}
|
||||
|
@ -270,11 +296,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(" ");
|
||||
}
|
||||
|
||||
if (this.layer) identifier = `(${this.layer})/${identifier}`;
|
||||
if (this.options.mode) {
|
||||
identifier += ` ${this.options.mode}`;
|
||||
|
@ -442,7 +487,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) => {
|
||||
|
@ -466,7 +515,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);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -167,6 +167,9 @@ module.exports = class ContextModuleFactory extends ModuleFactory {
|
|||
asyncLib.parallel(
|
||||
[
|
||||
callback => {
|
||||
const results = [];
|
||||
const yield_ = obj => results.push(obj);
|
||||
|
||||
contextResolver.resolve(
|
||||
{},
|
||||
context,
|
||||
|
@ -174,11 +177,12 @@ module.exports = class ContextModuleFactory extends ModuleFactory {
|
|||
{
|
||||
fileDependencies,
|
||||
missingDependencies,
|
||||
contextDependencies
|
||||
contextDependencies,
|
||||
yield: yield_
|
||||
},
|
||||
(err, result) => {
|
||||
err => {
|
||||
if (err) return callback(err);
|
||||
callback(null, result);
|
||||
callback(null, results);
|
||||
}
|
||||
);
|
||||
},
|
||||
|
@ -213,15 +217,20 @@ 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),
|
||||
resourceQuery: contextResult[0].query,
|
||||
resourceFragment: contextResult[0].fragment,
|
||||
...beforeResolveResult
|
||||
},
|
||||
(err, result) => {
|
||||
|
@ -278,26 +287,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) => {
|
||||
(_, 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(
|
||||
|
@ -324,16 +335,15 @@ module.exports = class ContextModuleFactory extends ModuleFactory {
|
|||
|
||||
if (stat.isDirectory()) {
|
||||
if (!recursive) return callback();
|
||||
addSubDirectory(subResource, callback);
|
||||
addSubDirectory(ctx, subResource, callback);
|
||||
} else if (
|
||||
stat.isFile() &&
|
||||
(!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(
|
||||
|
@ -344,8 +354,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,
|
||||
|
@ -382,12 +395,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, 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);
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -128,6 +128,11 @@ class ResolverCachePlugin {
|
|||
fileDependencies: new LazySet(),
|
||||
contextDependencies: new LazySet()
|
||||
};
|
||||
let yieldResult;
|
||||
if (typeof newResolveContext.yield === "function") {
|
||||
yieldResult = [];
|
||||
newResolveContext.yield = obj => yieldResult.push(obj);
|
||||
}
|
||||
const propagate = key => {
|
||||
if (resolveContext[key]) {
|
||||
addAllToSet(resolveContext[key], newResolveContext[key]);
|
||||
|
@ -155,15 +160,19 @@ class ResolverCachePlugin {
|
|||
snapshotOptions,
|
||||
(err, snapshot) => {
|
||||
if (err) return callback(err);
|
||||
const resolveResult = result || yieldResult;
|
||||
if (!snapshot) {
|
||||
if (result) return callback(null, result);
|
||||
if (resolveResult) return callback(null, resolveResult);
|
||||
return callback();
|
||||
}
|
||||
itemCache.store(new CacheEntry(result, snapshot), storeErr => {
|
||||
if (storeErr) return callback(storeErr);
|
||||
if (result) return callback(null, result);
|
||||
callback();
|
||||
});
|
||||
itemCache.store(
|
||||
new CacheEntry(resolveResult, snapshot),
|
||||
storeErr => {
|
||||
if (storeErr) return callback(storeErr);
|
||||
if (resolveResult) return callback(null, resolveResult);
|
||||
callback();
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
@ -173,6 +182,8 @@ class ResolverCachePlugin {
|
|||
factory(type, hook) {
|
||||
/** @type {Map<string, (function(Error=, Object=): void)[]>} */
|
||||
const activeRequests = new Map();
|
||||
/** @type {Map<string, [function(Error=, Object=): void, function(Error=, Object=): void][]>} */
|
||||
const activeRequestsWithYield = new Map();
|
||||
hook.tap(
|
||||
"ResolverCachePlugin",
|
||||
/**
|
||||
|
@ -197,29 +208,63 @@ class ResolverCachePlugin {
|
|||
if (request._ResolverCachePluginCacheMiss || !fileSystemInfo) {
|
||||
return callback();
|
||||
}
|
||||
const identifier = `${type}${optionsIdent}${objectToString(
|
||||
request,
|
||||
!cacheWithContext
|
||||
)}`;
|
||||
const activeRequest = activeRequests.get(identifier);
|
||||
if (activeRequest) {
|
||||
activeRequest.push(callback);
|
||||
return;
|
||||
const withYield = typeof resolveContext.yield === "function";
|
||||
const identifier = `${type}${
|
||||
withYield ? "|yield" : "|default"
|
||||
}${optionsIdent}${objectToString(request, !cacheWithContext)}`;
|
||||
|
||||
if (withYield) {
|
||||
const activeRequest = activeRequestsWithYield.get(identifier);
|
||||
if (activeRequest) {
|
||||
activeRequest[0].push(callback);
|
||||
activeRequest[1].push(resolveContext.yield);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
const activeRequest = activeRequests.get(identifier);
|
||||
if (activeRequest) {
|
||||
activeRequest.push(callback);
|
||||
return;
|
||||
}
|
||||
}
|
||||
const itemCache = cache.getItemCache(identifier, null);
|
||||
let callbacks;
|
||||
const done = (err, result) => {
|
||||
if (callbacks === undefined) {
|
||||
callback(err, result);
|
||||
callbacks = false;
|
||||
} else {
|
||||
for (const callback of callbacks) {
|
||||
callback(err, result);
|
||||
}
|
||||
activeRequests.delete(identifier);
|
||||
callbacks = false;
|
||||
}
|
||||
};
|
||||
let callbacks, yields;
|
||||
const done = withYield
|
||||
? (err, result) => {
|
||||
if (callbacks === undefined) {
|
||||
if (err) {
|
||||
callback(err);
|
||||
} else {
|
||||
if (result)
|
||||
for (const r of result) resolveContext.yield(r);
|
||||
callback(null, null);
|
||||
}
|
||||
yields = undefined;
|
||||
callbacks = false;
|
||||
} else {
|
||||
for (let i = 0; i < callbacks.length; i++) {
|
||||
const cb = callbacks[i];
|
||||
const yield_ = yields[i];
|
||||
if (result) for (const r of result) yield_(r);
|
||||
cb(null, null);
|
||||
}
|
||||
activeRequestsWithYield.delete(identifier);
|
||||
yields = undefined;
|
||||
callbacks = false;
|
||||
}
|
||||
}
|
||||
: (err, result) => {
|
||||
if (callbacks === undefined) {
|
||||
callback(err, result);
|
||||
callbacks = false;
|
||||
} else {
|
||||
for (const callback of callbacks) {
|
||||
callback(err, result);
|
||||
}
|
||||
activeRequests.delete(identifier);
|
||||
callbacks = false;
|
||||
}
|
||||
};
|
||||
/**
|
||||
* @param {Error=} err error if any
|
||||
* @param {CacheEntry=} cacheEntry cache entry
|
||||
|
@ -276,7 +321,14 @@ class ResolverCachePlugin {
|
|||
}
|
||||
};
|
||||
itemCache.get(processCacheResult);
|
||||
if (callbacks === undefined) {
|
||||
if (withYield && callbacks === undefined) {
|
||||
callbacks = [callback];
|
||||
yields = [resolveContext.yield];
|
||||
activeRequestsWithYield.set(
|
||||
identifier,
|
||||
/** @type {[any, any]} */ ([callbacks, yields])
|
||||
);
|
||||
} else if (callbacks === undefined) {
|
||||
callbacks = [callback];
|
||||
activeRequests.set(identifier, callbacks);
|
||||
}
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -13,10 +13,13 @@ describe("contextModule", () => {
|
|||
contextModule = new ContextModule(() => {}, {
|
||||
type: "javascript/auto",
|
||||
request,
|
||||
resource: "a",
|
||||
mode: "lazy",
|
||||
regExp: /a|b/
|
||||
});
|
||||
expect(contextModule.identifier()).toContain("/a%7Cb/");
|
||||
expect(contextModule.identifier()).toEqual(
|
||||
expect.stringContaining("/a%7Cb/")
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -119,5 +119,42 @@ describe("ContextModuleFactory", () => {
|
|||
}
|
||||
);
|
||||
});
|
||||
|
||||
it("should resolve correctly several resources", done => {
|
||||
memfs.readdir = (dir, callback) => {
|
||||
if (dir === "/a") setTimeout(() => callback(null, ["/B"]));
|
||||
if (dir === "/b") setTimeout(() => callback(null, ["/A"]));
|
||||
if (dir === "/a/B") setTimeout(() => callback(null, ["a"]));
|
||||
if (dir === "/b/A") setTimeout(() => callback(null, ["b"]));
|
||||
};
|
||||
memfs.stat = (file, callback) => {
|
||||
const resolvedValue = {
|
||||
isDirectory: () => file !== "/a/B/a" && file !== "/b/A/b",
|
||||
isFile: () => file === "/a/B/a" || file === "/b/A/b"
|
||||
};
|
||||
setTimeout(() => callback(null, resolvedValue));
|
||||
};
|
||||
memfs.realpath = undefined;
|
||||
factory.resolveDependencies(
|
||||
memfs,
|
||||
{
|
||||
resource: ["/a", "/b"],
|
||||
resourceFragment: "#hash",
|
||||
resourceQuery: "?query",
|
||||
recursive: true,
|
||||
regExp: /.*/
|
||||
},
|
||||
(err, res) => {
|
||||
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"
|
||||
]);
|
||||
expect(res.map(r => r.userRequest)).toEqual(["./B/a", "./A/b"]);
|
||||
done();
|
||||
}
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -737,62 +737,92 @@ exports[`StatsTestCases should print correct stats for concat-and-sideeffects 1`
|
|||
`;
|
||||
|
||||
exports[`StatsTestCases should print correct stats for context-independence 1`] = `
|
||||
"asset main-9eb37fb0850a854f8074.js 10.4 KiB [emitted] [immutable] (name: main)
|
||||
sourceMap main-9eb37fb0850a854f8074.js.map 9.26 KiB [emitted] [dev] (auxiliary name: main)
|
||||
"asset main-1aad2f42f93e93c4e0b4.js 12.7 KiB [emitted] [immutable] (name: main)
|
||||
sourceMap main-1aad2f42f93e93c4e0b4.js.map 11.1 KiB [emitted] [dev] (auxiliary name: main)
|
||||
asset 695-4dd37417c69a0af66bac.js 455 bytes [emitted] [immutable]
|
||||
sourceMap 695-4dd37417c69a0af66bac.js.map 342 bytes [emitted] [dev]
|
||||
runtime modules 6.29 KiB 8 modules
|
||||
runtime modules 6.6 KiB 9 modules
|
||||
orphan modules 19 bytes [orphan] 1 module
|
||||
cacheable modules 106 bytes
|
||||
./a/index.js (in Xdir/context-independence/a) 40 bytes [built] [code generated]
|
||||
./a/chunk.js + 1 modules (in Xdir/context-independence/a) 66 bytes [built] [code generated]
|
||||
built modules 500 bytes [built]
|
||||
modules by layer 234 bytes
|
||||
./a/c/ ./a/cc/ eager ^\\\\.\\\\/.*$ namespace object 198 bytes [built] [code generated]
|
||||
./a/c/a.js 18 bytes [optional] [built] [code generated]
|
||||
./a/cc/b.js 18 bytes [optional] [built] [code generated]
|
||||
modules by layer (in Xdir/context-independence/a) 266 bytes
|
||||
./a/index.js (in Xdir/context-independence/a) 200 bytes [built] [code generated]
|
||||
./a/chunk.js + 1 modules (in Xdir/context-independence/a) 66 bytes [built] [code generated]
|
||||
webpack x.x.x compiled successfully in X ms
|
||||
|
||||
asset main-9eb37fb0850a854f8074.js 10.4 KiB [emitted] [immutable] (name: main)
|
||||
sourceMap main-9eb37fb0850a854f8074.js.map 9.26 KiB [emitted] [dev] (auxiliary name: main)
|
||||
asset main-1aad2f42f93e93c4e0b4.js 12.7 KiB [emitted] [immutable] (name: main)
|
||||
sourceMap main-1aad2f42f93e93c4e0b4.js.map 11.1 KiB [emitted] [dev] (auxiliary name: main)
|
||||
asset 695-4dd37417c69a0af66bac.js 455 bytes [emitted] [immutable]
|
||||
sourceMap 695-4dd37417c69a0af66bac.js.map 342 bytes [emitted] [dev]
|
||||
runtime modules 6.29 KiB 8 modules
|
||||
runtime modules 6.6 KiB 9 modules
|
||||
orphan modules 19 bytes [orphan] 1 module
|
||||
cacheable modules 106 bytes
|
||||
./b/index.js (in Xdir/context-independence/b) 40 bytes [built] [code generated]
|
||||
./b/chunk.js + 1 modules (in Xdir/context-independence/b) 66 bytes [built] [code generated]
|
||||
built modules 500 bytes [built]
|
||||
modules by layer 234 bytes
|
||||
./b/c/ ./b/cc/ eager ^\\\\.\\\\/.*$ namespace object 198 bytes [built] [code generated]
|
||||
./b/c/a.js 18 bytes [optional] [built] [code generated]
|
||||
./b/cc/b.js 18 bytes [optional] [built] [code generated]
|
||||
modules by layer (in Xdir/context-independence/b) 266 bytes
|
||||
./b/index.js (in Xdir/context-independence/b) 200 bytes [built] [code generated]
|
||||
./b/chunk.js + 1 modules (in Xdir/context-independence/b) 66 bytes [built] [code generated]
|
||||
webpack x.x.x compiled successfully in X ms
|
||||
|
||||
asset main-180aaac92930f4aab865.js 11.6 KiB [emitted] [immutable] (name: main)
|
||||
asset main-488feb13e36da3e337fa.js 14.9 KiB [emitted] [immutable] (name: main)
|
||||
asset 695-828eb5c7418e1b8270bb.js 1.5 KiB [emitted] [immutable]
|
||||
runtime modules 6.29 KiB 8 modules
|
||||
runtime modules 6.6 KiB 9 modules
|
||||
orphan modules 19 bytes [orphan] 1 module
|
||||
cacheable modules 106 bytes
|
||||
./a/index.js (in Xdir/context-independence/a) 40 bytes [built] [code generated]
|
||||
./a/chunk.js + 1 modules (in Xdir/context-independence/a) 66 bytes [built] [code generated]
|
||||
built modules 500 bytes [built]
|
||||
modules by layer 234 bytes
|
||||
./a/c/ ./a/cc/ eager ^\\\\.\\\\/.*$ namespace object 198 bytes [built] [code generated]
|
||||
./a/c/a.js 18 bytes [optional] [built] [code generated]
|
||||
./a/cc/b.js 18 bytes [optional] [built] [code generated]
|
||||
modules by layer (in Xdir/context-independence/a) 266 bytes
|
||||
./a/index.js (in Xdir/context-independence/a) 200 bytes [built] [code generated]
|
||||
./a/chunk.js + 1 modules (in Xdir/context-independence/a) 66 bytes [built] [code generated]
|
||||
webpack x.x.x compiled successfully in X ms
|
||||
|
||||
asset main-180aaac92930f4aab865.js 11.6 KiB [emitted] [immutable] (name: main)
|
||||
asset main-488feb13e36da3e337fa.js 14.9 KiB [emitted] [immutable] (name: main)
|
||||
asset 695-828eb5c7418e1b8270bb.js 1.5 KiB [emitted] [immutable]
|
||||
runtime modules 6.29 KiB 8 modules
|
||||
runtime modules 6.6 KiB 9 modules
|
||||
orphan modules 19 bytes [orphan] 1 module
|
||||
cacheable modules 106 bytes
|
||||
./b/index.js (in Xdir/context-independence/b) 40 bytes [built] [code generated]
|
||||
./b/chunk.js + 1 modules (in Xdir/context-independence/b) 66 bytes [built] [code generated]
|
||||
built modules 500 bytes [built]
|
||||
modules by layer 234 bytes
|
||||
./b/c/ ./b/cc/ eager ^\\\\.\\\\/.*$ namespace object 198 bytes [built] [code generated]
|
||||
./b/c/a.js 18 bytes [optional] [built] [code generated]
|
||||
./b/cc/b.js 18 bytes [optional] [built] [code generated]
|
||||
modules by layer (in Xdir/context-independence/b) 266 bytes
|
||||
./b/index.js (in Xdir/context-independence/b) 200 bytes [built] [code generated]
|
||||
./b/chunk.js + 1 modules (in Xdir/context-independence/b) 66 bytes [built] [code generated]
|
||||
webpack x.x.x compiled successfully in X ms
|
||||
|
||||
asset main-633b38bd6be14d7e5f1e.js 11.3 KiB [emitted] [immutable] (name: main)
|
||||
asset main-c96ffcbdb3eefd9ed7c6.js 13.7 KiB [emitted] [immutable] (name: main)
|
||||
asset 695-ace208366ce0ce2556ef.js 1.01 KiB [emitted] [immutable]
|
||||
runtime modules 6.29 KiB 8 modules
|
||||
runtime modules 6.6 KiB 9 modules
|
||||
orphan modules 19 bytes [orphan] 1 module
|
||||
cacheable modules 106 bytes
|
||||
./a/index.js (in Xdir/context-independence/a) 40 bytes [built] [code generated]
|
||||
./a/chunk.js + 1 modules (in Xdir/context-independence/a) 66 bytes [built] [code generated]
|
||||
built modules 500 bytes [built]
|
||||
modules by layer 234 bytes
|
||||
./a/c/ ./a/cc/ eager ^\\\\.\\\\/.*$ namespace object 198 bytes [built] [code generated]
|
||||
./a/c/a.js 18 bytes [optional] [built] [code generated]
|
||||
./a/cc/b.js 18 bytes [optional] [built] [code generated]
|
||||
modules by layer (in Xdir/context-independence/a) 266 bytes
|
||||
./a/index.js (in Xdir/context-independence/a) 200 bytes [built] [code generated]
|
||||
./a/chunk.js + 1 modules (in Xdir/context-independence/a) 66 bytes [built] [code generated]
|
||||
webpack x.x.x compiled successfully in X ms
|
||||
|
||||
asset main-633b38bd6be14d7e5f1e.js 11.3 KiB [emitted] [immutable] (name: main)
|
||||
asset main-c96ffcbdb3eefd9ed7c6.js 13.7 KiB [emitted] [immutable] (name: main)
|
||||
asset 695-ace208366ce0ce2556ef.js 1.01 KiB [emitted] [immutable]
|
||||
runtime modules 6.29 KiB 8 modules
|
||||
runtime modules 6.6 KiB 9 modules
|
||||
orphan modules 19 bytes [orphan] 1 module
|
||||
cacheable modules 106 bytes
|
||||
./b/index.js (in Xdir/context-independence/b) 40 bytes [built] [code generated]
|
||||
./b/chunk.js + 1 modules (in Xdir/context-independence/b) 66 bytes [built] [code generated]
|
||||
built modules 500 bytes [built]
|
||||
modules by layer 234 bytes
|
||||
./b/c/ ./b/cc/ eager ^\\\\.\\\\/.*$ namespace object 198 bytes [built] [code generated]
|
||||
./b/c/a.js 18 bytes [optional] [built] [code generated]
|
||||
./b/cc/b.js 18 bytes [optional] [built] [code generated]
|
||||
modules by layer (in Xdir/context-independence/b) 266 bytes
|
||||
./b/index.js (in Xdir/context-independence/b) 200 bytes [built] [code generated]
|
||||
./b/chunk.js + 1 modules (in Xdir/context-independence/b) 66 bytes [built] [code generated]
|
||||
webpack x.x.x compiled successfully in X ms"
|
||||
`;
|
||||
|
||||
|
|
|
@ -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")]
|
||||
}
|
||||
}
|
||||
};
|
|
@ -0,0 +1 @@
|
|||
export default 2;
|
|
@ -0,0 +1 @@
|
|||
export default 1;
|
|
@ -1,2 +1,4 @@
|
|||
console.log("test");
|
||||
import("./chunk");
|
||||
const module = Math.round(Math.random() * 100) % 2 === 0 ? "a" : "b";
|
||||
import(/* webpackMode: "eager" */`c/${module}`).then(({ default: d }) => console.log(d));
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
export default 2;
|
|
@ -0,0 +1 @@
|
|||
export default 1;
|
|
@ -1,2 +1,4 @@
|
|||
console.log("test");
|
||||
import("./chunk");
|
||||
const module = Math.round(Math.random() * 100) % 2 === 0 ? "a" : "b";
|
||||
import(/* webpackMode: "eager" */`c/${module}`).then(({ default: d }) => console.log(d));
|
||||
|
|
|
@ -1,8 +1,13 @@
|
|||
const path = require("path");
|
||||
|
||||
const base = {
|
||||
/**
|
||||
* @param {string} name name
|
||||
* @param {string} devtool devtool
|
||||
* @returns {import("../../../").Configuration} configuration
|
||||
*/
|
||||
const base = (name, devtool) => ({
|
||||
mode: "production",
|
||||
devtool: "source-map",
|
||||
devtool,
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
|
@ -17,115 +22,37 @@ const base = {
|
|||
},
|
||||
experiments: {
|
||||
layers: true
|
||||
},
|
||||
entry: {
|
||||
main: {
|
||||
import: "./index",
|
||||
layer: path.resolve(__dirname, name)
|
||||
}
|
||||
},
|
||||
context: path.resolve(__dirname, name),
|
||||
output: {
|
||||
path: path.resolve(
|
||||
__dirname,
|
||||
`../../js/stats/context-independence/${devtool}-${name}`
|
||||
),
|
||||
filename: "[name]-[chunkhash].js"
|
||||
},
|
||||
resolve: {
|
||||
alias: {
|
||||
c: [
|
||||
path.resolve(__dirname, name, "c"),
|
||||
path.resolve(__dirname, name, "cc")
|
||||
]
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const base2 = {
|
||||
...base,
|
||||
devtool: "eval-source-map"
|
||||
};
|
||||
|
||||
const base3 = {
|
||||
...base,
|
||||
devtool: "eval"
|
||||
};
|
||||
});
|
||||
|
||||
/** @type {import("../../../").Configuration[]} */
|
||||
module.exports = [
|
||||
{
|
||||
...base,
|
||||
entry: {
|
||||
main: {
|
||||
import: "./index",
|
||||
layer: path.resolve(__dirname, "a")
|
||||
}
|
||||
},
|
||||
context: path.resolve(__dirname, "a"),
|
||||
output: {
|
||||
path: path.resolve(__dirname, "../../js/stats/context-independence/a"),
|
||||
filename: "[name]-[chunkhash].js"
|
||||
}
|
||||
},
|
||||
{
|
||||
...base,
|
||||
entry: {
|
||||
main: {
|
||||
import: "./index",
|
||||
layer: path.resolve(__dirname, "b")
|
||||
}
|
||||
},
|
||||
context: path.resolve(__dirname, "b"),
|
||||
output: {
|
||||
path: path.resolve(__dirname, "../../js/stats/context-independence/b"),
|
||||
filename: "[name]-[chunkhash].js"
|
||||
}
|
||||
},
|
||||
{
|
||||
...base2,
|
||||
entry: {
|
||||
main: {
|
||||
import: "./index",
|
||||
layer: path.resolve(__dirname, "a")
|
||||
}
|
||||
},
|
||||
context: path.resolve(__dirname, "a"),
|
||||
output: {
|
||||
path: path.resolve(
|
||||
__dirname,
|
||||
"../../js/stats/context-independence/eval-source-map-a"
|
||||
),
|
||||
filename: "[name]-[chunkhash].js"
|
||||
}
|
||||
},
|
||||
{
|
||||
...base2,
|
||||
entry: {
|
||||
main: {
|
||||
import: "./index",
|
||||
layer: path.resolve(__dirname, "b")
|
||||
}
|
||||
},
|
||||
context: path.resolve(__dirname, "b"),
|
||||
output: {
|
||||
path: path.resolve(
|
||||
__dirname,
|
||||
"../../js/stats/context-independence/eval-source-map-b"
|
||||
),
|
||||
filename: "[name]-[chunkhash].js"
|
||||
}
|
||||
},
|
||||
{
|
||||
...base3,
|
||||
entry: {
|
||||
main: {
|
||||
import: "./index",
|
||||
layer: path.resolve(__dirname, "a")
|
||||
}
|
||||
},
|
||||
context: path.resolve(__dirname, "a"),
|
||||
output: {
|
||||
path: path.resolve(
|
||||
__dirname,
|
||||
"../../js/stats/context-independence/eval-a"
|
||||
),
|
||||
filename: "[name]-[chunkhash].js"
|
||||
}
|
||||
},
|
||||
{
|
||||
...base3,
|
||||
entry: {
|
||||
main: {
|
||||
import: "./index",
|
||||
layer: path.resolve(__dirname, "b")
|
||||
}
|
||||
},
|
||||
context: path.resolve(__dirname, "b"),
|
||||
output: {
|
||||
path: path.resolve(
|
||||
__dirname,
|
||||
"../../js/stats/context-independence/eval-b"
|
||||
),
|
||||
filename: "[name]-[chunkhash].js"
|
||||
}
|
||||
}
|
||||
base("a", "source-map"),
|
||||
base("b", "source-map"),
|
||||
base("a", "eval-source-map"),
|
||||
base("b", "eval-source-map"),
|
||||
base("a", "eval"),
|
||||
base("b", "eval")
|
||||
];
|
||||
|
|
|
@ -2526,7 +2526,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;
|
||||
|
@ -9405,6 +9405,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;
|
||||
|
@ -11851,7 +11856,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;
|
||||
|
||||
|
|
|
@ -2259,10 +2259,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"
|
||||
|
|
Loading…
Reference in New Issue