mirror of https://github.com/webpack/webpack.git
Compare commits
7 Commits
5b6d7ba0c3
...
8ae623d6c1
| Author | SHA1 | Date |
|---|---|---|
|
|
8ae623d6c1 | |
|
|
9f98d803c0 | |
|
|
8804459884 | |
|
|
bc91301142 | |
|
|
5197fd7f03 | |
|
|
a51d2349ee | |
|
|
81268133cd |
|
|
@ -97,7 +97,7 @@ jobs:
|
||||||
- run: yarn link webpack --frozen-lockfile
|
- run: yarn link webpack --frozen-lockfile
|
||||||
|
|
||||||
- name: Run benchmarks
|
- name: Run benchmarks
|
||||||
uses: CodSpeedHQ/action@653fdc30e6c40ffd9739e40c8a0576f4f4523ca1 # v4.0.1
|
uses: CodSpeedHQ/action@3959e9e296ef25296e93e32afcc97196f966e57f # v4.1.0
|
||||||
with:
|
with:
|
||||||
run: yarn benchmark --ci
|
run: yarn benchmark --ci
|
||||||
mode: "instrumentation"
|
mode: "instrumentation"
|
||||||
|
|
|
||||||
|
|
@ -284,6 +284,7 @@
|
||||||
"url's",
|
"url's",
|
||||||
"valign",
|
"valign",
|
||||||
"valtype",
|
"valtype",
|
||||||
|
"walltime",
|
||||||
"wasi",
|
"wasi",
|
||||||
"wasm",
|
"wasm",
|
||||||
"watchings",
|
"watchings",
|
||||||
|
|
@ -304,7 +305,6 @@
|
||||||
"commithash",
|
"commithash",
|
||||||
"formaters",
|
"formaters",
|
||||||
"akait",
|
"akait",
|
||||||
"Akait",
|
|
||||||
"evenstensberg",
|
"evenstensberg",
|
||||||
"Stensberg",
|
"Stensberg",
|
||||||
"ovflowd",
|
"ovflowd",
|
||||||
|
|
|
||||||
|
|
@ -3349,7 +3349,6 @@ export interface JavascriptParserOptions {
|
||||||
* Set the inner regular expression for partial dynamic dependencies.
|
* Set the inner regular expression for partial dynamic dependencies.
|
||||||
*/
|
*/
|
||||||
wrappedContextRegExp?: RegExp;
|
wrappedContextRegExp?: RegExp;
|
||||||
[k: string]: any;
|
|
||||||
}
|
}
|
||||||
/**
|
/**
|
||||||
* Generator options for json modules.
|
* Generator options for json modules.
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
/*
|
||||||
|
* This file was automatically generated.
|
||||||
|
* DO NOT MODIFY BY HAND.
|
||||||
|
* Run `yarn fix:special` to update
|
||||||
|
*/
|
||||||
|
|
||||||
|
export interface ManifestPluginOptions {
|
||||||
|
/**
|
||||||
|
* Specifies the filename of the output file on disk. By default the plugin will emit `manifest.json` inside the 'output.path' directory.
|
||||||
|
*/
|
||||||
|
filename?: string;
|
||||||
|
/**
|
||||||
|
* A custom Function to create the manifest.
|
||||||
|
*/
|
||||||
|
handle?: (
|
||||||
|
manifest: Record<string, string>,
|
||||||
|
stats: import("../../lib/stats/DefaultStatsFactoryPlugin").StatsCompilation
|
||||||
|
) => string;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,149 @@
|
||||||
|
This example demonstrates how to use webpack internal ManifestPlugin.
|
||||||
|
|
||||||
|
# example.js
|
||||||
|
|
||||||
|
```js
|
||||||
|
import("./baz");
|
||||||
|
```
|
||||||
|
|
||||||
|
# foo.txt
|
||||||
|
|
||||||
|
```js
|
||||||
|
foo
|
||||||
|
```
|
||||||
|
|
||||||
|
# bar.txt
|
||||||
|
|
||||||
|
```js
|
||||||
|
bar
|
||||||
|
```
|
||||||
|
|
||||||
|
# baz.js
|
||||||
|
|
||||||
|
```js
|
||||||
|
import foo from "./foo.txt";
|
||||||
|
import bar from "./bar.txt";
|
||||||
|
|
||||||
|
export default foo + bar;
|
||||||
|
```
|
||||||
|
|
||||||
|
# webpack.config.js
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
const webpack = require("../../");
|
||||||
|
|
||||||
|
/** @type {webpack.Configuration} */
|
||||||
|
module.exports = {
|
||||||
|
devtool: "source-map",
|
||||||
|
module: {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
test: /foo.txt/,
|
||||||
|
type: "asset/resource"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /bar.txt/,
|
||||||
|
use: require.resolve("file-loader")
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
plugins: [
|
||||||
|
new webpack.ManifestPlugin({
|
||||||
|
filename: "manifest.json"
|
||||||
|
}),
|
||||||
|
new webpack.ManifestPlugin({
|
||||||
|
filename: "manifest.yml",
|
||||||
|
handle(manifest) {
|
||||||
|
let _manifest = "";
|
||||||
|
for (const key in manifest) {
|
||||||
|
if (key === "manifest.json") continue;
|
||||||
|
_manifest += `- ${key}: '${manifest[key]}'\n`;
|
||||||
|
}
|
||||||
|
return _manifest;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
]
|
||||||
|
};
|
||||||
|
```
|
||||||
|
|
||||||
|
# dist/manifest.json
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"output.js.map": "dist/output.js.map",
|
||||||
|
"main.js": "dist/output.js",
|
||||||
|
"bar.txt": "dist/a0145fafc7fab801e574631452de554b.txt",
|
||||||
|
"foo.txt": "dist/3ee037f347c64cc372ad.txt",
|
||||||
|
"1.output.js.map": "dist/1.output.js.map",
|
||||||
|
"1.output.js": "dist/1.output.js"
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
# dist/manifest.yml
|
||||||
|
|
||||||
|
```yml
|
||||||
|
- output.js.map: 'dist/output.js.map'
|
||||||
|
- main.js: 'dist/output.js'
|
||||||
|
- bar.txt: 'dist/a0145fafc7fab801e574631452de554b.txt'
|
||||||
|
- foo.txt: 'dist/3ee037f347c64cc372ad.txt'
|
||||||
|
- 1.output.js.map: 'dist/1.output.js.map'
|
||||||
|
- 1.output.js: 'dist/1.output.js'
|
||||||
|
```
|
||||||
|
|
||||||
|
# Info
|
||||||
|
|
||||||
|
## Unoptimized
|
||||||
|
|
||||||
|
```
|
||||||
|
assets by path *.js 11.9 KiB
|
||||||
|
asset output.js 9.61 KiB [emitted] (name: main) 1 related asset
|
||||||
|
asset 1.output.js 2.3 KiB [emitted] 1 related asset
|
||||||
|
assets by path *.txt 8 bytes
|
||||||
|
asset 3ee037f347c64cc372ad.txt 4 bytes [emitted] [immutable] [from: foo.txt]
|
||||||
|
asset a0145fafc7fab801e574631452de554b.txt 4 bytes [emitted] [immutable] [from: bar.txt]
|
||||||
|
asset manifest.json 260 bytes [emitted]
|
||||||
|
asset manifest.yml 240 bytes [emitted]
|
||||||
|
chunk (runtime: main) output.js (main) 17 bytes (javascript) 5.48 KiB (runtime) [entry] [rendered]
|
||||||
|
> ./example.js main
|
||||||
|
runtime modules 5.48 KiB 8 modules
|
||||||
|
./example.js 17 bytes [built] [code generated]
|
||||||
|
[used exports unknown]
|
||||||
|
entry ./example.js main
|
||||||
|
chunk (runtime: main) 1.output.js 207 bytes (javascript) 4 bytes (asset) [rendered]
|
||||||
|
> ./baz ./example.js 1:0-15
|
||||||
|
dependent modules 122 bytes (javascript) 4 bytes (asset) [dependent] 2 modules
|
||||||
|
./baz.js 85 bytes [built] [code generated]
|
||||||
|
[exports: default]
|
||||||
|
[used exports unknown]
|
||||||
|
import() ./baz ./example.js 1:0-15
|
||||||
|
webpack X.X.X compiled successfully
|
||||||
|
```
|
||||||
|
|
||||||
|
## Production mode
|
||||||
|
|
||||||
|
```
|
||||||
|
assets by path *.js 2.17 KiB
|
||||||
|
asset output.js 1.94 KiB [emitted] [minimized] (name: main) 1 related asset
|
||||||
|
asset 293.output.js 237 bytes [emitted] [minimized] 1 related asset
|
||||||
|
assets by path *.txt 8 bytes
|
||||||
|
asset 3ee037f347c64cc372ad.txt 4 bytes [emitted] [immutable] [from: foo.txt]
|
||||||
|
asset a0145fafc7fab801e574631452de554b.txt 4 bytes [emitted] [immutable] [from: bar.txt]
|
||||||
|
asset manifest.json 268 bytes [emitted]
|
||||||
|
asset manifest.yml 248 bytes [emitted]
|
||||||
|
chunk (runtime: main) 293.output.js 4 bytes (asset) 249 bytes (javascript) [rendered]
|
||||||
|
> ./baz ./example.js 1:0-15
|
||||||
|
./baz.js + 2 modules 207 bytes [built] [code generated]
|
||||||
|
[exports: default]
|
||||||
|
import() ./baz ./example.js 1:0-15
|
||||||
|
./foo.txt 4 bytes (asset) 42 bytes (javascript) [built] [code generated]
|
||||||
|
[no exports]
|
||||||
|
chunk (runtime: main) output.js (main) 17 bytes (javascript) 5.48 KiB (runtime) [entry] [rendered]
|
||||||
|
> ./example.js main
|
||||||
|
runtime modules 5.48 KiB 8 modules
|
||||||
|
./example.js 17 bytes [built] [code generated]
|
||||||
|
[no exports used]
|
||||||
|
entry ./example.js main
|
||||||
|
webpack X.X.X compiled successfully
|
||||||
|
```
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
bar
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
import foo from "./foo.txt";
|
||||||
|
import bar from "./bar.txt";
|
||||||
|
|
||||||
|
export default foo + bar;
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
require("../build-common");
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
import("./baz");
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
foo
|
||||||
|
|
@ -0,0 +1,57 @@
|
||||||
|
This example demonstrates how to use webpack internal ManifestPlugin.
|
||||||
|
|
||||||
|
# example.js
|
||||||
|
|
||||||
|
```js
|
||||||
|
_{{example.js}}_
|
||||||
|
```
|
||||||
|
|
||||||
|
# foo.txt
|
||||||
|
|
||||||
|
```js
|
||||||
|
_{{foo.txt}}_
|
||||||
|
```
|
||||||
|
|
||||||
|
# bar.txt
|
||||||
|
|
||||||
|
```js
|
||||||
|
_{{bar.txt}}_
|
||||||
|
```
|
||||||
|
|
||||||
|
# baz.js
|
||||||
|
|
||||||
|
```js
|
||||||
|
_{{baz.js}}_
|
||||||
|
```
|
||||||
|
|
||||||
|
# webpack.config.js
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
_{{webpack.config.js}}_
|
||||||
|
```
|
||||||
|
|
||||||
|
# dist/manifest.json
|
||||||
|
|
||||||
|
```json
|
||||||
|
_{{dist/manifest.json}}_
|
||||||
|
```
|
||||||
|
|
||||||
|
# dist/manifest.yml
|
||||||
|
|
||||||
|
```yml
|
||||||
|
_{{dist/manifest.yml}}_
|
||||||
|
```
|
||||||
|
|
||||||
|
# Info
|
||||||
|
|
||||||
|
## Unoptimized
|
||||||
|
|
||||||
|
```
|
||||||
|
_{{stdout}}_
|
||||||
|
```
|
||||||
|
|
||||||
|
## Production mode
|
||||||
|
|
||||||
|
```
|
||||||
|
_{{production:stdout}}_
|
||||||
|
```
|
||||||
|
|
@ -0,0 +1,36 @@
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
const webpack = require("../../");
|
||||||
|
|
||||||
|
/** @type {webpack.Configuration} */
|
||||||
|
module.exports = {
|
||||||
|
devtool: "source-map",
|
||||||
|
module: {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
test: /foo.txt/,
|
||||||
|
type: "asset/resource"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /bar.txt/,
|
||||||
|
use: require.resolve("file-loader")
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
plugins: [
|
||||||
|
new webpack.ManifestPlugin({
|
||||||
|
filename: "manifest.json"
|
||||||
|
}),
|
||||||
|
new webpack.ManifestPlugin({
|
||||||
|
filename: "manifest.yml",
|
||||||
|
handle(manifest) {
|
||||||
|
let _manifest = "";
|
||||||
|
for (const key in manifest) {
|
||||||
|
if (key === "manifest.json") continue;
|
||||||
|
_manifest += `- ${key}: '${manifest[key]}'\n`;
|
||||||
|
}
|
||||||
|
return _manifest;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
@ -355,6 +355,9 @@ module.exports = mergeExports(fn, {
|
||||||
get Stats() {
|
get Stats() {
|
||||||
return require("./Stats");
|
return require("./Stats");
|
||||||
},
|
},
|
||||||
|
get ManifestPlugin() {
|
||||||
|
return require("./stats/ManifestPlugin");
|
||||||
|
},
|
||||||
get Template() {
|
get Template() {
|
||||||
return require("./Template");
|
return require("./Template");
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,180 @@
|
||||||
|
/*
|
||||||
|
MIT License http://www.opensource.org/licenses/mit-license.php
|
||||||
|
Author Haijie Xie @hai-x
|
||||||
|
*/
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
const path = require("path");
|
||||||
|
const { RawSource } = require("webpack-sources");
|
||||||
|
const Compilation = require("../Compilation");
|
||||||
|
const HotUpdateChunk = require("../HotUpdateChunk");
|
||||||
|
const createSchemaValidation = require("../util/create-schema-validation");
|
||||||
|
|
||||||
|
/** @typedef {import("../Compiler")} Compiler */
|
||||||
|
/** @typedef {import("..").StatsCompilation} StatsCompilation */
|
||||||
|
/** @typedef {import("../Chunk")} Chunk */
|
||||||
|
/** @typedef {import("../Compilation").Asset} Asset */
|
||||||
|
/** @typedef {import("../Module")} Module */
|
||||||
|
/** @typedef {import("../NormalModule")} NormalModule */
|
||||||
|
/** @typedef {import("../config/defaults").WebpackOptionsNormalizedWithDefaults} WebpackOptions */
|
||||||
|
|
||||||
|
/** @typedef {import("../../declarations/plugins/ManifestPlugin").ManifestPluginOptions} ManifestPluginOptions */
|
||||||
|
|
||||||
|
const PLUGIN_NAME = "ManifestPlugin";
|
||||||
|
|
||||||
|
const validate = createSchemaValidation(
|
||||||
|
require("../../schemas/plugins/ManifestPlugin.check"),
|
||||||
|
() => require("../../schemas/plugins/ManifestPlugin.json"),
|
||||||
|
{
|
||||||
|
name: "ManifestPlugin",
|
||||||
|
baseDataPath: "options"
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} filename filename
|
||||||
|
* @returns {string} extname
|
||||||
|
*/
|
||||||
|
const extname = (filename) => {
|
||||||
|
const replaced = filename.replace(/\?.*/, "");
|
||||||
|
const split = replaced.split(".");
|
||||||
|
const last = split.pop();
|
||||||
|
if (!last) return "";
|
||||||
|
return last && /^(gz|map)$/i.test(last) ? `${split.pop()}.${last}` : last;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ManifestPlugin {
|
||||||
|
/**
|
||||||
|
* @param {ManifestPluginOptions} options options
|
||||||
|
*/
|
||||||
|
constructor(options) {
|
||||||
|
validate(options);
|
||||||
|
|
||||||
|
/** @type {Required<ManifestPluginOptions>} */
|
||||||
|
this.options = {
|
||||||
|
filename: "manifest.json",
|
||||||
|
handle: (manifest, _stats) => JSON.stringify(manifest, null, 2),
|
||||||
|
...options
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Apply the plugin
|
||||||
|
* @param {Compiler} compiler the compiler instance
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
|
apply(compiler) {
|
||||||
|
/** @type {WeakMap<Compilation, StatsCompilation>} */
|
||||||
|
const cachedStats = new WeakMap();
|
||||||
|
|
||||||
|
compiler.hooks.thisCompilation.tap(PLUGIN_NAME, (compilation) => {
|
||||||
|
compilation.hooks.processAssets.tap(
|
||||||
|
{
|
||||||
|
name: PLUGIN_NAME,
|
||||||
|
stage: Compilation.PROCESS_ASSETS_STAGE_SUMMARIZE
|
||||||
|
},
|
||||||
|
() => {
|
||||||
|
let stats =
|
||||||
|
/** @type {StatsCompilation | undefined} */ cachedStats.get(
|
||||||
|
compilation
|
||||||
|
);
|
||||||
|
if (!stats) {
|
||||||
|
stats = compilation.getStats().toJson({
|
||||||
|
all: false,
|
||||||
|
assets: true,
|
||||||
|
cachedAssets: true,
|
||||||
|
assetsSpace: Infinity,
|
||||||
|
publicPath: true
|
||||||
|
});
|
||||||
|
cachedStats.set(compilation, stats);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @type {Set<string>} */
|
||||||
|
const added = new Set();
|
||||||
|
/**
|
||||||
|
* @type {{name: string, file: string}[]}
|
||||||
|
*/
|
||||||
|
const items = [];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} file file
|
||||||
|
* @param {((file: string) => string)=} namer namer
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
|
const handleFile = (file, namer) => {
|
||||||
|
if (added.has(file)) return;
|
||||||
|
added.add(file);
|
||||||
|
|
||||||
|
let name = namer ? namer(file) : file;
|
||||||
|
const asset = compilation.getAsset(file);
|
||||||
|
if (asset && asset.info.sourceFilename) {
|
||||||
|
name = path.join(
|
||||||
|
path.dirname(file),
|
||||||
|
path.basename(asset.info.sourceFilename)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
items.push({ name, file });
|
||||||
|
};
|
||||||
|
|
||||||
|
for (const chunk of compilation.chunks) {
|
||||||
|
if (chunk instanceof HotUpdateChunk) continue;
|
||||||
|
|
||||||
|
const chunkName = chunk.name;
|
||||||
|
for (const auxiliaryFile of chunk.auxiliaryFiles) {
|
||||||
|
handleFile(auxiliaryFile, (file) => path.basename(file));
|
||||||
|
}
|
||||||
|
for (const file of chunk.files) {
|
||||||
|
handleFile(file, (file) => {
|
||||||
|
if (chunkName) return `${chunkName}.${extname(file)}`;
|
||||||
|
return file;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (stats.assets) {
|
||||||
|
for (const asset of stats.assets) {
|
||||||
|
if (asset.info.hotModuleReplacement) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
handleFile(asset.name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @type {Record<string, string>} */
|
||||||
|
const manifest = {};
|
||||||
|
const hashDigestLength = compilation.outputOptions.hashDigestLength;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {string} name name
|
||||||
|
* @returns {string} hash removed name
|
||||||
|
*/
|
||||||
|
const removeHash = (name) => {
|
||||||
|
// Handles hashes that match configured `hashDigestLength`
|
||||||
|
// i.e. index.XXXX.html -> index.html (html-webpack-plugin)
|
||||||
|
if (hashDigestLength <= 0) return name;
|
||||||
|
const reg = new RegExp(
|
||||||
|
`(\\.[a-f0-9]{${hashDigestLength}})(?=\\.)`,
|
||||||
|
"gi"
|
||||||
|
);
|
||||||
|
return name.replace(reg, "");
|
||||||
|
};
|
||||||
|
|
||||||
|
for (const { name, file } of items) {
|
||||||
|
manifest[removeHash(name)] = stats.publicPath
|
||||||
|
? stats.publicPath +
|
||||||
|
(stats.publicPath.endsWith("/") ? `${file}` : `/${file}`)
|
||||||
|
: file;
|
||||||
|
}
|
||||||
|
|
||||||
|
compilation.emitAsset(
|
||||||
|
this.options.filename,
|
||||||
|
new RawSource(this.options.handle(manifest, stats))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = ManifestPlugin;
|
||||||
|
|
@ -110,7 +110,7 @@
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "^7.27.1",
|
"@babel/core": "^7.27.1",
|
||||||
"@babel/preset-react": "^7.27.1",
|
"@babel/preset-react": "^7.27.1",
|
||||||
"@codspeed/core": "^4.0.1",
|
"@codspeed/core": "^5.0.1",
|
||||||
"@eslint/js": "^9.36.0",
|
"@eslint/js": "^9.36.0",
|
||||||
"@eslint/markdown": "^7.3.0",
|
"@eslint/markdown": "^7.3.0",
|
||||||
"@stylistic/eslint-plugin": "^5.4.0",
|
"@stylistic/eslint-plugin": "^5.4.0",
|
||||||
|
|
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -1786,7 +1786,7 @@
|
||||||
"JavascriptParserOptions": {
|
"JavascriptParserOptions": {
|
||||||
"description": "Parser options for javascript modules.",
|
"description": "Parser options for javascript modules.",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"additionalProperties": true,
|
"additionalProperties": false,
|
||||||
"properties": {
|
"properties": {
|
||||||
"amd": {
|
"amd": {
|
||||||
"$ref": "#/definitions/Amd"
|
"$ref": "#/definitions/Amd"
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
/*
|
||||||
|
* This file was automatically generated.
|
||||||
|
* DO NOT MODIFY BY HAND.
|
||||||
|
* Run `yarn fix:special` to update
|
||||||
|
*/
|
||||||
|
declare const check: (options: import("../../declarations/plugins/ManifestPlugin").ManifestPluginOptions) => boolean;
|
||||||
|
export = check;
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
/*
|
||||||
|
* This file was automatically generated.
|
||||||
|
* DO NOT MODIFY BY HAND.
|
||||||
|
* Run `yarn fix:special` to update
|
||||||
|
*/
|
||||||
|
const r=/^(?:[A-Za-z]:[\\/]|\\\\|\/)/;function e(t,{instancePath:a="",parentData:n,parentDataProperty:o,rootData:s=t}={}){if(!t||"object"!=typeof t||Array.isArray(t))return e.errors=[{params:{type:"object"}}],!1;{const a=0;for(const r in t)if("filename"!==r&&"handle"!==r)return e.errors=[{params:{additionalProperty:r}}],!1;if(0===a){if(void 0!==t.filename){let a=t.filename;const n=0;if(0===n){if("string"!=typeof a)return e.errors=[{params:{type:"string"}}],!1;if(a.includes("!")||!1!==r.test(a))return e.errors=[{params:{}}],!1;if(a.length<1)return e.errors=[{params:{}}],!1}var i=0===n}else i=!0;if(i)if(void 0!==t.handle){const r=0;if(!(t.handle instanceof Function))return e.errors=[{params:{}}],!1;i=0===r}else i=!0}}return e.errors=null,!0}module.exports=e,module.exports.default=e;
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
{
|
||||||
|
"title": "ManifestPluginOptions",
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": false,
|
||||||
|
"properties": {
|
||||||
|
"filename": {
|
||||||
|
"description": "Specifies the filename of the output file on disk. By default the plugin will emit `manifest.json` inside the 'output.path' directory.",
|
||||||
|
"type": "string",
|
||||||
|
"absolutePath": false,
|
||||||
|
"minLength": 1
|
||||||
|
},
|
||||||
|
"handle": {
|
||||||
|
"description": "A custom Function to create the manifest.",
|
||||||
|
"instanceof": "Function",
|
||||||
|
"tsType": "((manifest: Record<string, string>, stats: import('../../lib/stats/DefaultStatsFactoryPlugin').StatsCompilation) => string)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -3,6 +3,15 @@ import fs from "fs/promises";
|
||||||
import { Session } from "inspector";
|
import { Session } from "inspector";
|
||||||
import path from "path";
|
import path from "path";
|
||||||
import { fileURLToPath, pathToFileURL } from "url";
|
import { fileURLToPath, pathToFileURL } from "url";
|
||||||
|
import {
|
||||||
|
InstrumentHooks,
|
||||||
|
getCodspeedRunnerMode,
|
||||||
|
getGitDir,
|
||||||
|
getV8Flags,
|
||||||
|
mongoMeasurement,
|
||||||
|
setupCore,
|
||||||
|
teardownCore
|
||||||
|
} from "@codspeed/core";
|
||||||
import { simpleGit } from "simple-git";
|
import { simpleGit } from "simple-git";
|
||||||
import { Bench, hrtimeNow } from "tinybench";
|
import { Bench, hrtimeNow } from "tinybench";
|
||||||
|
|
||||||
|
|
@ -12,32 +21,6 @@ const git = simpleGit(rootPath);
|
||||||
|
|
||||||
const REV_LIST_REGEXP = /^([a-f0-9]+)\s*([a-f0-9]+)\s*([a-f0-9]+)?\s*$/;
|
const REV_LIST_REGEXP = /^([a-f0-9]+)\s*([a-f0-9]+)\s*([a-f0-9]+)?\s*$/;
|
||||||
|
|
||||||
const getV8Flags = () => {
|
|
||||||
const nodeVersionMajor = Number.parseInt(
|
|
||||||
process.version.slice(1).split(".")[0],
|
|
||||||
10
|
|
||||||
);
|
|
||||||
const flags = [
|
|
||||||
"--hash-seed=1",
|
|
||||||
"--random-seed=1",
|
|
||||||
"--no-opt",
|
|
||||||
"--predictable",
|
|
||||||
"--predictable-gc-schedule",
|
|
||||||
"--interpreted-frames-native-stack",
|
|
||||||
"--allow-natives-syntax",
|
|
||||||
"--expose-gc",
|
|
||||||
"--no-concurrent-sweeping",
|
|
||||||
"--max-old-space-size=4096"
|
|
||||||
];
|
|
||||||
if (nodeVersionMajor < 18) {
|
|
||||||
flags.push("--no-randomize-hashes");
|
|
||||||
}
|
|
||||||
if (nodeVersionMajor < 20) {
|
|
||||||
flags.push("--no-scavenge-task");
|
|
||||||
}
|
|
||||||
return flags;
|
|
||||||
};
|
|
||||||
|
|
||||||
const checkV8Flags = () => {
|
const checkV8Flags = () => {
|
||||||
const requiredFlags = getV8Flags();
|
const requiredFlags = getV8Flags();
|
||||||
const actualFlags = process.execArgv;
|
const actualFlags = process.execArgv;
|
||||||
|
|
@ -248,6 +231,8 @@ for (const baselineInfo of baselineRevisions) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const baseOutputPath = path.join(__dirname, "js", "benchmark");
|
||||||
|
|
||||||
function buildConfiguration(
|
function buildConfiguration(
|
||||||
test,
|
test,
|
||||||
baseline,
|
baseline,
|
||||||
|
|
@ -385,24 +370,7 @@ const scenarios = [
|
||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
const baseOutputPath = path.join(__dirname, "js", "benchmark");
|
function getStackTrace(belowFn) {
|
||||||
|
|
||||||
const withCodSpeed = async (/** @type {import("tinybench").Bench} */ bench) => {
|
|
||||||
const { Measurement, getGitDir, mongoMeasurement, setupCore, teardownCore } =
|
|
||||||
await import("@codspeed/core");
|
|
||||||
|
|
||||||
if (!Measurement.isInstrumented()) {
|
|
||||||
const rawRun = bench.run;
|
|
||||||
bench.run = async () => {
|
|
||||||
console.warn(
|
|
||||||
`[CodSpeed] ${bench.tasks.length} benches detected but no instrumentation found, falling back to tinybench`
|
|
||||||
);
|
|
||||||
return await rawRun.bind(bench)();
|
|
||||||
};
|
|
||||||
return bench;
|
|
||||||
}
|
|
||||||
|
|
||||||
const getStackTrace = (belowFn) => {
|
|
||||||
const oldLimit = Error.stackTraceLimit;
|
const oldLimit = Error.stackTraceLimit;
|
||||||
Error.stackTraceLimit = Infinity;
|
Error.stackTraceLimit = Infinity;
|
||||||
const dummyObject = {};
|
const dummyObject = {};
|
||||||
|
|
@ -413,9 +381,9 @@ const withCodSpeed = async (/** @type {import("tinybench").Bench} */ bench) => {
|
||||||
Error.prepareStackTrace = v8Handler;
|
Error.prepareStackTrace = v8Handler;
|
||||||
Error.stackTraceLimit = oldLimit;
|
Error.stackTraceLimit = oldLimit;
|
||||||
return v8StackTrace;
|
return v8StackTrace;
|
||||||
};
|
}
|
||||||
|
|
||||||
const getCallingFile = () => {
|
function getCallingFile() {
|
||||||
const stack = getStackTrace();
|
const stack = getStackTrace();
|
||||||
let callingFile = stack[2].getFileName(); // [here, withCodSpeed, actual caller]
|
let callingFile = stack[2].getFileName(); // [here, withCodSpeed, actual caller]
|
||||||
const gitDir = getGitDir(callingFile);
|
const gitDir = getGitDir(callingFile);
|
||||||
|
|
@ -426,64 +394,215 @@ const withCodSpeed = async (/** @type {import("tinybench").Bench} */ bench) => {
|
||||||
callingFile = fileURLToPath(callingFile);
|
callingFile = fileURLToPath(callingFile);
|
||||||
}
|
}
|
||||||
return path.relative(gitDir, callingFile);
|
return path.relative(gitDir, callingFile);
|
||||||
};
|
}
|
||||||
|
|
||||||
|
const taskUriMap = new WeakMap();
|
||||||
|
|
||||||
|
function getOrCreateUriMap(bench) {
|
||||||
|
let uriMap = taskUriMap.get(bench);
|
||||||
|
if (!uriMap) {
|
||||||
|
uriMap = new Map();
|
||||||
|
taskUriMap.set(bench, uriMap);
|
||||||
|
}
|
||||||
|
return uriMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
function getTaskUri(bench, taskName, rootCallingFile) {
|
||||||
|
const uriMap = taskUriMap.get(bench);
|
||||||
|
return uriMap?.get(taskName) || `${rootCallingFile}::${taskName}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
const withCodSpeed = async (/** @type {import("tinybench").Bench} */ bench) => {
|
||||||
|
const codspeedRunnerMode = getCodspeedRunnerMode();
|
||||||
|
|
||||||
|
if (codspeedRunnerMode === "disabled") {
|
||||||
|
return bench;
|
||||||
|
}
|
||||||
|
|
||||||
const rawAdd = bench.add;
|
const rawAdd = bench.add;
|
||||||
|
const uriMap = getOrCreateUriMap(bench);
|
||||||
bench.add = (name, fn, opts) => {
|
bench.add = (name, fn, opts) => {
|
||||||
const callingFile = getCallingFile();
|
const callingFile = getCallingFile();
|
||||||
const uri = `${callingFile}::${name}`;
|
let uri = callingFile;
|
||||||
const options = { ...opts, uri };
|
if (bench.name !== undefined) {
|
||||||
return rawAdd.bind(bench)(name, fn, options);
|
uri += `::${bench.name}`;
|
||||||
|
}
|
||||||
|
uri += `::${name}`;
|
||||||
|
uriMap.set(name, uri);
|
||||||
|
return rawAdd.bind(bench)(name, fn, opts);
|
||||||
};
|
};
|
||||||
const rootCallingFile = getCallingFile();
|
const rootCallingFile = getCallingFile();
|
||||||
bench.run = async function run() {
|
|
||||||
const iterations = bench.opts.iterations - 1;
|
if (codspeedRunnerMode === "instrumented") {
|
||||||
console.log("[CodSpeed] running");
|
const setupBenchRun = () => {
|
||||||
setupCore();
|
setupCore();
|
||||||
for (const task of bench.tasks) {
|
console.log(
|
||||||
await bench.opts.setup?.(task, "run");
|
"[CodSpeed] running with @codspeed/tinybench (instrumented mode)"
|
||||||
await task.fnOpts.beforeAll?.call(task);
|
);
|
||||||
const samples = [];
|
};
|
||||||
async function iteration() {
|
const finalizeBenchRun = () => {
|
||||||
|
teardownCore();
|
||||||
|
console.log(`[CodSpeed] Done running ${bench.tasks.length} benches.`);
|
||||||
|
return bench.tasks;
|
||||||
|
};
|
||||||
|
|
||||||
|
const wrapFunctionWithFrame = (fn, isAsync) => {
|
||||||
|
if (isAsync) {
|
||||||
|
return async function __codspeed_root_frame__() {
|
||||||
|
await fn();
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return function __codspeed_root_frame__() {
|
||||||
|
fn();
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
const logTaskCompletion = (uri, status) => {
|
||||||
|
console.log(`[CodSpeed] ${status} ${uri}`);
|
||||||
|
};
|
||||||
|
|
||||||
|
const taskCompletionMessage = () =>
|
||||||
|
InstrumentHooks.isInstrumented() ? "Measured" : "Checked";
|
||||||
|
|
||||||
|
const iterationAsync = async (task) => {
|
||||||
try {
|
try {
|
||||||
await task.fnOpts.beforeEach?.call(task, "run");
|
await task.fnOpts.beforeEach?.call(task, "run");
|
||||||
const start = bench.opts.now();
|
const start = bench.opts.now();
|
||||||
await task.fn();
|
await task.fn();
|
||||||
samples.push(bench.opts.now() - start || 0);
|
const end = bench.opts.now() - start || 0;
|
||||||
await task.fnOpts.afterEach?.call(this, "run");
|
await task.fnOpts.afterEach?.call(this, "run");
|
||||||
|
return [start, end];
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
if (bench.opts.throws) {
|
if (bench.opts.throws) {
|
||||||
throw err;
|
throw err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
while (samples.length < iterations) {
|
|
||||||
await iteration();
|
|
||||||
}
|
|
||||||
// Codspeed Measure
|
|
||||||
const uri =
|
|
||||||
task.opts && "uri" in task.options
|
|
||||||
? task.opts.uri
|
|
||||||
: `${rootCallingFile}::${task.name}`;
|
|
||||||
await task.fnOpts.beforeEach?.call(task);
|
|
||||||
await mongoMeasurement.start(uri);
|
|
||||||
await (async function __codspeed_root_frame__() {
|
|
||||||
Measurement.startInstrumentation();
|
|
||||||
await task.fn();
|
|
||||||
Measurement.stopInstrumentation(uri);
|
|
||||||
})();
|
|
||||||
await mongoMeasurement.stop(uri);
|
|
||||||
await task.fnOpts.afterEach?.call(task);
|
|
||||||
console.log(`[Codspeed] ✔ Measured ${uri}`);
|
|
||||||
await task.fnOpts.afterAll?.call(task);
|
|
||||||
|
|
||||||
await bench.opts.teardown?.(task, "run");
|
|
||||||
task.processRunResult({ latencySamples: samples });
|
|
||||||
}
|
|
||||||
teardownCore();
|
|
||||||
console.log(`[CodSpeed] Done running ${bench.tasks.length} benches.`);
|
|
||||||
return bench.tasks;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const wrapWithInstrumentHooksAsync = async (fn, uri) => {
|
||||||
|
InstrumentHooks.startBenchmark();
|
||||||
|
const result = await fn();
|
||||||
|
InstrumentHooks.stopBenchmark();
|
||||||
|
InstrumentHooks.setExecutedBenchmark(process.pid, uri);
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
|
const runTaskAsync = async (task, uri) => {
|
||||||
|
const { fnOpts, fn } = task;
|
||||||
|
|
||||||
|
// Custom setup
|
||||||
|
await bench.opts.setup?.(task, "run");
|
||||||
|
|
||||||
|
await fnOpts?.beforeAll?.call(task, "run");
|
||||||
|
|
||||||
|
// Custom warmup
|
||||||
|
// We don't run `optimizeFunction` because our function is never optimized, instead we just warmup webpack
|
||||||
|
const samples = [];
|
||||||
|
|
||||||
|
while (samples.length < bench.opts.iterations - 1) {
|
||||||
|
samples.push(await iterationAsync(task));
|
||||||
|
}
|
||||||
|
|
||||||
|
await fnOpts?.beforeEach?.call(task, "run");
|
||||||
|
await mongoMeasurement.start(uri);
|
||||||
|
global.gc?.();
|
||||||
|
await wrapWithInstrumentHooksAsync(wrapFunctionWithFrame(fn, true), uri);
|
||||||
|
await mongoMeasurement.stop(uri);
|
||||||
|
await fnOpts?.afterEach?.call(task, "run");
|
||||||
|
console.log(`[Codspeed] ✔ Measured ${uri}`);
|
||||||
|
await fnOpts?.afterAll?.call(task, "run");
|
||||||
|
|
||||||
|
// Custom teardown
|
||||||
|
await bench.opts.teardown?.(task, "run");
|
||||||
|
|
||||||
|
logTaskCompletion(uri, taskCompletionMessage());
|
||||||
|
};
|
||||||
|
|
||||||
|
const iteration = (task) => {
|
||||||
|
try {
|
||||||
|
task.fnOpts.beforeEach?.call(task, "run");
|
||||||
|
const start = bench.opts.now();
|
||||||
|
task.fn();
|
||||||
|
const end = bench.opts.now() - start || 0;
|
||||||
|
task.fnOpts.afterEach?.call(this, "run");
|
||||||
|
return [start, end];
|
||||||
|
} catch (err) {
|
||||||
|
if (bench.opts.throws) {
|
||||||
|
throw err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const wrapWithInstrumentHooks = (fn, uri) => {
|
||||||
|
InstrumentHooks.startBenchmark();
|
||||||
|
const result = fn();
|
||||||
|
InstrumentHooks.stopBenchmark();
|
||||||
|
InstrumentHooks.setExecutedBenchmark(process.pid, uri);
|
||||||
|
return result;
|
||||||
|
};
|
||||||
|
|
||||||
|
const runTaskSync = (task, uri) => {
|
||||||
|
const { fnOpts, fn } = task;
|
||||||
|
|
||||||
|
// Custom setup
|
||||||
|
bench.opts.setup?.(task, "run");
|
||||||
|
|
||||||
|
fnOpts?.beforeAll?.call(task, "run");
|
||||||
|
|
||||||
|
// Custom warmup
|
||||||
|
const samples = [];
|
||||||
|
|
||||||
|
while (samples.length < bench.opts.iterations - 1) {
|
||||||
|
samples.push(iteration(task));
|
||||||
|
}
|
||||||
|
|
||||||
|
fnOpts?.beforeEach?.call(task, "run");
|
||||||
|
|
||||||
|
wrapWithInstrumentHooks(wrapFunctionWithFrame(fn, false), uri);
|
||||||
|
|
||||||
|
fnOpts?.afterEach?.call(task, "run");
|
||||||
|
console.log(`[Codspeed] ✔ Measured ${uri}`);
|
||||||
|
fnOpts?.afterAll?.call(task, "run");
|
||||||
|
|
||||||
|
// Custom teardown
|
||||||
|
bench.opts.teardown?.(task, "run");
|
||||||
|
|
||||||
|
logTaskCompletion(uri, taskCompletionMessage());
|
||||||
|
};
|
||||||
|
|
||||||
|
const finalizeAsyncRun = () => {
|
||||||
|
finalizeBenchRun();
|
||||||
|
};
|
||||||
|
const finalizeSyncRun = () => {
|
||||||
|
finalizeBenchRun();
|
||||||
|
};
|
||||||
|
|
||||||
|
bench.run = async () => {
|
||||||
|
setupBenchRun();
|
||||||
|
|
||||||
|
for (const task of bench.tasks) {
|
||||||
|
const uri = getTaskUri(task.bench, task.name, rootCallingFile);
|
||||||
|
await runTaskAsync(task, uri);
|
||||||
|
}
|
||||||
|
|
||||||
|
return finalizeAsyncRun();
|
||||||
|
};
|
||||||
|
|
||||||
|
bench.runSync = () => {
|
||||||
|
setupBenchRun();
|
||||||
|
|
||||||
|
for (const task of bench.tasks) {
|
||||||
|
const uri = getTaskUri(task.bench, task.name, rootCallingFile);
|
||||||
|
runTaskSync(task, uri);
|
||||||
|
}
|
||||||
|
|
||||||
|
return finalizeSyncRun();
|
||||||
|
};
|
||||||
|
} else if (codspeedRunnerMode === "walltime") {
|
||||||
|
// We don't need it
|
||||||
|
}
|
||||||
|
|
||||||
return bench;
|
return bench;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -495,7 +614,6 @@ const bench = await withCodSpeed(
|
||||||
warmupIterations: 2,
|
warmupIterations: 2,
|
||||||
iterations: 8,
|
iterations: 8,
|
||||||
setup(task, mode) {
|
setup(task, mode) {
|
||||||
global.gc();
|
|
||||||
console.log(`Setup (${mode} mode): ${task.name}`);
|
console.log(`Setup (${mode} mode): ${task.name}`);
|
||||||
},
|
},
|
||||||
teardown(task, mode) {
|
teardown(task, mode) {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
file
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
import fs from "fs";
|
||||||
|
import path from "path";
|
||||||
|
import url from "../../asset-modules/_images/file.png";
|
||||||
|
|
||||||
|
import(/* webpackChunkName: 'file' */ "./file.txt?foo");
|
||||||
|
|
||||||
|
it("should emit manifest with expected entries and paths", () => {
|
||||||
|
expect(url).toEqual("/app/file-loader.png");
|
||||||
|
|
||||||
|
const manifest = JSON.parse(
|
||||||
|
fs.readFileSync(path.resolve(__dirname, "test.json"), "utf-8")
|
||||||
|
);
|
||||||
|
|
||||||
|
const keys = Object.keys(manifest).sort();
|
||||||
|
expect(keys).toEqual(
|
||||||
|
[
|
||||||
|
"file.js",
|
||||||
|
"file.txt?foo",
|
||||||
|
"main.js",
|
||||||
|
"third.party.js",
|
||||||
|
"file.png"
|
||||||
|
].sort()
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(manifest["main.js"]).toMatch(/\/app\/bundle0\.js/);
|
||||||
|
expect(manifest["file.js"]).toMatch(/\/app\/file\.[a-f0-9]+\.js/);
|
||||||
|
expect(manifest["file.txt?foo"]).toMatch(/\/app\/file\.[a-f0-9]+\.txt\?foo/);
|
||||||
|
expect(manifest["third.party.js"]).toBe("/app/third.party.js");
|
||||||
|
expect(manifest["file.png"]).toBe("/app/file-loader.png");
|
||||||
|
});
|
||||||
|
|
@ -0,0 +1,7 @@
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
module.exports = [
|
||||||
|
// each time returns different OriginalSource in webpack.config.js:33
|
||||||
|
// this prevents hit in inmemory cache
|
||||||
|
/^Pack got invalid because of write to: RealContentHashPlugin|analyse|third.party.js$/
|
||||||
|
];
|
||||||
|
|
@ -0,0 +1,61 @@
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
const { RawSource } = require("webpack-sources");
|
||||||
|
const webpack = require("../../../../");
|
||||||
|
|
||||||
|
/** @typedef {import("../../../../lib/Compiler")} Compiler */
|
||||||
|
|
||||||
|
class CopyPlugin {
|
||||||
|
/**
|
||||||
|
* Apply the plugin
|
||||||
|
* @param {Compiler} compiler the compiler instance
|
||||||
|
* @returns {void}
|
||||||
|
*/
|
||||||
|
apply(compiler) {
|
||||||
|
const hookOptions = {
|
||||||
|
name: "MockCopyPlugin",
|
||||||
|
stage: webpack.Compilation.PROCESS_ASSETS_STAGE_ADDITIONS
|
||||||
|
};
|
||||||
|
|
||||||
|
compiler.hooks.thisCompilation.tap(hookOptions, (compilation) => {
|
||||||
|
compilation.hooks.processAssets.tap(hookOptions, () => {
|
||||||
|
const output = "// some compilation result\n";
|
||||||
|
compilation.emitAsset("third.party.js", new RawSource(output));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/** @type {import("../../../../").Configuration} */
|
||||||
|
module.exports = {
|
||||||
|
node: {
|
||||||
|
__dirname: false,
|
||||||
|
__filename: false
|
||||||
|
},
|
||||||
|
output: {
|
||||||
|
publicPath: "/app/",
|
||||||
|
chunkFilename: "[name].[contenthash].js",
|
||||||
|
assetModuleFilename: "[name].[contenthash][ext][query]"
|
||||||
|
},
|
||||||
|
plugins: [
|
||||||
|
new CopyPlugin(),
|
||||||
|
new webpack.ManifestPlugin({
|
||||||
|
filename: "test.json"
|
||||||
|
})
|
||||||
|
],
|
||||||
|
module: {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
test: /\.txt$/,
|
||||||
|
type: "asset/resource"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /\.png$/,
|
||||||
|
loader: "file-loader",
|
||||||
|
options: {
|
||||||
|
name: "file-loader.[ext]"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
"use strict";
|
"use strict";
|
||||||
|
|
||||||
module.exports = [
|
module.exports = [
|
||||||
// each time returns different OriginalSource in webpack.config.js:78
|
// each time returns different OriginalSource in webpack.config.js:108
|
||||||
// this prevents hit in inmemory cache
|
// this prevents hit in inmemory cache
|
||||||
/^Pack got invalid because of write to: RealContentHashPlugin|analyse|index\.html$/
|
/^Pack got invalid because of write to: RealContentHashPlugin|analyse|index\.html$/
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -8195,8 +8195,6 @@ declare class JavascriptParser extends ParserClass {
|
||||||
* Parser options for javascript modules.
|
* Parser options for javascript modules.
|
||||||
*/
|
*/
|
||||||
declare interface JavascriptParserOptions {
|
declare interface JavascriptParserOptions {
|
||||||
[index: string]: any;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the value of `require.amd` and `define.amd`. Or disable AMD support.
|
* Set the value of `require.amd` and `define.amd`. Or disable AMD support.
|
||||||
*/
|
*/
|
||||||
|
|
@ -9892,6 +9890,29 @@ declare interface MakeDirectoryOptions {
|
||||||
recursive?: boolean;
|
recursive?: boolean;
|
||||||
mode?: string | number;
|
mode?: string | number;
|
||||||
}
|
}
|
||||||
|
declare class ManifestPlugin {
|
||||||
|
constructor(options: ManifestPluginOptions);
|
||||||
|
options: Required<ManifestPluginOptions>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Apply the plugin
|
||||||
|
*/
|
||||||
|
apply(compiler: Compiler): void;
|
||||||
|
}
|
||||||
|
declare interface ManifestPluginOptions {
|
||||||
|
/**
|
||||||
|
* Specifies the filename of the output file on disk. By default the plugin will emit `manifest.json` inside the 'output.path' directory.
|
||||||
|
*/
|
||||||
|
filename?: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A custom Function to create the manifest.
|
||||||
|
*/
|
||||||
|
handle?: (
|
||||||
|
manifest: Record<string, string>,
|
||||||
|
stats: StatsCompilation
|
||||||
|
) => string;
|
||||||
|
}
|
||||||
declare interface MapOptions {
|
declare interface MapOptions {
|
||||||
/**
|
/**
|
||||||
* need columns?
|
* need columns?
|
||||||
|
|
@ -19271,6 +19292,7 @@ declare namespace exports {
|
||||||
EntryPlugin as SingleEntryPlugin,
|
EntryPlugin as SingleEntryPlugin,
|
||||||
SourceMapDevToolPlugin,
|
SourceMapDevToolPlugin,
|
||||||
Stats,
|
Stats,
|
||||||
|
ManifestPlugin,
|
||||||
Template,
|
Template,
|
||||||
WatchIgnorePlugin,
|
WatchIgnorePlugin,
|
||||||
WebpackError,
|
WebpackError,
|
||||||
|
|
|
||||||
12
yarn.lock
12
yarn.lock
|
|
@ -332,14 +332,14 @@
|
||||||
resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39"
|
resolved "https://registry.yarnpkg.com/@bcoe/v8-coverage/-/v8-coverage-0.2.3.tgz#75a2e8b51cb758a7553d6804a5932d7aace75c39"
|
||||||
integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==
|
integrity sha512-0hYQ8SB4Db5zvZB4axdMHGwEaQjkZzFjQiN9LVYvIFB2nSUHW9tYpxWriPrWDASIxiaXax83REcLxuSdnGPZtw==
|
||||||
|
|
||||||
"@codspeed/core@^4.0.1":
|
"@codspeed/core@^5.0.1":
|
||||||
version "4.0.1"
|
version "5.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/@codspeed/core/-/core-4.0.1.tgz#91049cce17b8c1d1b4b6cbc481f5ddc1145d6e1e"
|
resolved "https://registry.yarnpkg.com/@codspeed/core/-/core-5.0.1.tgz#6145c898a86a6d56a169611c3e9657a8b97c7642"
|
||||||
integrity sha512-fJ53arfgtzCDZa8DuGJhpTZ3Ll9A1uW5nQ2jSJnfO4Hl5MRD2cP8P4vPvIUAGbdbjwCxR1jat6cW8OloMJkJXw==
|
integrity sha512-4g5ZyFAin8QywK4+0FK1uXG3GLRPu0oc3xbP+7OUhhFxbwpzFuaJtKmnTofMqLy9/pHH6Bl/7H0/DTVH3cpFkA==
|
||||||
dependencies:
|
dependencies:
|
||||||
axios "^1.4.0"
|
axios "^1.4.0"
|
||||||
find-up "^6.3.0"
|
find-up "^6.3.0"
|
||||||
form-data "^4.0.0"
|
form-data "^4.0.4"
|
||||||
node-gyp-build "^4.6.0"
|
node-gyp-build "^4.6.0"
|
||||||
|
|
||||||
"@cspell/cspell-bundled-dicts@9.1.3":
|
"@cspell/cspell-bundled-dicts@9.1.3":
|
||||||
|
|
@ -3878,7 +3878,7 @@ fork-ts-checker-webpack-plugin@^9.0.2:
|
||||||
semver "^7.3.5"
|
semver "^7.3.5"
|
||||||
tapable "^2.2.1"
|
tapable "^2.2.1"
|
||||||
|
|
||||||
form-data@^4.0.0, form-data@^4.0.4:
|
form-data@^4.0.4:
|
||||||
version "4.0.4"
|
version "4.0.4"
|
||||||
resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.4.tgz#784cdcce0669a9d68e94d11ac4eea98088edd2c4"
|
resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.4.tgz#784cdcce0669a9d68e94d11ac4eea98088edd2c4"
|
||||||
integrity sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==
|
integrity sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue