mirror of https://github.com/webpack/webpack.git
fallback to normal snapshotting when managed path optimization fails
This commit is contained in:
parent
98ea582bf0
commit
cae22d1888
|
@ -1993,7 +1993,6 @@ class FileSystemInfo {
|
||||||
if (managedItem) {
|
if (managedItem) {
|
||||||
managedItems.add(managedItem);
|
managedItems.add(managedItem);
|
||||||
managedSet.add(path);
|
managedSet.add(path);
|
||||||
managedFiles.add(join(this.fs, managedItem, "package.json"));
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2004,7 +2003,6 @@ class FileSystemInfo {
|
||||||
if (managedItem) {
|
if (managedItem) {
|
||||||
managedItems.add(managedItem);
|
managedItems.add(managedItem);
|
||||||
managedSet.add(path);
|
managedSet.add(path);
|
||||||
managedFiles.add(join(this.fs, managedItem, "package.json"));
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2018,8 +2016,7 @@ class FileSystemInfo {
|
||||||
}
|
}
|
||||||
return capturedItems;
|
return capturedItems;
|
||||||
};
|
};
|
||||||
if (files) {
|
const processCapturedFiles = capturedFiles => {
|
||||||
const capturedFiles = captureNonManaged(files, managedFiles);
|
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case 3:
|
case 3:
|
||||||
this._fileTshsOptimization.optimize(snapshot, capturedFiles);
|
this._fileTshsOptimization.optimize(snapshot, capturedFiles);
|
||||||
|
@ -2096,12 +2093,11 @@ class FileSystemInfo {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
if (files) {
|
||||||
|
processCapturedFiles(captureNonManaged(files, managedFiles));
|
||||||
}
|
}
|
||||||
if (directories) {
|
const processCapturedDirectories = capturedDirectories => {
|
||||||
const capturedDirectories = captureNonManaged(
|
|
||||||
directories,
|
|
||||||
managedContexts
|
|
||||||
);
|
|
||||||
switch (mode) {
|
switch (mode) {
|
||||||
case 3:
|
case 3:
|
||||||
this._contextTshsOptimization.optimize(snapshot, capturedDirectories);
|
this._contextTshsOptimization.optimize(snapshot, capturedDirectories);
|
||||||
|
@ -2221,9 +2217,13 @@ class FileSystemInfo {
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
if (directories) {
|
||||||
|
processCapturedDirectories(
|
||||||
|
captureNonManaged(directories, managedContexts)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
if (missing) {
|
const processCapturedMissing = capturedMissing => {
|
||||||
const capturedMissing = captureNonManaged(missing, managedMissing);
|
|
||||||
this._missingExistenceOptimization.optimize(snapshot, capturedMissing);
|
this._missingExistenceOptimization.optimize(snapshot, capturedMissing);
|
||||||
for (const path of capturedMissing) {
|
for (const path of capturedMissing) {
|
||||||
const cache = this._fileTimestamps.get(path);
|
const cache = this._fileTimestamps.get(path);
|
||||||
|
@ -2248,11 +2248,15 @@ class FileSystemInfo {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
if (missing) {
|
||||||
|
processCapturedMissing(captureNonManaged(missing, managedMissing));
|
||||||
}
|
}
|
||||||
this._managedItemInfoOptimization.optimize(snapshot, managedItems);
|
this._managedItemInfoOptimization.optimize(snapshot, managedItems);
|
||||||
for (const path of managedItems) {
|
for (const path of managedItems) {
|
||||||
const cache = this._managedItems.get(path);
|
const cache = this._managedItems.get(path);
|
||||||
if (cache !== undefined) {
|
if (cache !== undefined) {
|
||||||
|
managedFiles.add(join(this.fs, path, "package.json"));
|
||||||
managedItemInfo.set(path, cache);
|
managedItemInfo.set(path, cache);
|
||||||
} else {
|
} else {
|
||||||
jobs++;
|
jobs++;
|
||||||
|
@ -2264,9 +2268,24 @@ class FileSystemInfo {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
jobError();
|
jobError();
|
||||||
} else {
|
} else if (entry) {
|
||||||
|
managedFiles.add(join(this.fs, path, "package.json"));
|
||||||
managedItemInfo.set(path, entry);
|
managedItemInfo.set(path, entry);
|
||||||
jobDone();
|
jobDone();
|
||||||
|
} else {
|
||||||
|
// Fallback to normal snapshotting
|
||||||
|
const process = (set, fn) => {
|
||||||
|
if (set.size === 0) return;
|
||||||
|
const captured = new Set();
|
||||||
|
for (const file of set) {
|
||||||
|
if (file.startsWith(path)) captured.add(file);
|
||||||
|
}
|
||||||
|
if (captured.size > 0) fn(captured);
|
||||||
|
};
|
||||||
|
process(managedFiles, processCapturedFiles);
|
||||||
|
process(managedContexts, processCapturedDirectories);
|
||||||
|
process(managedMissing, processCapturedMissing);
|
||||||
|
jobDone();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -3479,9 +3498,10 @@ class FileSystemInfo {
|
||||||
this._managedItems.set(path, "nested");
|
this._managedItems.set(path, "nested");
|
||||||
return callback(null, "nested");
|
return callback(null, "nested");
|
||||||
}
|
}
|
||||||
const problem = `Managed item ${path} isn't a directory or doesn't contain a package.json`;
|
this.logger.warn(
|
||||||
this.logger.warn(problem);
|
`Managed item ${path} isn't a directory or doesn't contain a package.json (see snapshot.managedPaths option)`
|
||||||
return callback(new Error(problem));
|
);
|
||||||
|
return callback();
|
||||||
});
|
});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -3493,6 +3513,12 @@ class FileSystemInfo {
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
return callback(e);
|
return callback(e);
|
||||||
}
|
}
|
||||||
|
if (!data.name) {
|
||||||
|
this.logger.warn(
|
||||||
|
`${packageJsonPath} doesn't contain a "name" property (see snapshot.managedPaths option)`
|
||||||
|
);
|
||||||
|
return callback();
|
||||||
|
}
|
||||||
const info = `${data.name || ""}@${data.version || ""}`;
|
const info = `${data.name || ""}@${data.version || ""}`;
|
||||||
this._managedItems.set(path, info);
|
this._managedItems.set(path, info);
|
||||||
callback(null, info);
|
callback(null, info);
|
||||||
|
|
|
@ -39,10 +39,49 @@ const exec = (n, options = {}) => {
|
||||||
p.stderr.on("data", chunk => chunks.push(chunk));
|
p.stderr.on("data", chunk => chunks.push(chunk));
|
||||||
p.stdout.on("data", chunk => chunks.push(chunk));
|
p.stdout.on("data", chunk => chunks.push(chunk));
|
||||||
p.once("exit", code => {
|
p.once("exit", code => {
|
||||||
const stdout = chunks.join("");
|
const errors = [];
|
||||||
|
const warnings = [];
|
||||||
|
const rawStdout = chunks.join("");
|
||||||
|
const stdout = rawStdout.replace(
|
||||||
|
// This warning is expected
|
||||||
|
/<([ew])> \[.+\n(?:<([ew])> [^[].+\n)*/g,
|
||||||
|
(message, type) => {
|
||||||
|
(type === "e" ? errors : warnings).push(message);
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
);
|
||||||
|
if (errors.length > 0) {
|
||||||
|
return reject(
|
||||||
|
new Error(
|
||||||
|
`Unexpected errors in ${n} output:\n${errors.join(
|
||||||
|
"\n"
|
||||||
|
)}\n\n${rawStdout}`
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
for (const regexp of options.warnings || []) {
|
||||||
|
const idx = warnings.findIndex(w => regexp.test(w));
|
||||||
|
if (idx < 0) {
|
||||||
|
return reject(
|
||||||
|
new Error(
|
||||||
|
`Warning ${regexp} was not found in ${n} output:\n${rawStdout}`
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
warnings.splice(idx, 1);
|
||||||
|
}
|
||||||
|
if (warnings.length > 0) {
|
||||||
|
return reject(
|
||||||
|
new Error(
|
||||||
|
`Unexpected warnings in ${n} output:\n${warnings.join(
|
||||||
|
"\n"
|
||||||
|
)}\n\n${rawStdout}`
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
if (code === 0) {
|
if (code === 0) {
|
||||||
if (!options.ignoreErrors && /<[ew]>/.test(stdout))
|
if (!options.ignoreErrors && /<[ew]>/.test(stdout))
|
||||||
return reject(stdout);
|
return reject(new Error(stdout));
|
||||||
resolve(stdout);
|
resolve(stdout);
|
||||||
} else {
|
} else {
|
||||||
reject(new Error(`Code ${code}: ${stdout}`));
|
reject(new Error(`Code ${code}: ${stdout}`));
|
||||||
|
@ -99,7 +138,7 @@ describe("BuildDependencies", () => {
|
||||||
await exec("0", {
|
await exec("0", {
|
||||||
invalidBuildDepdencies: true,
|
invalidBuildDepdencies: true,
|
||||||
buildTwice: true,
|
buildTwice: true,
|
||||||
ignoreErrors: true
|
warnings: [/Can't resolve 'should-fail-resolving'/]
|
||||||
});
|
});
|
||||||
fs.writeFileSync(
|
fs.writeFileSync(
|
||||||
path.resolve(inputDirectory, "loader-dependency.js"),
|
path.resolve(inputDirectory, "loader-dependency.js"),
|
||||||
|
@ -113,13 +152,21 @@ describe("BuildDependencies", () => {
|
||||||
path.resolve(inputDirectory, "esm-dependency.js"),
|
path.resolve(inputDirectory, "esm-dependency.js"),
|
||||||
"module.exports = 1;"
|
"module.exports = 1;"
|
||||||
);
|
);
|
||||||
await exec("1");
|
await exec("1", {
|
||||||
|
warnings: supportsEsm && [
|
||||||
|
/Managed item .+dep-without-package\.json isn't a directory or doesn't contain a package\.json/
|
||||||
|
]
|
||||||
|
});
|
||||||
fs.writeFileSync(
|
fs.writeFileSync(
|
||||||
path.resolve(inputDirectory, "loader-dependency.js"),
|
path.resolve(inputDirectory, "loader-dependency.js"),
|
||||||
"module.exports = Date.now();"
|
"module.exports = Date.now();"
|
||||||
);
|
);
|
||||||
const now1 = Date.now();
|
const now1 = Date.now();
|
||||||
const output2 = await exec("2");
|
const output2 = await exec("2", {
|
||||||
|
warnings: supportsEsm && [
|
||||||
|
/Managed item .+dep-without-package\.json isn't a directory or doesn't contain a package\.json/
|
||||||
|
]
|
||||||
|
});
|
||||||
expect(output2).toMatch(/but build dependencies have changed/);
|
expect(output2).toMatch(/but build dependencies have changed/);
|
||||||
expect(output2).toMatch(/Captured build dependencies/);
|
expect(output2).toMatch(/Captured build dependencies/);
|
||||||
expect(output2).not.toMatch(/Assuming/);
|
expect(output2).not.toMatch(/Assuming/);
|
||||||
|
@ -137,7 +184,11 @@ describe("BuildDependencies", () => {
|
||||||
version: "2.0.0"
|
version: "2.0.0"
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
const output4 = await exec("4");
|
const output4 = await exec("4", {
|
||||||
|
warnings: supportsEsm && [
|
||||||
|
/Managed item .+dep-without-package\.json isn't a directory or doesn't contain a package\.json/
|
||||||
|
]
|
||||||
|
});
|
||||||
expect(output4).toMatch(/resolving of build dependencies is invalid/);
|
expect(output4).toMatch(/resolving of build dependencies is invalid/);
|
||||||
expect(output4).not.toMatch(/but build dependencies have changed/);
|
expect(output4).not.toMatch(/but build dependencies have changed/);
|
||||||
expect(output4).toMatch(/Captured build dependencies/);
|
expect(output4).toMatch(/Captured build dependencies/);
|
||||||
|
@ -146,7 +197,11 @@ describe("BuildDependencies", () => {
|
||||||
"module.exports = Date.now();"
|
"module.exports = Date.now();"
|
||||||
);
|
);
|
||||||
const now2 = Date.now();
|
const now2 = Date.now();
|
||||||
await exec("5");
|
await exec("5", {
|
||||||
|
warnings: supportsEsm && [
|
||||||
|
/Managed item .+dep-without-package\.json isn't a directory or doesn't contain a package\.json/
|
||||||
|
]
|
||||||
|
});
|
||||||
const now3 = Date.now();
|
const now3 = Date.now();
|
||||||
await exec("6");
|
await exec("6");
|
||||||
await exec("7", {
|
await exec("7", {
|
||||||
|
@ -160,7 +215,10 @@ describe("BuildDependencies", () => {
|
||||||
);
|
);
|
||||||
now4 = Date.now();
|
now4 = Date.now();
|
||||||
await exec("8", {
|
await exec("8", {
|
||||||
definedValue: "other"
|
definedValue: "other",
|
||||||
|
warnings: [
|
||||||
|
/Managed item .+dep-without-package\.json isn't a directory or doesn't contain a package\.json/
|
||||||
|
]
|
||||||
});
|
});
|
||||||
fs.writeFileSync(
|
fs.writeFileSync(
|
||||||
path.resolve(inputDirectory, "esm-async-dependency.mjs"),
|
path.resolve(inputDirectory, "esm-async-dependency.mjs"),
|
||||||
|
@ -169,7 +227,10 @@ describe("BuildDependencies", () => {
|
||||||
now5 = Date.now();
|
now5 = Date.now();
|
||||||
|
|
||||||
await exec("9", {
|
await exec("9", {
|
||||||
definedValue: "other"
|
definedValue: "other",
|
||||||
|
warnings: [
|
||||||
|
/Managed item .+dep-without-package\.json isn't a directory or doesn't contain a package\.json/
|
||||||
|
]
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
const results = Array.from({ length: supportsEsm ? 10 : 8 }).map((_, i) =>
|
const results = Array.from({ length: supportsEsm ? 10 : 8 }).map((_, i) =>
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
const path = require("path");
|
|
||||||
const { describeCases } = require("./ConfigTestCases.template");
|
const { describeCases } = require("./ConfigTestCases.template");
|
||||||
|
|
||||||
describeCases({
|
describeCases({
|
||||||
|
@ -8,8 +7,5 @@ describeCases({
|
||||||
buildDependencies: {
|
buildDependencies: {
|
||||||
defaultWebpack: []
|
defaultWebpack: []
|
||||||
}
|
}
|
||||||
},
|
|
||||||
snapshot: {
|
|
||||||
managedPaths: [path.resolve(__dirname, "../node_modules")]
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -98,10 +98,11 @@ const describeCases = config => {
|
||||||
...config.cache
|
...config.cache
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if (config.snapshot) {
|
if (!options.snapshot) options.snapshot = {};
|
||||||
options.snapshot = {
|
if (!options.snapshot.managedPaths) {
|
||||||
...config.snapshot
|
options.snapshot.managedPaths = [
|
||||||
};
|
path.resolve(__dirname, "../node_modules")
|
||||||
|
];
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
testConfig = {
|
testConfig = {
|
||||||
|
|
|
@ -0,0 +1,3 @@
|
||||||
|
import "./loader!package";
|
||||||
|
|
||||||
|
it("should compile and run the test in config", () => {});
|
|
@ -0,0 +1,8 @@
|
||||||
|
const path = require("path");
|
||||||
|
|
||||||
|
/** @type {import("../../../../").LoaderDefinition} */
|
||||||
|
module.exports = function (source) {
|
||||||
|
this.addDependency(path.resolve(__dirname, "node_modules/package/extra.js"));
|
||||||
|
this.addDependency(path.resolve(__dirname, "extra.js"));
|
||||||
|
return source;
|
||||||
|
};
|
0
test/configCases/cache-dependencies/managed-items-unsafe-cache/node_modules/package/extra.js
generated
vendored
Normal file
0
test/configCases/cache-dependencies/managed-items-unsafe-cache/node_modules/package/extra.js
generated
vendored
Normal file
0
test/configCases/cache-dependencies/managed-items-unsafe-cache/node_modules/package/index.js
generated
vendored
Normal file
0
test/configCases/cache-dependencies/managed-items-unsafe-cache/node_modules/package/index.js
generated
vendored
Normal file
4
test/configCases/cache-dependencies/managed-items-unsafe-cache/node_modules/package/package.json
generated
vendored
Normal file
4
test/configCases/cache-dependencies/managed-items-unsafe-cache/node_modules/package/package.json
generated
vendored
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
{
|
||||||
|
"name": "package",
|
||||||
|
"version": "1.0.0"
|
||||||
|
}
|
|
@ -0,0 +1,29 @@
|
||||||
|
const path = require("path");
|
||||||
|
|
||||||
|
/** @type {import("../../../../").Configuration} */
|
||||||
|
module.exports = {
|
||||||
|
snapshot: {
|
||||||
|
managedPaths: [path.resolve(__dirname, "node_modules")]
|
||||||
|
},
|
||||||
|
plugins: [
|
||||||
|
compiler => {
|
||||||
|
compiler.hooks.done.tap("Test", ({ compilation }) => {
|
||||||
|
const fileDeps = Array.from(compilation.fileDependencies);
|
||||||
|
expect(fileDeps).toContain(
|
||||||
|
path.resolve(__dirname, "node_modules/package/index.js")
|
||||||
|
);
|
||||||
|
expect(fileDeps).toContain(
|
||||||
|
path.resolve(__dirname, "node_modules/package/extra.js")
|
||||||
|
);
|
||||||
|
expect(fileDeps).toContain(
|
||||||
|
path.resolve(__dirname, "node_modules/package/package.json")
|
||||||
|
);
|
||||||
|
expect(fileDeps).toContain(path.resolve(__dirname, "extra.js"));
|
||||||
|
expect(fileDeps).toContain(path.resolve(__dirname, "index.js"));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
],
|
||||||
|
module: {
|
||||||
|
unsafeCache: true
|
||||||
|
}
|
||||||
|
};
|
|
@ -23,5 +23,8 @@ module.exports = {
|
||||||
expect(fileDeps).toContain(path.resolve(__dirname, "index.js"));
|
expect(fileDeps).toContain(path.resolve(__dirname, "index.js"));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
|
module: {
|
||||||
|
unsafeCache: false
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
3
test/fixtures/buildDependencies/node_modules/dep#with#hash/package.json
generated
vendored
Normal file
3
test/fixtures/buildDependencies/node_modules/dep#with#hash/package.json
generated
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
{
|
||||||
|
"name": "dep#with#hash"
|
||||||
|
}
|
|
@ -1,4 +1,5 @@
|
||||||
{
|
{
|
||||||
|
"name": "dep-with-exports",
|
||||||
"exports": {
|
"exports": {
|
||||||
".": "./main-entry.js",
|
".": "./main-entry.js",
|
||||||
"./sub": {
|
"./sub": {
|
||||||
|
|
1
test/fixtures/buildDependencies/node_modules/dependency-with-exports/package.json
generated
vendored
1
test/fixtures/buildDependencies/node_modules/dependency-with-exports/package.json
generated
vendored
|
@ -1,3 +1,4 @@
|
||||||
{
|
{
|
||||||
|
"name": "dependency-with-exports",
|
||||||
"exports": "./main.js"
|
"exports": "./main.js"
|
||||||
}
|
}
|
||||||
|
|
1
test/fixtures/buildDependencies/node_modules/dependency-with-optional/package.json
generated
vendored
1
test/fixtures/buildDependencies/node_modules/dependency-with-optional/package.json
generated
vendored
|
@ -1,4 +1,5 @@
|
||||||
{
|
{
|
||||||
|
"name": "dependency-with-optional",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"dep": "*"
|
"dep": "*"
|
||||||
},
|
},
|
||||||
|
|
3
test/fixtures/buildDependencies/node_modules/require-dependency-with-exports/package.json
generated
vendored
Normal file
3
test/fixtures/buildDependencies/node_modules/require-dependency-with-exports/package.json
generated
vendored
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
{
|
||||||
|
"name": "require-dependency-with-exports"
|
||||||
|
}
|
|
@ -55,6 +55,10 @@ function run({ default: value2, asyncDep: value3 }) {
|
||||||
level: "verbose",
|
level: "verbose",
|
||||||
debug: /PackFile/
|
debug: /PackFile/
|
||||||
},
|
},
|
||||||
|
snapshot: {
|
||||||
|
// TODO remove webpack 6
|
||||||
|
managedPaths: [/^(.+?[\\/]node_modules[\\/])/]
|
||||||
|
},
|
||||||
cache: {
|
cache: {
|
||||||
type: "filesystem",
|
type: "filesystem",
|
||||||
cacheDirectory: path.resolve(__dirname, "../../js/buildDepsCache"),
|
cacheDirectory: path.resolve(__dirname, "../../js/buildDepsCache"),
|
||||||
|
|
Loading…
Reference in New Issue