add "snapshot" configuration to allow to configure how snapshots are created

expose snapshot options for module, resolve, buildDependencies and resolveBuildDependencies
move managedPaths and immutablePaths from config.cache to config.snapshot
add timestamp + hash snapshotting mode
use timestamp + hash mode by default in production and for buildDependencies
This commit is contained in:
Tobias Koppers 2020-08-26 00:36:16 +02:00
parent 86ca074290
commit d6e637f33c
22 changed files with 1117 additions and 346 deletions

View File

@ -679,6 +679,10 @@ export interface WebpackOptions {
* Options for the resolver when resolving loaders.
*/
resolveLoader?: ResolveLoader;
/**
* Options affecting how file system snapshots are created and validated.
*/
snapshot?: SnapshotOptions;
/**
* Stats options object or preset name.
*/
@ -700,14 +704,6 @@ export interface WebpackOptions {
* Options object for in-memory caching.
*/
export interface MemoryCacheOptions {
/**
* List of paths that are managed by a package manager and contain a version or hash in its path so all files are immutable.
*/
immutablePaths?: string[];
/**
* List of paths that are managed by a package manager and can be trusted to not be modified otherwise.
*/
managedPaths?: string[];
/**
* In memory caching.
*/
@ -1751,6 +1747,71 @@ export interface PerformanceOptions {
*/
maxEntrypointSize?: number;
}
/**
* Options affecting how file system snapshots are created and validated.
*/
export interface SnapshotOptions {
/**
* Options for snapshotting build dependencies to determine if the whole cache need to be invalidated.
*/
buildDependencies?: {
/**
* Use hashes of the content of the files/directories to determine invalidation.
*/
hash?: boolean;
/**
* Use timestamps of the files/directories to determine invalidation.
*/
timestamp?: boolean;
};
/**
* List of paths that are managed by a package manager and contain a version or hash in its path so all files are immutable.
*/
immutablePaths?: string[];
/**
* List of paths that are managed by a package manager and can be trusted to not be modified otherwise.
*/
managedPaths?: string[];
/**
* Options for snapshotting dependencies of modules to determine if they need to be built again.
*/
module?: {
/**
* Use hashes of the content of the files/directories to determine invalidation.
*/
hash?: boolean;
/**
* Use timestamps of the files/directories to determine invalidation.
*/
timestamp?: boolean;
};
/**
* Options for snapshotting dependencies of request resolving to determine if requests need to be re-resolved.
*/
resolve?: {
/**
* Use hashes of the content of the files/directories to determine invalidation.
*/
hash?: boolean;
/**
* Use timestamps of the files/directories to determine invalidation.
*/
timestamp?: boolean;
};
/**
* Options for snapshotting the resolving of build dependencies to determine if the build dependencies need to be re-resolved.
*/
resolveBuildDependencies?: {
/**
* Use hashes of the content of the files/directories to determine invalidation.
*/
hash?: boolean;
/**
* Use timestamps of the files/directories to determine invalidation.
*/
timestamp?: boolean;
};
}
/**
* Stats options object.
*/
@ -2303,6 +2364,10 @@ export interface WebpackOptionsNormalized {
* Options for the resolver when resolving loaders.
*/
resolveLoader: ResolveLoader;
/**
* Options affecting how file system snapshots are created and validated.
*/
snapshot: SnapshotOptions;
/**
* Stats options object or preset name.
*/

View File

@ -81,6 +81,8 @@ const makeSerializable = require("./util/makeSerializable");
* @param {ResolveDependenciesCallback} callback
*/
const SNAPSHOT_OPTIONS = { timestamp: true };
const TYPES = new Set(["javascript"]);
class ContextModule extends Module {
@ -428,7 +430,7 @@ class ContextModule extends Module {
null,
[this.context],
null,
{},
SNAPSHOT_OPTIONS,
(err, snapshot) => {
if (err) return callback(err);
this.buildInfo.snapshot = snapshot;

File diff suppressed because it is too large Load Diff

View File

@ -804,7 +804,8 @@ class NormalModule extends Module {
};
const handleBuildDone = () => {
if (!this.buildInfo.cacheable) {
const snapshotOptions = compilation.options.snapshot.module;
if (!this.buildInfo.cacheable || !snapshotOptions) {
return callback();
}
// convert file/context/missingDependencies into filesystem snapshot
@ -813,7 +814,7 @@ class NormalModule extends Module {
this.buildInfo.fileDependencies,
this.buildInfo.contextDependencies,
this.buildInfo.missingDependencies,
null,
snapshotOptions,
(err, snapshot) => {
if (err) {
this.markModuleAsErrored(err);

View File

@ -490,13 +490,14 @@ class WebpackOptionsApply extends OptionsApply {
new WarnCaseSensitiveModulesPlugin().apply(compiler);
const AddManagedPathsPlugin = require("./cache/AddManagedPathsPlugin");
new AddManagedPathsPlugin(
options.snapshot.managedPaths,
options.snapshot.immutablePaths
).apply(compiler);
if (options.cache && typeof options.cache === "object") {
const cacheOptions = options.cache;
const AddManagedPathsPlugin = require("./cache/AddManagedPathsPlugin");
new AddManagedPathsPlugin(
cacheOptions.managedPaths,
cacheOptions.immutablePaths
).apply(compiler);
switch (cacheOptions.type) {
case "memory": {
const MemoryCachePlugin = require("./cache/MemoryCachePlugin");
@ -525,8 +526,7 @@ class WebpackOptionsApply extends OptionsApply {
logger: compiler.getInfrastructureLogger(
"webpack.cache.PackFileCacheStrategy"
),
managedPaths: cacheOptions.managedPaths,
immutablePaths: cacheOptions.immutablePaths
snapshot: options.snapshot
}),
cacheOptions.idleTimeout,
cacheOptions.idleTimeoutForInitialStore

View File

@ -13,6 +13,7 @@ const makeSerializable = require("../util/makeSerializable");
const memorize = require("../util/memorize");
const { createFileSerializer } = require("../util/serialization");
/** @typedef {import("../../declarations/WebpackOptions").SnapshotOptions} SnapshotOptions */
/** @typedef {import("../Cache").Etag} Etag */
/** @typedef {import("../Compiler")} Compiler */
/** @typedef {import("../FileSystemInfo").Snapshot} Snapshot */
@ -721,8 +722,7 @@ class PackFileCacheStrategy {
* @param {string} options.cacheLocation the location of the cache data
* @param {string} options.version version identifier
* @param {Logger} options.logger a logger
* @param {Iterable<string>} options.managedPaths paths managed only by package manager
* @param {Iterable<string>} options.immutablePaths immutable paths
* @param {SnapshotOptions} options.snapshot options regarding snapshotting
*/
constructor({
compiler,
@ -731,13 +731,12 @@ class PackFileCacheStrategy {
cacheLocation,
version,
logger,
managedPaths,
immutablePaths
snapshot
}) {
this.fileSerializer = createFileSerializer(fs);
this.fileSystemInfo = new FileSystemInfo(fs, {
managedPaths,
immutablePaths,
managedPaths: snapshot.managedPaths,
immutablePaths: snapshot.immutablePaths,
logger: logger.getChildLogger("webpack.FileSystemInfo")
});
this.compiler = compiler;
@ -745,6 +744,7 @@ class PackFileCacheStrategy {
this.cacheLocation = cacheLocation;
this.version = version;
this.logger = logger;
this.snapshot = snapshot;
/** @type {Set<string>} */
this.buildDependencies = new Set();
/** @type {LazySet<string>} */
@ -996,17 +996,19 @@ class PackFileCacheStrategy {
} else {
this.resolveResults = resolveResults;
}
if (reportProgress)
if (reportProgress) {
reportProgress(
0.6,
"snapshot build dependencies (timestamps)"
"snapshot build dependencies",
"resolving"
);
}
this.fileSystemInfo.createSnapshot(
undefined,
resolveDependencies.files,
resolveDependencies.directories,
resolveDependencies.missing,
{},
this.snapshot.resolveBuildDependencies,
(err, snapshot) => {
if (err) {
this.logger.timeEnd("snapshot build dependencies");
@ -1026,17 +1028,19 @@ class PackFileCacheStrategy {
} else {
this.resolveBuildDependenciesSnapshot = snapshot;
}
if (reportProgress)
if (reportProgress) {
reportProgress(
0.7,
"snapshot build dependencies (hashes)"
"snapshot build dependencies",
"modules"
);
}
this.fileSystemInfo.createSnapshot(
undefined,
files,
directories,
missing,
{ hash: true },
this.snapshot.buildDependencies,
(err, snapshot) => {
this.logger.timeEnd("snapshot build dependencies");
if (err) return reject(err);

View File

@ -79,11 +79,13 @@ class ResolverCachePlugin {
const cache = compiler.getCache("ResolverCachePlugin");
/** @type {FileSystemInfo} */
let fileSystemInfo;
let snapshotOptions;
let realResolves = 0;
let cachedResolves = 0;
let cacheInvalidResolves = 0;
let concurrentResolves = 0;
compiler.hooks.thisCompilation.tap("ResolverCachePlugin", compilation => {
snapshotOptions = compilation.options.snapshot.resolve;
fileSystemInfo = compilation.fileSystemInfo;
compilation.hooks.finishModules.tap("ResolverCachePlugin", () => {
if (realResolves + cachedResolves > 0) {
@ -151,7 +153,7 @@ class ResolverCachePlugin {
fileDependencies,
contextDependencies,
missingDependencies,
{ timestamp: true },
snapshotOptions,
(err, snapshot) => {
if (err) return callback(err);
if (!snapshot) {

View File

@ -23,6 +23,7 @@ const { cleverMerge } = require("../util/cleverMerge");
/** @typedef {import("../../declarations/WebpackOptions").Performance} Performance */
/** @typedef {import("../../declarations/WebpackOptions").ResolveOptions} ResolveOptions */
/** @typedef {import("../../declarations/WebpackOptions").RuleSetRules} RuleSetRules */
/** @typedef {import("../../declarations/WebpackOptions").SnapshotOptions} SnapshotOptions */
/** @typedef {import("../../declarations/WebpackOptions").Target} Target */
/** @typedef {import("../../declarations/WebpackOptions").WebpackOptionsNormalized} WebpackOptions */
@ -148,6 +149,8 @@ const applyWebpackOptionsDefaults = options => {
});
const cache = !!options.cache;
applySnapshotDefaults(options.snapshot, { production });
applyExperimentsDefaults(options.experiments);
applyModuleDefaults(options.module, {
@ -267,7 +270,16 @@ const applyCacheDefaults = (cache, { name, mode }) => {
]);
break;
}
A(cache, "managedPaths", () => {
};
/**
* @param {SnapshotOptions} snapshot options
* @param {Object} options options
* @param {boolean} options.production is production
* @returns {void}
*/
const applySnapshotDefaults = (snapshot, { production }) => {
A(snapshot, "managedPaths", () => {
if (process.versions.pnp === "3") {
const match = /^(.+?)[\\/]cache[\\/]watchpack-npm-[^\\/]+\.zip[\\/]node_modules[\\/]/.exec(
require.resolve("watchpack")
@ -286,7 +298,7 @@ const applyCacheDefaults = (cache, { name, mode }) => {
}
return [];
});
A(cache, "immutablePaths", () => {
A(snapshot, "immutablePaths", () => {
if (process.versions.pnp === "1") {
const match = /^(.+?[\\/]v4)[\\/]npm-watchpack-[^\\/]+-[\da-f]{40}[\\/]node_modules[\\/]/.exec(
require.resolve("watchpack")
@ -304,6 +316,17 @@ const applyCacheDefaults = (cache, { name, mode }) => {
}
return [];
});
F(snapshot, "resolveBuildDependencies", () => ({
timestamp: true,
hash: true
}));
F(snapshot, "buildDependencies", () => ({ timestamp: true, hash: true }));
F(snapshot, "module", () =>
production ? { timestamp: true, hash: true } : { timestamp: true }
);
F(snapshot, "resolve", () =>
production ? { timestamp: true, hash: true } : { timestamp: true }
);
};
/**

View File

@ -115,10 +115,6 @@ const getNormalizedWebpackOptions = config => {
hashAlgorithm: cache.hashAlgorithm,
idleTimeout: cache.idleTimeout,
idleTimeoutForInitialStore: cache.idleTimeoutForInitialStore,
immutablePaths: optionalNestedArray(cache.immutablePaths, p => [
...p
]),
managedPaths: optionalNestedArray(cache.managedPaths, p => [...p]),
name: cache.name,
store: cache.store,
version: cache.version
@ -126,11 +122,7 @@ const getNormalizedWebpackOptions = config => {
case undefined:
case "memory":
return {
type: "memory",
immutablePaths: optionalNestedArray(cache.immutablePaths, p => [
...p
]),
managedPaths: optionalNestedArray(cache.managedPaths, p => [...p])
type: "memory"
};
default:
// @ts-expect-error Property 'type' does not exist on type 'never'. ts(2339)
@ -307,6 +299,32 @@ const getNormalizedWebpackOptions = config => {
resolveLoader: nestedConfig(config.resolveLoader, resolve => ({
...resolve
})),
snapshot: nestedConfig(config.snapshot, snapshot => ({
resolveBuildDependencies: optionalNestedConfig(
snapshot.resolveBuildDependencies,
resolveBuildDependencies => ({
timestamp: resolveBuildDependencies.timestamp,
hash: resolveBuildDependencies.hash
})
),
buildDependencies: optionalNestedConfig(
snapshot.buildDependencies,
buildDependencies => ({
timestamp: buildDependencies.timestamp,
hash: buildDependencies.hash
})
),
resolve: optionalNestedConfig(snapshot.resolve, resolve => ({
timestamp: resolve.timestamp,
hash: resolve.hash
})),
module: optionalNestedConfig(snapshot.module, module => ({
timestamp: module.timestamp,
hash: module.hash
})),
immutablePaths: optionalNestedArray(snapshot.immutablePaths, p => [...p]),
managedPaths: optionalNestedArray(snapshot.managedPaths, p => [...p])
})),
stats: nestedConfig(config.stats, stats => {
if (stats === false) {
return {

View File

@ -23,6 +23,8 @@ const DID_YOU_MEAN = {
pathinfo: "output.pathinfo",
pathInfo: "output.pathinfo",
splitChunks: "optimization.splitChunks",
immutablePaths: "snapshot.immutablePaths",
managedPaths: "snapshot.managedPaths",
hashedModuleIds:
'optimization.moduleIds: "hashed" (BREAKING CHANGE since webpack 5)',
namedChunks:

View File

@ -854,26 +854,6 @@
"type": "object",
"additionalProperties": false,
"properties": {
"immutablePaths": {
"description": "List of paths that are managed by a package manager and contain a version or hash in its path so all files are immutable.",
"type": "array",
"items": {
"description": "A path to a immutable directory (usually a package manager cache directory).",
"type": "string",
"absolutePath": true,
"minLength": 1
}
},
"managedPaths": {
"description": "List of paths that are managed by a package manager and can be trusted to not be modified otherwise.",
"type": "array",
"items": {
"description": "A path to a managed directory (usually a node_modules directory).",
"type": "string",
"absolutePath": true,
"minLength": 1
}
},
"type": {
"description": "In memory caching.",
"enum": ["memory"]
@ -2802,6 +2782,93 @@
"description": "This option enables loading async chunks via a custom script type, such as script type=\"module\".",
"enum": [false, "text/javascript", "module"]
},
"SnapshotOptions": {
"description": "Options affecting how file system snapshots are created and validated.",
"type": "object",
"additionalProperties": false,
"properties": {
"buildDependencies": {
"description": "Options for snapshotting build dependencies to determine if the whole cache need to be invalidated.",
"type": "object",
"additionalProperties": false,
"properties": {
"hash": {
"description": "Use hashes of the content of the files/directories to determine invalidation.",
"type": "boolean"
},
"timestamp": {
"description": "Use timestamps of the files/directories to determine invalidation.",
"type": "boolean"
}
}
},
"immutablePaths": {
"description": "List of paths that are managed by a package manager and contain a version or hash in its path so all files are immutable.",
"type": "array",
"items": {
"description": "A path to a immutable directory (usually a package manager cache directory).",
"type": "string",
"absolutePath": true,
"minLength": 1
}
},
"managedPaths": {
"description": "List of paths that are managed by a package manager and can be trusted to not be modified otherwise.",
"type": "array",
"items": {
"description": "A path to a managed directory (usually a node_modules directory).",
"type": "string",
"absolutePath": true,
"minLength": 1
}
},
"module": {
"description": "Options for snapshotting dependencies of modules to determine if they need to be built again.",
"type": "object",
"additionalProperties": false,
"properties": {
"hash": {
"description": "Use hashes of the content of the files/directories to determine invalidation.",
"type": "boolean"
},
"timestamp": {
"description": "Use timestamps of the files/directories to determine invalidation.",
"type": "boolean"
}
}
},
"resolve": {
"description": "Options for snapshotting dependencies of request resolving to determine if requests need to be re-resolved.",
"type": "object",
"additionalProperties": false,
"properties": {
"hash": {
"description": "Use hashes of the content of the files/directories to determine invalidation.",
"type": "boolean"
},
"timestamp": {
"description": "Use timestamps of the files/directories to determine invalidation.",
"type": "boolean"
}
}
},
"resolveBuildDependencies": {
"description": "Options for snapshotting the resolving of build dependencies to determine if the build dependencies need to be re-resolved.",
"type": "object",
"additionalProperties": false,
"properties": {
"hash": {
"description": "Use hashes of the content of the files/directories to determine invalidation.",
"type": "boolean"
},
"timestamp": {
"description": "Use timestamps of the files/directories to determine invalidation.",
"type": "boolean"
}
}
}
}
},
"SourceMapFilename": {
"description": "The filename of the SourceMaps for the JavaScript files. They are inside the `output.path` directory.",
"type": "string",
@ -3308,6 +3375,9 @@
"resolveLoader": {
"$ref": "#/definitions/ResolveLoader"
},
"snapshot": {
"$ref": "#/definitions/SnapshotOptions"
},
"stats": {
"$ref": "#/definitions/StatsValue"
},
@ -3323,6 +3393,7 @@
},
"required": [
"cache",
"snapshot",
"entry",
"experiments",
"externals",
@ -3445,6 +3516,9 @@
"resolveLoader": {
"$ref": "#/definitions/ResolveLoader"
},
"snapshot": {
"$ref": "#/definitions/SnapshotOptions"
},
"stats": {
"$ref": "#/definitions/StatsValue"
},

View File

@ -4,7 +4,9 @@ const { describeCases } = require("./ConfigTestCases.template");
describeCases({
name: "ConfigCacheTestCases",
cache: {
type: "filesystem",
type: "filesystem"
},
snapshot: {
managedPaths: [path.resolve(__dirname, "../node_modules")]
}
});

View File

@ -72,6 +72,11 @@ const describeCases = config => {
...config.cache
};
}
if (config.snapshot) {
options.snapshot = {
...config.snapshot
};
}
});
testConfig = {
findBundle: function (i, options) {

View File

@ -444,6 +444,26 @@ describe("Defaults", () => {
"index",
],
},
"snapshot": Object {
"buildDependencies": Object {
"hash": true,
"timestamp": true,
},
"immutablePaths": Array [],
"managedPaths": Array [
"<cwd>/node_modules",
],
"module": Object {
"timestamp": true,
},
"resolve": Object {
"timestamp": true,
},
"resolveBuildDependencies": Object {
"hash": true,
"timestamp": true,
},
},
"stats": Object {},
"target": "web",
"watch": false,
@ -527,6 +547,10 @@ describe("Defaults", () => {
+ "maxAssetSize": 250000,
+ "maxEntrypointSize": 250000,
+ },
@@ ... @@
+ "hash": true,
@@ ... @@
+ "hash": true,
`)
);
test("production", { mode: "production" }, e =>
@ -585,6 +609,10 @@ describe("Defaults", () => {
+ "maxAssetSize": 250000,
+ "maxEntrypointSize": 250000,
+ },
@@ ... @@
+ "hash": true,
@@ ... @@
+ "hash": true,
`)
);
test("development", { mode: "development" }, e =>
@ -595,10 +623,6 @@ describe("Defaults", () => {
@@ ... @@
- "cache": false,
+ "cache": Object {
+ "immutablePaths": Array [],
+ "managedPaths": Array [
+ "<cwd>/node_modules",
+ ],
+ "type": "memory",
+ },
@@ ... @@
@ -1271,10 +1295,6 @@ describe("Defaults", () => {
@@ ... @@
- "cache": false,
+ "cache": Object {
+ "immutablePaths": Array [],
+ "managedPaths": Array [
+ "<cwd>/node_modules",
+ ],
+ "type": "memory",
+ },
@@ ... @@
@ -1306,10 +1326,6 @@ describe("Defaults", () => {
+ "hashAlgorithm": "md4",
+ "idleTimeout": 60000,
+ "idleTimeoutForInitialStore": 0,
+ "immutablePaths": Array [],
+ "managedPaths": Array [
+ "<cwd>/node_modules",
+ ],
+ "name": "default-none",
+ "store": "pack",
+ "type": "filesystem",

View File

@ -5,7 +5,9 @@ describe("TestCases", () => {
describeCases({
name: "cache pack",
cache: {
type: "filesystem",
type: "filesystem"
},
snapshot: {
managedPaths: [path.resolve(__dirname, "../node_modules")]
},
optimization: {

View File

@ -24,7 +24,7 @@ describe("Validation", () => {
expect(msg).toMatchInlineSnapshot(`
"Invalid configuration object. Webpack has been initialized using a configuration object that does not match the API schema.
- configuration should be an object:
object { amd?, bail?, cache?, context?, dependencies?, devServer?, devtool?, entry?, experiments?, externals?, externalsType?, infrastructureLogging?, loader?, mode?, module?, name?, node?, optimization?, output?, parallelism?, performance?, plugins?, profile?, recordsInputPath?, recordsOutputPath?, recordsPath?, resolve?, resolveLoader?, stats?, target?, watch?, watchOptions? }
object { amd?, bail?, cache?, context?, dependencies?, devServer?, devtool?, entry?, experiments?, externals?, externalsType?, infrastructureLogging?, loader?, mode?, module?, name?, node?, optimization?, output?, parallelism?, performance?, plugins?, profile?, recordsInputPath?, recordsOutputPath?, recordsPath?, resolve?, resolveLoader?, snapshot?, stats?, target?, watch?, watchOptions? }
-> Options object as provided by the user."
`)
);
@ -33,7 +33,7 @@ describe("Validation", () => {
expect(msg).toMatchInlineSnapshot(`
"Invalid configuration object. Webpack has been initialized using a configuration object that does not match the API schema.
- configuration should be an object:
object { amd?, bail?, cache?, context?, dependencies?, devServer?, devtool?, entry?, experiments?, externals?, externalsType?, infrastructureLogging?, loader?, mode?, module?, name?, node?, optimization?, output?, parallelism?, performance?, plugins?, profile?, recordsInputPath?, recordsOutputPath?, recordsPath?, resolve?, resolveLoader?, stats?, target?, watch?, watchOptions? }
object { amd?, bail?, cache?, context?, dependencies?, devServer?, devtool?, entry?, experiments?, externals?, externalsType?, infrastructureLogging?, loader?, mode?, module?, name?, node?, optimization?, output?, parallelism?, performance?, plugins?, profile?, recordsInputPath?, recordsOutputPath?, recordsPath?, resolve?, resolveLoader?, snapshot?, stats?, target?, watch?, watchOptions? }
-> Options object as provided by the user."
`)
);
@ -196,7 +196,7 @@ describe("Validation", () => {
expect(msg).toMatchInlineSnapshot(`
"Invalid configuration object. Webpack has been initialized using a configuration object that does not match the API schema.
- configuration has an unknown property 'postcss'. These properties are valid:
object { amd?, bail?, cache?, context?, dependencies?, devServer?, devtool?, entry?, experiments?, externals?, externalsType?, infrastructureLogging?, loader?, mode?, module?, name?, node?, optimization?, output?, parallelism?, performance?, plugins?, profile?, recordsInputPath?, recordsOutputPath?, recordsPath?, resolve?, resolveLoader?, stats?, target?, watch?, watchOptions? }
object { amd?, bail?, cache?, context?, dependencies?, devServer?, devtool?, entry?, experiments?, externals?, externalsType?, infrastructureLogging?, loader?, mode?, module?, name?, node?, optimization?, output?, parallelism?, performance?, plugins?, profile?, recordsInputPath?, recordsOutputPath?, recordsPath?, resolve?, resolveLoader?, snapshot?, stats?, target?, watch?, watchOptions? }
-> Options object as provided by the user.
For typos: please correct them.
For loader options: webpack >= v2.0.0 no longer allows custom properties in configuration.
@ -426,7 +426,7 @@ describe("Validation", () => {
expect(msg).toMatchInlineSnapshot(`
"Invalid configuration object. Webpack has been initialized using a configuration object that does not match the API schema.
- configuration has an unknown property 'debug'. These properties are valid:
object { amd?, bail?, cache?, context?, dependencies?, devServer?, devtool?, entry?, experiments?, externals?, externalsType?, infrastructureLogging?, loader?, mode?, module?, name?, node?, optimization?, output?, parallelism?, performance?, plugins?, profile?, recordsInputPath?, recordsOutputPath?, recordsPath?, resolve?, resolveLoader?, stats?, target?, watch?, watchOptions? }
object { amd?, bail?, cache?, context?, dependencies?, devServer?, devtool?, entry?, experiments?, externals?, externalsType?, infrastructureLogging?, loader?, mode?, module?, name?, node?, optimization?, output?, parallelism?, performance?, plugins?, profile?, recordsInputPath?, recordsOutputPath?, recordsPath?, resolve?, resolveLoader?, snapshot?, stats?, target?, watch?, watchOptions? }
-> Options object as provided by the user.
The 'debug' property was removed in webpack 2.0.0.
Loaders should be updated to allow passing this option via loader options in module.rules.
@ -482,7 +482,7 @@ describe("Validation", () => {
expect(msg).toMatchInlineSnapshot(`
"Invalid configuration object. Webpack has been initialized using a configuration object that does not match the API schema.
- configuration[1] should be an object:
object { amd?, bail?, cache?, context?, dependencies?, devServer?, devtool?, entry?, experiments?, externals?, externalsType?, infrastructureLogging?, loader?, mode?, module?, name?, node?, optimization?, output?, parallelism?, performance?, plugins?, profile?, recordsInputPath?, recordsOutputPath?, recordsPath?, resolve?, resolveLoader?, stats?, target?, watch?, watchOptions? }
object { amd?, bail?, cache?, context?, dependencies?, devServer?, devtool?, entry?, experiments?, externals?, externalsType?, infrastructureLogging?, loader?, mode?, module?, name?, node?, optimization?, output?, parallelism?, performance?, plugins?, profile?, recordsInputPath?, recordsOutputPath?, recordsPath?, resolve?, resolveLoader?, snapshot?, stats?, target?, watch?, watchOptions? }
-> Options object as provided by the user."
`)
);
@ -621,7 +621,7 @@ describe("Validation", () => {
expect(msg).toMatchInlineSnapshot(`
"Invalid configuration object. Webpack has been initialized using a configuration object that does not match the API schema.
- configuration has an unknown property 'rules'. These properties are valid:
object { amd?, bail?, cache?, context?, dependencies?, devServer?, devtool?, entry?, experiments?, externals?, externalsType?, infrastructureLogging?, loader?, mode?, module?, name?, node?, optimization?, output?, parallelism?, performance?, plugins?, profile?, recordsInputPath?, recordsOutputPath?, recordsPath?, resolve?, resolveLoader?, stats?, target?, watch?, watchOptions? }
object { amd?, bail?, cache?, context?, dependencies?, devServer?, devtool?, entry?, experiments?, externals?, externalsType?, infrastructureLogging?, loader?, mode?, module?, name?, node?, optimization?, output?, parallelism?, performance?, plugins?, profile?, recordsInputPath?, recordsOutputPath?, recordsPath?, resolve?, resolveLoader?, snapshot?, stats?, target?, watch?, watchOptions? }
-> Options object as provided by the user.
Did you mean module.rules?"
`)
@ -635,7 +635,7 @@ describe("Validation", () => {
expect(msg).toMatchInlineSnapshot(`
"Invalid configuration object. Webpack has been initialized using a configuration object that does not match the API schema.
- configuration has an unknown property 'splitChunks'. These properties are valid:
object { amd?, bail?, cache?, context?, dependencies?, devServer?, devtool?, entry?, experiments?, externals?, externalsType?, infrastructureLogging?, loader?, mode?, module?, name?, node?, optimization?, output?, parallelism?, performance?, plugins?, profile?, recordsInputPath?, recordsOutputPath?, recordsPath?, resolve?, resolveLoader?, stats?, target?, watch?, watchOptions? }
object { amd?, bail?, cache?, context?, dependencies?, devServer?, devtool?, entry?, experiments?, externals?, externalsType?, infrastructureLogging?, loader?, mode?, module?, name?, node?, optimization?, output?, parallelism?, performance?, plugins?, profile?, recordsInputPath?, recordsOutputPath?, recordsPath?, resolve?, resolveLoader?, snapshot?, stats?, target?, watch?, watchOptions? }
-> Options object as provided by the user.
Did you mean optimization.splitChunks?"
`)
@ -649,7 +649,7 @@ describe("Validation", () => {
expect(msg).toMatchInlineSnapshot(`
"Invalid configuration object. Webpack has been initialized using a configuration object that does not match the API schema.
- configuration has an unknown property 'noParse'. These properties are valid:
object { amd?, bail?, cache?, context?, dependencies?, devServer?, devtool?, entry?, experiments?, externals?, externalsType?, infrastructureLogging?, loader?, mode?, module?, name?, node?, optimization?, output?, parallelism?, performance?, plugins?, profile?, recordsInputPath?, recordsOutputPath?, recordsPath?, resolve?, resolveLoader?, stats?, target?, watch?, watchOptions? }
object { amd?, bail?, cache?, context?, dependencies?, devServer?, devtool?, entry?, experiments?, externals?, externalsType?, infrastructureLogging?, loader?, mode?, module?, name?, node?, optimization?, output?, parallelism?, performance?, plugins?, profile?, recordsInputPath?, recordsOutputPath?, recordsPath?, resolve?, resolveLoader?, snapshot?, stats?, target?, watch?, watchOptions? }
-> Options object as provided by the user.
Did you mean module.noParse?"
`)

View File

@ -3552,6 +3552,162 @@ Object {
"multiple": false,
"simpleType": "boolean",
},
"snapshot-build-dependencies-hash": Object {
"configs": Array [
Object {
"description": "Use hashes of the content of the files/directories to determine invalidation.",
"multiple": false,
"path": "snapshot.buildDependencies.hash",
"type": "boolean",
},
],
"description": "Use hashes of the content of the files/directories to determine invalidation.",
"multiple": false,
"simpleType": "boolean",
},
"snapshot-build-dependencies-timestamp": Object {
"configs": Array [
Object {
"description": "Use timestamps of the files/directories to determine invalidation.",
"multiple": false,
"path": "snapshot.buildDependencies.timestamp",
"type": "boolean",
},
],
"description": "Use timestamps of the files/directories to determine invalidation.",
"multiple": false,
"simpleType": "boolean",
},
"snapshot-immutable-paths": Object {
"configs": Array [
Object {
"description": "A path to a immutable directory (usually a package manager cache directory).",
"multiple": true,
"path": "snapshot.immutablePaths[]",
"type": "path",
},
],
"description": "A path to a immutable directory (usually a package manager cache directory).",
"multiple": true,
"simpleType": "string",
},
"snapshot-immutable-paths-reset": Object {
"configs": Array [
Object {
"description": "Clear all items provided in configuration. List of paths that are managed by a package manager and contain a version or hash in its path so all files are immutable.",
"multiple": false,
"path": "snapshot.immutablePaths",
"type": "reset",
},
],
"description": "Clear all items provided in configuration. List of paths that are managed by a package manager and contain a version or hash in its path so all files are immutable.",
"multiple": false,
"simpleType": "boolean",
},
"snapshot-managed-paths": Object {
"configs": Array [
Object {
"description": "A path to a managed directory (usually a node_modules directory).",
"multiple": true,
"path": "snapshot.managedPaths[]",
"type": "path",
},
],
"description": "A path to a managed directory (usually a node_modules directory).",
"multiple": true,
"simpleType": "string",
},
"snapshot-managed-paths-reset": Object {
"configs": Array [
Object {
"description": "Clear all items provided in configuration. List of paths that are managed by a package manager and can be trusted to not be modified otherwise.",
"multiple": false,
"path": "snapshot.managedPaths",
"type": "reset",
},
],
"description": "Clear all items provided in configuration. List of paths that are managed by a package manager and can be trusted to not be modified otherwise.",
"multiple": false,
"simpleType": "boolean",
},
"snapshot-module-hash": Object {
"configs": Array [
Object {
"description": "Use hashes of the content of the files/directories to determine invalidation.",
"multiple": false,
"path": "snapshot.module.hash",
"type": "boolean",
},
],
"description": "Use hashes of the content of the files/directories to determine invalidation.",
"multiple": false,
"simpleType": "boolean",
},
"snapshot-module-timestamp": Object {
"configs": Array [
Object {
"description": "Use timestamps of the files/directories to determine invalidation.",
"multiple": false,
"path": "snapshot.module.timestamp",
"type": "boolean",
},
],
"description": "Use timestamps of the files/directories to determine invalidation.",
"multiple": false,
"simpleType": "boolean",
},
"snapshot-resolve-build-dependencies-hash": Object {
"configs": Array [
Object {
"description": "Use hashes of the content of the files/directories to determine invalidation.",
"multiple": false,
"path": "snapshot.resolveBuildDependencies.hash",
"type": "boolean",
},
],
"description": "Use hashes of the content of the files/directories to determine invalidation.",
"multiple": false,
"simpleType": "boolean",
},
"snapshot-resolve-build-dependencies-timestamp": Object {
"configs": Array [
Object {
"description": "Use timestamps of the files/directories to determine invalidation.",
"multiple": false,
"path": "snapshot.resolveBuildDependencies.timestamp",
"type": "boolean",
},
],
"description": "Use timestamps of the files/directories to determine invalidation.",
"multiple": false,
"simpleType": "boolean",
},
"snapshot-resolve-hash": Object {
"configs": Array [
Object {
"description": "Use hashes of the content of the files/directories to determine invalidation.",
"multiple": false,
"path": "snapshot.resolve.hash",
"type": "boolean",
},
],
"description": "Use hashes of the content of the files/directories to determine invalidation.",
"multiple": false,
"simpleType": "boolean",
},
"snapshot-resolve-timestamp": Object {
"configs": Array [
Object {
"description": "Use timestamps of the files/directories to determine invalidation.",
"multiple": false,
"path": "snapshot.resolve.timestamp",
"type": "boolean",
},
],
"description": "Use timestamps of the files/directories to determine invalidation.",
"multiple": false,
"simpleType": "boolean",
},
"stats": Object {
"configs": Array [
Object {

View File

@ -1164,9 +1164,9 @@ Entrypoint <CLR=BOLD>main</CLR> = <CLR=32,BOLD>main.js</CLR>
<CLR=BOLD>0% root snapshot uncached (0 / 0)</CLR>
<CLR=BOLD>0% children snapshot uncached (0 / 0)</CLR>
<CLR=BOLD>0 entries tested</CLR>
<CLR=BOLD>File info in cache: 1 timestamps 0 hashes</CLR>
<CLR=BOLD>File timestamp snapshot optimization: 0% (0/1) entries shared via 0 shared snapshots (0 times referenced)</CLR>
<CLR=BOLD>Directory info in cache: 0 timestamps 0 hashes</CLR>
<CLR=BOLD>File info in cache: 1 timestamps 1 hashes 1 timestamp hash combinations</CLR>
<CLR=BOLD>File timestamp hash combination snapshot optimization: 0% (0/1) entries shared via 0 shared snapshots (0 times referenced)</CLR>
<CLR=BOLD>Directory info in cache: 0 timestamps 0 hashes 0 timestamp hash combinations</CLR>
<CLR=BOLD>Managed items info in cache: 0 items</CLR>
"
`;
@ -1973,9 +1973,9 @@ LOG from webpack.FileSystemInfo
0% root snapshot uncached (0 / 0)
0% children snapshot uncached (0 / 0)
0 entries tested
File info in cache: 6 timestamps 0 hashes
File timestamp snapshot optimization: 0% (0/6) entries shared via 0 shared snapshots (0 times referenced)
Directory info in cache: 0 timestamps 0 hashes
File info in cache: 6 timestamps 6 hashes 6 timestamp hash combinations
File timestamp hash combination snapshot optimization: 0% (0/6) entries shared via 0 shared snapshots (0 times referenced)
Directory info in cache: 0 timestamps 0 hashes 0 timestamp hash combinations
Managed items info in cache: 0 items
"
`;
@ -2310,9 +2310,9 @@ LOG from webpack.FileSystemInfo
0% root snapshot uncached (0 / 0)
0% children snapshot uncached (0 / 0)
0 entries tested
File info in cache: 6 timestamps 0 hashes
File timestamp snapshot optimization: 0% (0/6) entries shared via 0 shared snapshots (0 times referenced)
Directory info in cache: 0 timestamps 0 hashes
File info in cache: 6 timestamps 6 hashes 6 timestamp hash combinations
File timestamp hash combination snapshot optimization: 0% (0/6) entries shared via 0 shared snapshots (0 times referenced)
Directory info in cache: 0 timestamps 0 hashes 0 timestamp hash combinations
Managed items info in cache: 0 items
"
`;

View File

@ -31,7 +31,9 @@ webpack(
__filename,
path.resolve(__dirname, "../../../node_modules/.yarn-integrity")
]
},
}
},
snapshot: {
managedPaths: [path.resolve(__dirname, "../../../node_modules")]
}
},

View File

@ -4,7 +4,9 @@ const path = require("path");
module.exports = {
mode: "development",
cache: {
type: "memory",
type: "memory"
},
snapshot: {
managedPaths: [
path.resolve(
__dirname,

View File

@ -2,7 +2,9 @@ const path = require("path");
/** @type {function(any, any): import("../../../../").Configuration} */
module.exports = (env, { srcPath }) => ({
cache: {
type: "memory",
type: "memory"
},
snapshot: {
managedPaths: [path.resolve(srcPath, "node_modules")]
}
});

107
types.d.ts vendored
View File

@ -1741,6 +1741,11 @@ declare interface Configuration {
*/
resolveLoader?: ResolveOptionsWebpackOptions;
/**
* Options affecting how file system snapshots are created and validated.
*/
snapshot?: SnapshotOptions;
/**
* Stats options object or preset name.
*/
@ -3090,11 +3095,11 @@ declare abstract class FileSystemInfo {
missing: Iterable<string>,
options: {
/**
* should use hash to snapshot
* Use hashes of the content of the files/directories to determine invalidation.
*/
hash?: boolean;
/**
* should use timestamp to snapshot
* Use timestamps of the files/directories to determine invalidation.
*/
timestamp?: boolean;
},
@ -4236,16 +4241,6 @@ declare interface MapOptions {
* Options object for in-memory caching.
*/
declare interface MemoryCacheOptions {
/**
* List of paths that are managed by a package manager and contain a version or hash in its path so all files are immutable.
*/
immutablePaths?: string[];
/**
* List of paths that are managed by a package manager and can be trusted to not be modified otherwise.
*/
managedPaths?: string[];
/**
* In memory caching.
*/
@ -7859,8 +7854,10 @@ declare abstract class Snapshot {
startTime: number;
fileTimestamps: Map<string, FileSystemInfoEntry>;
fileHashes: Map<string, string>;
fileTshs: Map<string, string | TimestampAndHash>;
contextTimestamps: Map<string, FileSystemInfoEntry>;
contextHashes: Map<string, string>;
contextTshs: Map<string, string | TimestampAndHash>;
missingExistence: Map<string, boolean>;
managedItemInfo: Map<string, string>;
managedFiles: Set<string>;
@ -7874,10 +7871,14 @@ declare abstract class Snapshot {
setFileTimestamps(value?: any): void;
hasFileHashes(): boolean;
setFileHashes(value?: any): void;
hasFileTshs(): boolean;
setFileTshs(value?: any): void;
hasContextTimestamps(): boolean;
setContextTimestamps(value?: any): void;
hasContextHashes(): boolean;
setContextHashes(value?: any): void;
hasContextTshs(): boolean;
setContextTshs(value?: any): void;
hasMissingExistence(): boolean;
setMissingExistence(value?: any): void;
hasManagedItemInfo(): boolean;
@ -7897,6 +7898,77 @@ declare abstract class Snapshot {
getContextIterable(): Iterable<string>;
getMissingIterable(): Iterable<string>;
}
/**
* Options affecting how file system snapshots are created and validated.
*/
declare interface SnapshotOptions {
/**
* Options for snapshotting build dependencies to determine if the whole cache need to be invalidated.
*/
buildDependencies?: {
/**
* Use hashes of the content of the files/directories to determine invalidation.
*/
hash?: boolean;
/**
* Use timestamps of the files/directories to determine invalidation.
*/
timestamp?: boolean;
};
/**
* List of paths that are managed by a package manager and contain a version or hash in its path so all files are immutable.
*/
immutablePaths?: string[];
/**
* List of paths that are managed by a package manager and can be trusted to not be modified otherwise.
*/
managedPaths?: string[];
/**
* Options for snapshotting dependencies of modules to determine if they need to be built again.
*/
module?: {
/**
* Use hashes of the content of the files/directories to determine invalidation.
*/
hash?: boolean;
/**
* Use timestamps of the files/directories to determine invalidation.
*/
timestamp?: boolean;
};
/**
* Options for snapshotting dependencies of request resolving to determine if requests need to be re-resolved.
*/
resolve?: {
/**
* Use hashes of the content of the files/directories to determine invalidation.
*/
hash?: boolean;
/**
* Use timestamps of the files/directories to determine invalidation.
*/
timestamp?: boolean;
};
/**
* Options for snapshotting the resolving of build dependencies to determine if the build dependencies need to be re-resolved.
*/
resolveBuildDependencies?: {
/**
* Use hashes of the content of the files/directories to determine invalidation.
*/
hash?: boolean;
/**
* Use timestamps of the files/directories to determine invalidation.
*/
timestamp?: boolean;
};
}
declare abstract class SortableSet<T> extends Set<T> {
/**
* Sort with a comparer function
@ -8507,6 +8579,12 @@ declare class Template {
static NUMBER_OF_IDENTIFIER_START_CHARS: number;
static NUMBER_OF_IDENTIFIER_CONTINUATION_CHARS: number;
}
declare interface TimestampAndHash {
safeTime: number;
timestamp?: number;
timestampHash?: string;
hash: string;
}
declare const UNDEFINED_MARKER: unique symbol;
declare interface UpdateHashContextDependency {
chunkGraph: ChunkGraph;
@ -8970,6 +9048,11 @@ declare interface WebpackOptionsNormalized {
*/
resolveLoader: ResolveOptionsWebpackOptions;
/**
* Options affecting how file system snapshots are created and validated.
*/
snapshot: SnapshotOptions;
/**
* Stats options object or preset name.
*/