mirror of https://github.com/webpack/webpack.git
Compare commits
2 Commits
5197fd7f03
...
d4d787a922
| Author | SHA1 | Date |
|---|---|---|
|
|
d4d787a922 | |
|
|
dac300f09a |
|
|
@ -4,16 +4,35 @@
|
||||||
* Run `yarn fix:special` to update
|
* Run `yarn fix:special` to update
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A function that receives the manifest object and returns the manifest string.
|
||||||
|
*/
|
||||||
|
export type HandlerFunction = (manifest: ManifestObject) => string;
|
||||||
|
/**
|
||||||
|
* Maps asset identifiers to their manifest entries.
|
||||||
|
*/
|
||||||
|
export type ManifestObject = Record<string, ManifestItem>;
|
||||||
|
|
||||||
export interface ManifestPluginOptions {
|
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.
|
* Specifies the filename of the output file on disk. By default the plugin will emit `manifest.json` inside the 'output.path' directory.
|
||||||
*/
|
*/
|
||||||
filename?: string;
|
filename?: string;
|
||||||
/**
|
/**
|
||||||
* A custom Function to create the manifest.
|
* A function that receives the manifest object and returns the manifest string.
|
||||||
*/
|
*/
|
||||||
handle?: (
|
handler?: HandlerFunction;
|
||||||
manifest: Record<string, string>,
|
}
|
||||||
stats: import("../../lib/stats/DefaultStatsFactoryPlugin").StatsCompilation
|
/**
|
||||||
) => string;
|
* Describes a manifest entry that links the emitted path to the producing asset.
|
||||||
|
*/
|
||||||
|
export interface ManifestItem {
|
||||||
|
/**
|
||||||
|
* The compilation asset that produced this manifest entry.
|
||||||
|
*/
|
||||||
|
asset?: import("../../lib/Compilation").Asset;
|
||||||
|
/**
|
||||||
|
* The public path recorded in the manifest for this asset.
|
||||||
|
*/
|
||||||
|
filePath: string;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -55,11 +55,11 @@ module.exports = {
|
||||||
}),
|
}),
|
||||||
new webpack.ManifestPlugin({
|
new webpack.ManifestPlugin({
|
||||||
filename: "manifest.yml",
|
filename: "manifest.yml",
|
||||||
handle(manifest) {
|
handler(manifest) {
|
||||||
let _manifest = "";
|
let _manifest = "";
|
||||||
for (const key in manifest) {
|
for (const key in manifest) {
|
||||||
if (key === "manifest.json") continue;
|
if (key === "manifest.json") continue;
|
||||||
_manifest += `- ${key}: '${manifest[key]}'\n`;
|
_manifest += `- ${key}: '${manifest[key].filePath}'\n`;
|
||||||
}
|
}
|
||||||
return _manifest;
|
return _manifest;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,11 +23,11 @@ module.exports = {
|
||||||
}),
|
}),
|
||||||
new webpack.ManifestPlugin({
|
new webpack.ManifestPlugin({
|
||||||
filename: "manifest.yml",
|
filename: "manifest.yml",
|
||||||
handle(manifest) {
|
handler(manifest) {
|
||||||
let _manifest = "";
|
let _manifest = "";
|
||||||
for (const key in manifest) {
|
for (const key in manifest) {
|
||||||
if (key === "manifest.json") continue;
|
if (key === "manifest.json") continue;
|
||||||
_manifest += `- ${key}: '${manifest[key]}'\n`;
|
_manifest += `- ${key}: '${manifest[key].filePath}'\n`;
|
||||||
}
|
}
|
||||||
return _manifest;
|
return _manifest;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,25 +7,27 @@
|
||||||
|
|
||||||
const path = require("path");
|
const path = require("path");
|
||||||
const { RawSource } = require("webpack-sources");
|
const { RawSource } = require("webpack-sources");
|
||||||
const Compilation = require("../Compilation");
|
const Compilation = require("./Compilation");
|
||||||
const HotUpdateChunk = require("../HotUpdateChunk");
|
const HotUpdateChunk = require("./HotUpdateChunk");
|
||||||
const createSchemaValidation = require("../util/create-schema-validation");
|
const createSchemaValidation = require("./util/create-schema-validation");
|
||||||
|
|
||||||
/** @typedef {import("../Compiler")} Compiler */
|
/** @typedef {import("./Compiler")} Compiler */
|
||||||
/** @typedef {import("..").StatsCompilation} StatsCompilation */
|
/** @typedef {import("..").StatsCompilation} StatsCompilation */
|
||||||
/** @typedef {import("../Chunk")} Chunk */
|
/** @typedef {import("./Chunk")} Chunk */
|
||||||
/** @typedef {import("../Compilation").Asset} Asset */
|
/** @typedef {import("./Compilation").Asset} Asset */
|
||||||
/** @typedef {import("../Module")} Module */
|
/** @typedef {import("./Module")} Module */
|
||||||
/** @typedef {import("../NormalModule")} NormalModule */
|
/** @typedef {import("./NormalModule")} NormalModule */
|
||||||
/** @typedef {import("../config/defaults").WebpackOptionsNormalizedWithDefaults} WebpackOptions */
|
/** @typedef {import("./config/defaults").WebpackOptionsNormalizedWithDefaults} WebpackOptions */
|
||||||
|
|
||||||
/** @typedef {import("../../declarations/plugins/ManifestPlugin").ManifestPluginOptions} ManifestPluginOptions */
|
/** @typedef {import("../declarations/plugins/ManifestPlugin").ManifestPluginOptions} ManifestPluginOptions */
|
||||||
|
/** @typedef {import("../declarations/plugins/ManifestPlugin").ManifestObject} ManifestObject */
|
||||||
|
/** @typedef {import("../declarations/plugins/ManifestPlugin").ManifestItem} ManifestItem */
|
||||||
|
|
||||||
const PLUGIN_NAME = "ManifestPlugin";
|
const PLUGIN_NAME = "ManifestPlugin";
|
||||||
|
|
||||||
const validate = createSchemaValidation(
|
const validate = createSchemaValidation(
|
||||||
require("../../schemas/plugins/ManifestPlugin.check"),
|
require("../schemas/plugins/ManifestPlugin.check"),
|
||||||
() => require("../../schemas/plugins/ManifestPlugin.json"),
|
() => require("../schemas/plugins/ManifestPlugin.json"),
|
||||||
{
|
{
|
||||||
name: "ManifestPlugin",
|
name: "ManifestPlugin",
|
||||||
baseDataPath: "options"
|
baseDataPath: "options"
|
||||||
|
|
@ -41,7 +43,7 @@ const extname = (filename) => {
|
||||||
const split = replaced.split(".");
|
const split = replaced.split(".");
|
||||||
const last = split.pop();
|
const last = split.pop();
|
||||||
if (!last) return "";
|
if (!last) return "";
|
||||||
return last && /^(gz|map)$/i.test(last) ? `${split.pop()}.${last}` : last;
|
return last && /^(gz|br|map)$/i.test(last) ? `${split.pop()}.${last}` : last;
|
||||||
};
|
};
|
||||||
|
|
||||||
class ManifestPlugin {
|
class ManifestPlugin {
|
||||||
|
|
@ -54,20 +56,32 @@ class ManifestPlugin {
|
||||||
/** @type {Required<ManifestPluginOptions>} */
|
/** @type {Required<ManifestPluginOptions>} */
|
||||||
this.options = {
|
this.options = {
|
||||||
filename: "manifest.json",
|
filename: "manifest.json",
|
||||||
handle: (manifest, _stats) => JSON.stringify(manifest, null, 2),
|
handler: (manifest) => this._handleManifest(manifest),
|
||||||
...options
|
...options
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {ManifestObject} manifest manifest object
|
||||||
|
* @returns {string} manifest content
|
||||||
|
*/
|
||||||
|
_handleManifest(manifest) {
|
||||||
|
return JSON.stringify(
|
||||||
|
Object.keys(manifest).reduce((acc, cur) => {
|
||||||
|
acc[cur] = manifest[cur].filePath;
|
||||||
|
return acc;
|
||||||
|
}, /** @type {Record<string, string>} */ ({})),
|
||||||
|
null,
|
||||||
|
2
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Apply the plugin
|
* Apply the plugin
|
||||||
* @param {Compiler} compiler the compiler instance
|
* @param {Compiler} compiler the compiler instance
|
||||||
* @returns {void}
|
* @returns {void}
|
||||||
*/
|
*/
|
||||||
apply(compiler) {
|
apply(compiler) {
|
||||||
/** @type {WeakMap<Compilation, StatsCompilation>} */
|
|
||||||
const cachedStats = new WeakMap();
|
|
||||||
|
|
||||||
compiler.hooks.thisCompilation.tap(PLUGIN_NAME, (compilation) => {
|
compiler.hooks.thisCompilation.tap(PLUGIN_NAME, (compilation) => {
|
||||||
compilation.hooks.processAssets.tap(
|
compilation.hooks.processAssets.tap(
|
||||||
{
|
{
|
||||||
|
|
@ -75,27 +89,31 @@ class ManifestPlugin {
|
||||||
stage: Compilation.PROCESS_ASSETS_STAGE_SUMMARIZE
|
stage: Compilation.PROCESS_ASSETS_STAGE_SUMMARIZE
|
||||||
},
|
},
|
||||||
() => {
|
() => {
|
||||||
let stats =
|
const assets = compilation.getAssets();
|
||||||
/** @type {StatsCompilation | undefined} */ cachedStats.get(
|
const hashDigestLength = compilation.outputOptions.hashDigestLength;
|
||||||
compilation
|
const publicPath = compilation.getPath(
|
||||||
|
compilation.outputOptions.publicPath
|
||||||
);
|
);
|
||||||
if (!stats) {
|
|
||||||
stats = compilation.getStats().toJson({
|
|
||||||
all: false,
|
|
||||||
assets: true,
|
|
||||||
cachedAssets: true,
|
|
||||||
assetsSpace: Infinity,
|
|
||||||
publicPath: true
|
|
||||||
});
|
|
||||||
cachedStats.set(compilation, stats);
|
|
||||||
}
|
|
||||||
|
|
||||||
/** @type {Set<string>} */
|
/** @type {Set<string>} */
|
||||||
const added = new Set();
|
const added = new Set();
|
||||||
|
/** @type {ManifestObject} */
|
||||||
|
const manifest = {};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @type {{name: string, file: string}[]}
|
* @param {string} name name
|
||||||
|
* @returns {string} hash removed name
|
||||||
*/
|
*/
|
||||||
const items = [];
|
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},32})(?=\\.)`,
|
||||||
|
"gi"
|
||||||
|
);
|
||||||
|
return name.replace(reg, "");
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {string} file file
|
* @param {string} file file
|
||||||
|
|
@ -114,7 +132,13 @@ class ManifestPlugin {
|
||||||
path.basename(asset.info.sourceFilename)
|
path.basename(asset.info.sourceFilename)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
items.push({ name, file });
|
manifest[removeHash(name)] = {
|
||||||
|
filePath: publicPath
|
||||||
|
? publicPath +
|
||||||
|
(publicPath.endsWith("/") ? `${file}` : `/${file}`)
|
||||||
|
: file,
|
||||||
|
asset
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
for (const chunk of compilation.chunks) {
|
for (const chunk of compilation.chunks) {
|
||||||
|
|
@ -132,44 +156,16 @@ class ManifestPlugin {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stats.assets) {
|
for (const asset of assets) {
|
||||||
for (const asset of stats.assets) {
|
|
||||||
if (asset.info.hotModuleReplacement) {
|
if (asset.info.hotModuleReplacement) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
handleFile(asset.name);
|
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(
|
compilation.emitAsset(
|
||||||
this.options.filename,
|
this.options.filename,
|
||||||
new RawSource(this.options.handle(manifest, stats))
|
new RawSource(this.options.handler(manifest))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
@ -356,7 +356,7 @@ module.exports = mergeExports(fn, {
|
||||||
return require("./Stats");
|
return require("./Stats");
|
||||||
},
|
},
|
||||||
get ManifestPlugin() {
|
get ManifestPlugin() {
|
||||||
return require("./stats/ManifestPlugin");
|
return require("./ManifestPlugin");
|
||||||
},
|
},
|
||||||
get Template() {
|
get Template() {
|
||||||
return require("./Template");
|
return require("./Template");
|
||||||
|
|
|
||||||
|
|
@ -3,4 +3,4 @@
|
||||||
* DO NOT MODIFY BY HAND.
|
* DO NOT MODIFY BY HAND.
|
||||||
* Run `yarn fix:special` to update
|
* 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;
|
const r=/^(?:[A-Za-z]:[\\/]|\\\\|\/)/;function e(t,{instancePath:n="",parentData:a,parentDataProperty:s,rootData:o=t}={}){let i=null,l=0;if(0===l){if(!t||"object"!=typeof t||Array.isArray(t))return e.errors=[{params:{type:"object"}}],!1;{const n=l;for(const r in t)if("filename"!==r&&"handler"!==r)return e.errors=[{params:{additionalProperty:r}}],!1;if(n===l){if(void 0!==t.filename){let n=t.filename;const a=l;if(l===a){if("string"!=typeof n)return e.errors=[{params:{type:"string"}}],!1;if(n.includes("!")||!1!==r.test(n))return e.errors=[{params:{}}],!1;if(n.length<1)return e.errors=[{params:{}}],!1}var f=a===l}else f=!0;if(f)if(void 0!==t.handler){const r=l,n=l;let a=!1,s=null;const o=l;if(!(t.handler instanceof Function)){const r={params:{}};null===i?i=[r]:i.push(r),l++}if(o===l&&(a=!0,s=0),!a){const r={params:{passingSchemas:s}};return null===i?i=[r]:i.push(r),l++,e.errors=i,!1}l=n,null!==i&&(n?i.length=n:i=null),f=r===l}else f=!0}}}return e.errors=i,0===l}module.exports=e,module.exports.default=e;
|
||||||
|
|
@ -1,4 +1,35 @@
|
||||||
{
|
{
|
||||||
|
"definitions": {
|
||||||
|
"HandlerFunction": {
|
||||||
|
"description": "A function that receives the manifest object and returns the manifest string.",
|
||||||
|
"instanceof": "Function",
|
||||||
|
"tsType": "(manifest: ManifestObject) => string"
|
||||||
|
},
|
||||||
|
"ManifestItem": {
|
||||||
|
"description": "Describes a manifest entry that links the emitted path to the producing asset.",
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": false,
|
||||||
|
"properties": {
|
||||||
|
"asset": {
|
||||||
|
"description": "The compilation asset that produced this manifest entry.",
|
||||||
|
"tsType": "import('../../lib/Compilation').Asset"
|
||||||
|
},
|
||||||
|
"filePath": {
|
||||||
|
"description": "The public path recorded in the manifest for this asset.",
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"required": ["filePath"]
|
||||||
|
},
|
||||||
|
"ManifestObject": {
|
||||||
|
"description": "Maps asset identifiers to their manifest entries.",
|
||||||
|
"type": "object",
|
||||||
|
"additionalProperties": {
|
||||||
|
"$ref": "#/definitions/ManifestItem"
|
||||||
|
},
|
||||||
|
"tsType": "Record<string, ManifestItem>"
|
||||||
|
}
|
||||||
|
},
|
||||||
"title": "ManifestPluginOptions",
|
"title": "ManifestPluginOptions",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"additionalProperties": false,
|
"additionalProperties": false,
|
||||||
|
|
@ -9,10 +40,12 @@
|
||||||
"absolutePath": false,
|
"absolutePath": false,
|
||||||
"minLength": 1
|
"minLength": 1
|
||||||
},
|
},
|
||||||
"handle": {
|
"handler": {
|
||||||
"description": "A custom Function to create the manifest.",
|
"oneOf": [
|
||||||
"instanceof": "Function",
|
{
|
||||||
"tsType": "((manifest: Record<string, string>, stats: import('../../lib/stats/DefaultStatsFactoryPlugin').StatsCompilation) => string)"
|
"$ref": "#/definitions/HandlerFunction"
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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 with function publicPath", () => {
|
||||||
|
expect(url).toEqual("/dist/file-loader.png");
|
||||||
|
|
||||||
|
const manifest = JSON.parse(
|
||||||
|
fs.readFileSync(path.resolve(__dirname, "bar.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(/\/dist\/bundle1\.js/);
|
||||||
|
expect(manifest["file.js"]).toMatch(/\/dist\/file\.[a-f0-9]+\.js/);
|
||||||
|
expect(manifest["file.txt?foo"]).toMatch(/\/dist\/file\.[a-f0-9]+\.txt\?foo/);
|
||||||
|
expect(manifest["third.party.js"]).toBe("/dist/third.party.js");
|
||||||
|
expect(manifest["file.png"]).toBe("/dist/file-loader.png");
|
||||||
|
});
|
||||||
|
|
@ -4,11 +4,11 @@ import url from "../../asset-modules/_images/file.png";
|
||||||
|
|
||||||
import(/* webpackChunkName: 'file' */ "./file.txt?foo");
|
import(/* webpackChunkName: 'file' */ "./file.txt?foo");
|
||||||
|
|
||||||
it("should emit manifest with expected entries and paths", () => {
|
it("should emit manifest with expected entries and paths with string publicPath", () => {
|
||||||
expect(url).toEqual("/app/file-loader.png");
|
expect(url).toEqual("/app/file-loader.png");
|
||||||
|
|
||||||
const manifest = JSON.parse(
|
const manifest = JSON.parse(
|
||||||
fs.readFileSync(path.resolve(__dirname, "test.json"), "utf-8")
|
fs.readFileSync(path.resolve(__dirname, "foo.json"), "utf-8")
|
||||||
);
|
);
|
||||||
|
|
||||||
const keys = Object.keys(manifest).sort();
|
const keys = Object.keys(manifest).sort();
|
||||||
|
|
|
||||||
|
|
@ -3,5 +3,6 @@
|
||||||
module.exports = [
|
module.exports = [
|
||||||
// each time returns different OriginalSource in webpack.config.js:33
|
// each time returns different OriginalSource in webpack.config.js:33
|
||||||
// this prevents hit in inmemory cache
|
// this prevents hit in inmemory cache
|
||||||
|
/^Pack got invalid because of write to: RealContentHashPlugin|analyse|third.party.js$/,
|
||||||
/^Pack got invalid because of write to: RealContentHashPlugin|analyse|third.party.js$/
|
/^Pack got invalid because of write to: RealContentHashPlugin|analyse|third.party.js$/
|
||||||
];
|
];
|
||||||
|
|
|
||||||
|
|
@ -26,8 +26,9 @@ class CopyPlugin {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @type {import("../../../../").Configuration} */
|
/** @type {import("../../../../").Configuration[]} */
|
||||||
module.exports = {
|
module.exports = [
|
||||||
|
{
|
||||||
node: {
|
node: {
|
||||||
__dirname: false,
|
__dirname: false,
|
||||||
__filename: false
|
__filename: false
|
||||||
|
|
@ -40,7 +41,7 @@ module.exports = {
|
||||||
plugins: [
|
plugins: [
|
||||||
new CopyPlugin(),
|
new CopyPlugin(),
|
||||||
new webpack.ManifestPlugin({
|
new webpack.ManifestPlugin({
|
||||||
filename: "test.json"
|
filename: "foo.json"
|
||||||
})
|
})
|
||||||
],
|
],
|
||||||
module: {
|
module: {
|
||||||
|
|
@ -58,4 +59,38 @@ module.exports = {
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
};
|
},
|
||||||
|
{
|
||||||
|
entry: "./index-2.js",
|
||||||
|
node: {
|
||||||
|
__dirname: false,
|
||||||
|
__filename: false
|
||||||
|
},
|
||||||
|
output: {
|
||||||
|
publicPath: (_data) => "/dist/",
|
||||||
|
chunkFilename: "[name].[contenthash].js",
|
||||||
|
assetModuleFilename: "[name].[contenthash][ext][query]"
|
||||||
|
},
|
||||||
|
plugins: [
|
||||||
|
new CopyPlugin(),
|
||||||
|
new webpack.ManifestPlugin({
|
||||||
|
filename: "bar.json"
|
||||||
|
})
|
||||||
|
],
|
||||||
|
module: {
|
||||||
|
rules: [
|
||||||
|
{
|
||||||
|
test: /\.txt$/,
|
||||||
|
type: "asset/resource"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /\.png$/,
|
||||||
|
loader: "file-loader",
|
||||||
|
options: {
|
||||||
|
name: "file-loader.[ext]"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
|
||||||
|
|
@ -9758,6 +9758,24 @@ declare interface MakeDirectoryOptions {
|
||||||
recursive?: boolean;
|
recursive?: boolean;
|
||||||
mode?: string | number;
|
mode?: string | number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Describes a manifest entry that links the emitted path to the producing asset.
|
||||||
|
*/
|
||||||
|
declare interface ManifestItem {
|
||||||
|
/**
|
||||||
|
* The compilation asset that produced this manifest entry.
|
||||||
|
*/
|
||||||
|
asset?: Asset;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The public path recorded in the manifest for this asset.
|
||||||
|
*/
|
||||||
|
filePath: string;
|
||||||
|
}
|
||||||
|
declare interface ManifestObject {
|
||||||
|
[index: string]: ManifestItem;
|
||||||
|
}
|
||||||
declare class ManifestPlugin {
|
declare class ManifestPlugin {
|
||||||
constructor(options: ManifestPluginOptions);
|
constructor(options: ManifestPluginOptions);
|
||||||
options: Required<ManifestPluginOptions>;
|
options: Required<ManifestPluginOptions>;
|
||||||
|
|
@ -9774,12 +9792,9 @@ declare interface ManifestPluginOptions {
|
||||||
filename?: string;
|
filename?: string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A custom Function to create the manifest.
|
* A function that receives the manifest object and returns the manifest string.
|
||||||
*/
|
*/
|
||||||
handle?: (
|
handler?: (manifest: ManifestObject) => string;
|
||||||
manifest: Record<string, string>,
|
|
||||||
stats: StatsCompilation
|
|
||||||
) => string;
|
|
||||||
}
|
}
|
||||||
declare interface MapOptions {
|
declare interface MapOptions {
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue