Compare commits

...

7 Commits

Author SHA1 Message Date
hai-x b3950567f6
Merge 5197fd7f03 into 3c08fd105c 2025-09-30 23:10:01 +08:00
Kevin Brey 3c08fd105c
fix(warnings): update import.meta warning messages for clarity (#19961)
Github Actions / lint (push) Waiting to run Details
Github Actions / validate-legacy-node (push) Waiting to run Details
Github Actions / benchmark (1/4) (push) Waiting to run Details
Github Actions / benchmark (2/4) (push) Waiting to run Details
Github Actions / benchmark (3/4) (push) Waiting to run Details
Github Actions / benchmark (4/4) (push) Waiting to run Details
Github Actions / basic (push) Waiting to run Details
Github Actions / unit (push) Waiting to run Details
Github Actions / integration (10.x, macos-latest, a) (push) Blocked by required conditions Details
Github Actions / integration (10.x, macos-latest, b) (push) Blocked by required conditions Details
Github Actions / integration (10.x, ubuntu-latest, a) (push) Blocked by required conditions Details
Github Actions / integration (10.x, ubuntu-latest, b) (push) Blocked by required conditions Details
Github Actions / integration (10.x, windows-latest, a) (push) Blocked by required conditions Details
Github Actions / integration (10.x, windows-latest, b) (push) Blocked by required conditions Details
Github Actions / integration (12.x, ubuntu-latest, a) (push) Blocked by required conditions Details
Github Actions / integration (14.x, ubuntu-latest, a) (push) Blocked by required conditions Details
Github Actions / integration (16.x, ubuntu-latest, a) (push) Blocked by required conditions Details
Github Actions / integration (18.x, ubuntu-latest, a) (push) Blocked by required conditions Details
Github Actions / integration (20.x, macos-latest, a) (push) Blocked by required conditions Details
Github Actions / integration (20.x, macos-latest, b) (push) Blocked by required conditions Details
Github Actions / integration (20.x, ubuntu-latest, a) (push) Blocked by required conditions Details
Github Actions / integration (20.x, ubuntu-latest, b) (push) Blocked by required conditions Details
Github Actions / integration (20.x, windows-latest, a) (push) Blocked by required conditions Details
Github Actions / integration (20.x, windows-latest, b) (push) Blocked by required conditions Details
Github Actions / integration (22.x, macos-latest, a) (push) Blocked by required conditions Details
Github Actions / integration (22.x, macos-latest, b) (push) Blocked by required conditions Details
Github Actions / integration (22.x, ubuntu-latest, a) (push) Blocked by required conditions Details
Github Actions / integration (22.x, ubuntu-latest, b) (push) Blocked by required conditions Details
Github Actions / integration (22.x, windows-latest, a) (push) Blocked by required conditions Details
Github Actions / integration (22.x, windows-latest, b) (push) Blocked by required conditions Details
Github Actions / integration (24.x, macos-latest, a) (push) Blocked by required conditions Details
Github Actions / integration (24.x, macos-latest, b) (push) Blocked by required conditions Details
Github Actions / integration (24.x, ubuntu-latest, a) (push) Blocked by required conditions Details
Github Actions / integration (24.x, ubuntu-latest, b) (push) Blocked by required conditions Details
Github Actions / integration (24.x, windows-latest, a) (push) Blocked by required conditions Details
Github Actions / integration (24.x, windows-latest, b) (push) Blocked by required conditions Details
Github Actions / integration (lts/*, ubuntu-latest, a, 1) (push) Blocked by required conditions Details
Github Actions / integration (lts/*, ubuntu-latest, b, 1) (push) Blocked by required conditions Details
2025-09-30 17:32:35 +03:00
Alexander Akait f508e8b705
chore: pin memfs for old node.js version (#19963) 2025-09-30 17:32:09 +03:00
Alexander Akait 5c11f27b6b
chore(deps): update (#19960)
Github Actions / lint (push) Waiting to run Details
Github Actions / validate-legacy-node (push) Waiting to run Details
Github Actions / benchmark (1/4) (push) Waiting to run Details
Github Actions / benchmark (2/4) (push) Waiting to run Details
Github Actions / benchmark (3/4) (push) Waiting to run Details
Github Actions / benchmark (4/4) (push) Waiting to run Details
Github Actions / basic (push) Waiting to run Details
Github Actions / unit (push) Waiting to run Details
Github Actions / integration (10.x, macos-latest, a) (push) Blocked by required conditions Details
Github Actions / integration (10.x, macos-latest, b) (push) Blocked by required conditions Details
Github Actions / integration (10.x, ubuntu-latest, a) (push) Blocked by required conditions Details
Github Actions / integration (10.x, ubuntu-latest, b) (push) Blocked by required conditions Details
Github Actions / integration (10.x, windows-latest, a) (push) Blocked by required conditions Details
Github Actions / integration (10.x, windows-latest, b) (push) Blocked by required conditions Details
Github Actions / integration (12.x, ubuntu-latest, a) (push) Blocked by required conditions Details
Github Actions / integration (14.x, ubuntu-latest, a) (push) Blocked by required conditions Details
Github Actions / integration (16.x, ubuntu-latest, a) (push) Blocked by required conditions Details
Github Actions / integration (18.x, ubuntu-latest, a) (push) Blocked by required conditions Details
Github Actions / integration (20.x, macos-latest, a) (push) Blocked by required conditions Details
Github Actions / integration (20.x, macos-latest, b) (push) Blocked by required conditions Details
Github Actions / integration (20.x, ubuntu-latest, a) (push) Blocked by required conditions Details
Github Actions / integration (20.x, ubuntu-latest, b) (push) Blocked by required conditions Details
Github Actions / integration (20.x, windows-latest, a) (push) Blocked by required conditions Details
Github Actions / integration (20.x, windows-latest, b) (push) Blocked by required conditions Details
Github Actions / integration (22.x, macos-latest, a) (push) Blocked by required conditions Details
Github Actions / integration (22.x, macos-latest, b) (push) Blocked by required conditions Details
Github Actions / integration (22.x, ubuntu-latest, a) (push) Blocked by required conditions Details
Github Actions / integration (22.x, ubuntu-latest, b) (push) Blocked by required conditions Details
Github Actions / integration (22.x, windows-latest, a) (push) Blocked by required conditions Details
Github Actions / integration (22.x, windows-latest, b) (push) Blocked by required conditions Details
Github Actions / integration (24.x, macos-latest, a) (push) Blocked by required conditions Details
Github Actions / integration (24.x, macos-latest, b) (push) Blocked by required conditions Details
Github Actions / integration (24.x, ubuntu-latest, a) (push) Blocked by required conditions Details
Github Actions / integration (24.x, ubuntu-latest, b) (push) Blocked by required conditions Details
Github Actions / integration (24.x, windows-latest, a) (push) Blocked by required conditions Details
Github Actions / integration (24.x, windows-latest, b) (push) Blocked by required conditions Details
Github Actions / integration (lts/*, ubuntu-latest, a, 1) (push) Blocked by required conditions Details
Github Actions / integration (lts/*, ubuntu-latest, b, 1) (push) Blocked by required conditions Details
2025-09-30 12:55:30 +03:00
Hai 5197fd7f03 fix: review 2025-09-22 02:58:31 +08:00
Hai a51d2349ee fix: lint 2025-09-15 00:44:05 +08:00
Hai 81268133cd feat: port webpack-manifest-plugin 2025-09-15 00:30:46 +08:00
26 changed files with 1052 additions and 354 deletions

View File

@ -214,7 +214,7 @@ jobs:
# Install old `jest` version and deps for legacy node versions
- run: |
yarn upgrade jest@^27.5.0 jest-circus@^27.5.0 jest-cli@^27.5.0 jest-diff@^27.5.0 jest-environment-node@^27.5.0 jest-junit@^13.0.0 @types/jest@^27.4.0 pretty-format@^27.0.2 husky@^8.0.3 lint-staged@^13.2.1 cspell@^6.31.1 open-cli@^7.2.0 coffee-loader@^1.0.0 babel-loader@^8.1.0 style-loader@^2.0.0 css-loader@^5.0.1 less-loader@^8.1.1 mini-css-extract-plugin@^1.6.1 nyc@^15.1.0 --ignore-engines
yarn upgrade jest@^27.5.0 jest-circus@^27.5.0 jest-cli@^27.5.0 jest-diff@^27.5.0 jest-environment-node@^27.5.0 jest-junit@^13.0.0 @types/jest@^27.4.0 pretty-format@^27.0.2 husky@^8.0.3 lint-staged@^13.2.1 cspell@^6.31.1 open-cli@^7.2.0 coffee-loader@^1.0.0 babel-loader@^8.1.0 style-loader@^2.0.0 css-loader@^5.0.1 less-loader@^8.1.1 mini-css-extract-plugin@^1.6.1 nyc@^15.1.0 memfs@4.14.0 --ignore-engines
yarn --frozen-lockfile --ignore-engines
if: matrix.node-version == '10.x' || matrix.node-version == '12.x' || matrix.node-version == '14.x'

View File

@ -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;
}

View File

@ -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
```

View File

@ -0,0 +1 @@
bar

View File

@ -0,0 +1,4 @@
import foo from "./foo.txt";
import bar from "./bar.txt";
export default foo + bar;

View File

@ -0,0 +1 @@
require("../build-common");

View File

@ -0,0 +1 @@
import("./baz");

View File

@ -0,0 +1 @@
foo

View File

@ -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}}_
```

View File

@ -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;
}
})
]
};

View File

@ -115,7 +115,7 @@ class ImportMetaPlugin {
new ModuleDependencyWarning(
parser.state.module,
new CriticalDependencyWarning(
"Accessing import.meta directly is unsupported (only property access or destructuring is supported)"
"'import.meta' cannot be used as a standalone expression. For static analysis, its properties must be accessed directly (e.g., 'import.meta.url') or through destructuring."
),
/** @type {DependencyLocation} */ (metaProperty.loc)
)

View File

@ -355,6 +355,9 @@ module.exports = mergeExports(fn, {
get Stats() {
return require("./Stats");
},
get ManifestPlugin() {
return require("./stats/ManifestPlugin");
},
get Template() {
return require("./Template");
},

180
lib/stats/ManifestPlugin.js Normal file
View File

@ -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;

View File

@ -111,16 +111,16 @@
"@babel/core": "^7.27.1",
"@babel/preset-react": "^7.27.1",
"@codspeed/core": "^4.0.1",
"@eslint/js": "^9.29.0",
"@eslint/markdown": "^7.1.0",
"@stylistic/eslint-plugin": "^5.2.2",
"@eslint/js": "^9.36.0",
"@eslint/markdown": "^7.3.0",
"@stylistic/eslint-plugin": "^5.4.0",
"@types/glob-to-regexp": "^0.4.4",
"@types/graceful-fs": "^4.1.9",
"@types/jest": "^30.0.0",
"@types/mime-types": "^2.1.4",
"@types/node": "^24.1.0",
"@types/node": "^24.5.2",
"@types/xxhashjs": "^0.2.4",
"assemblyscript": "^0.28.5",
"assemblyscript": "^0.28.8",
"babel-loader": "^10.0.0",
"bundle-loader": "^0.5.6",
"coffee-loader": "^5.0.0",
@ -131,13 +131,13 @@
"date-fns": "^4.0.0",
"es5-ext": "^0.10.53",
"es6-promise-polyfill": "^1.2.0",
"eslint": "^9.29.0",
"eslint": "^9.36.0",
"eslint-config-prettier": "^10.1.1",
"eslint-config-webpack": "^4.5.1",
"eslint-plugin-import": "^2.32.0",
"eslint-plugin-jest": "^29.0.1",
"eslint-plugin-jsdoc": "^51.2.3",
"eslint-plugin-n": "^17.21.0",
"eslint-plugin-n": "^17.23.1",
"eslint-plugin-prettier": "^5.5.0",
"eslint-plugin-unicorn": "^61.0.1",
"file-loader": "^6.0.0",
@ -146,11 +146,11 @@
"hash-wasm": "^4.9.0",
"husky": "^9.0.11",
"istanbul": "^0.4.5",
"jest": "^30.1.2",
"jest-circus": "^30.1.2",
"jest-cli": "^30.1.2",
"jest-diff": "^30.1.2",
"jest-environment-node": "^30.1.2",
"jest": "^30.2.0",
"jest-circus": "^30.2.0",
"jest-cli": "^30.2.0",
"jest-diff": "^30.2.0",
"jest-environment-node": "^30.2.0",
"jest-junit": "^16.0.0",
"json-loader": "^0.5.7",
"json5": "^2.1.3",

View File

@ -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;

View File

@ -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;

View File

@ -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)"
}
}
}

View File

@ -1,3 +1,7 @@
"use strict";
module.exports = [[/Critical dependency: Accessing import\.meta/]];
module.exports = [
[
/Critical dependency: 'import\.meta' cannot be used as a standalone expression\. For static analysis, its properties must be accessed directly \(e\.g\., 'import\.meta\.url'\) or through destructuring\./
]
];

View File

@ -2,6 +2,6 @@
module.exports = [
[
/Accessing import.meta directly is unsupported \(only property access or destructuring is supported\)/
/'import\.meta' cannot be used as a standalone expression\. For static analysis, its properties must be accessed directly \(e\.g\., 'import\.meta\.url'\) or through destructuring\./
]
];

View File

@ -0,0 +1 @@
file

View 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");
});

View File

@ -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$/
];

View File

@ -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]"
}
}
]
}
};

View File

@ -1,7 +1,7 @@
"use strict";
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
/^Pack got invalid because of write to: RealContentHashPlugin|analyse|index\.html$/
];

24
types.d.ts vendored
View File

@ -9789,6 +9789,29 @@ declare interface MakeDirectoryOptions {
recursive?: boolean;
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 {
/**
* need columns?
@ -18950,6 +18973,7 @@ declare namespace exports {
EntryPlugin as SingleEntryPlugin,
SourceMapDevToolPlugin,
Stats,
ManifestPlugin,
Template,
WatchIgnorePlugin,
WebpackError,

762
yarn.lock

File diff suppressed because it is too large Load Diff