mirror of https://github.com/webpack/webpack.git
feat: support assetModulePublicPath
This commit is contained in:
parent
1def19ea8a
commit
55fd79ee6a
|
|
@ -417,6 +417,15 @@ export type AssetModuleFilename =
|
|||
pathData: import("../lib/Compilation").PathData,
|
||||
assetInfo?: import("../lib/Compilation").AssetInfo
|
||||
) => string);
|
||||
/**
|
||||
* The publicPath of asset modules.
|
||||
*/
|
||||
export type AssetModulePublicPath =
|
||||
| string
|
||||
| ((
|
||||
pathData: import("../lib/Compilation").PathData,
|
||||
assetInfo?: import("../lib/Compilation").AssetInfo
|
||||
) => string);
|
||||
/**
|
||||
* Add charset attribute for script tag.
|
||||
*/
|
||||
|
|
@ -1874,6 +1883,10 @@ export interface Output {
|
|||
* The filename of asset modules as relative path inside the 'output.path' directory.
|
||||
*/
|
||||
assetModuleFilename?: AssetModuleFilename;
|
||||
/**
|
||||
* The publicPath of asset modules.
|
||||
*/
|
||||
assetModulePublicPath?: AssetModulePublicPath;
|
||||
/**
|
||||
* Add a comment in the UMD wrapper.
|
||||
*/
|
||||
|
|
@ -2592,6 +2605,10 @@ export interface AssetResourceGeneratorOptions {
|
|||
* Specifies the filename template of output files on disk. You must **not** specify an absolute path here, but the path may contain folders separated by '/'! The specified path is joined with the value of the 'output.path' option to determine the location on disk.
|
||||
*/
|
||||
filename?: FilenameTemplate;
|
||||
/**
|
||||
* The publicPath of asset modules.
|
||||
*/
|
||||
publicPath?: AssetModulePublicPath;
|
||||
}
|
||||
/**
|
||||
* No generator options are supported for this module type.
|
||||
|
|
@ -2827,6 +2844,10 @@ export interface OutputNormalized {
|
|||
* The filename of asset modules as relative path inside the 'output.path' directory.
|
||||
*/
|
||||
assetModuleFilename?: AssetModuleFilename;
|
||||
/**
|
||||
* The publicPath of asset modules.
|
||||
*/
|
||||
assetModulePublicPath?: AssetModulePublicPath;
|
||||
/**
|
||||
* Add charset attribute for script tag.
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ const { makePathsRelative } = require("../util/identifier");
|
|||
|
||||
/** @typedef {import("webpack-sources").Source} Source */
|
||||
/** @typedef {import("../../declarations/WebpackOptions").AssetGeneratorOptions} AssetGeneratorOptions */
|
||||
/** @typedef {import("../../declarations/WebpackOptions").AssetModulePublicPath} AssetModulePublicPath */
|
||||
/** @typedef {import("../Compilation")} Compilation */
|
||||
/** @typedef {import("../Compiler")} Compiler */
|
||||
/** @typedef {import("../Generator").GenerateContext} GenerateContext */
|
||||
|
|
@ -31,12 +32,14 @@ class AssetGenerator extends Generator {
|
|||
/**
|
||||
* @param {AssetGeneratorOptions["dataUrl"]=} dataUrlOptions the options for the data url
|
||||
* @param {string=} filename override for output.assetModuleFilename
|
||||
* @param {AssetModulePublicPath=} publicPath override for output.assetModulePublicPath
|
||||
* @param {boolean=} emit generate output asset
|
||||
*/
|
||||
constructor(dataUrlOptions, filename, emit) {
|
||||
constructor(dataUrlOptions, filename, publicPath, emit) {
|
||||
super();
|
||||
this.dataUrlOptions = dataUrlOptions;
|
||||
this.filename = filename;
|
||||
this.publicPath = publicPath;
|
||||
this.emit = emit;
|
||||
}
|
||||
|
||||
|
|
@ -113,6 +116,10 @@ class AssetGenerator extends Generator {
|
|||
} else {
|
||||
const assetModuleFilename =
|
||||
this.filename || runtimeTemplate.outputOptions.assetModuleFilename;
|
||||
let assetModulePublicPath =
|
||||
this.publicPath ||
|
||||
runtimeTemplate.outputOptions.assetModulePublicPath;
|
||||
let publicPath;
|
||||
const hash = createHash(runtimeTemplate.outputOptions.hashFunction);
|
||||
if (runtimeTemplate.outputOptions.hashSalt) {
|
||||
hash.update(runtimeTemplate.outputOptions.hashSalt);
|
||||
|
|
@ -144,6 +151,23 @@ class AssetGenerator extends Generator {
|
|||
contentHash
|
||||
}
|
||||
);
|
||||
if (assetModulePublicPath) {
|
||||
publicPath = JSON.stringify(
|
||||
runtimeTemplate.compilation.getAssetPathWithInfo(
|
||||
assetModulePublicPath,
|
||||
{
|
||||
module,
|
||||
runtime,
|
||||
filename: sourceFilename,
|
||||
chunkGraph,
|
||||
contentHash
|
||||
}
|
||||
).path
|
||||
);
|
||||
} else {
|
||||
publicPath = RuntimeGlobals.publicPath;
|
||||
runtimeRequirements.add(RuntimeGlobals.publicPath); // add __webpack_require__.p
|
||||
}
|
||||
module.buildInfo.filename = filename;
|
||||
module.buildInfo.assetInfo = {
|
||||
sourceFilename,
|
||||
|
|
@ -159,12 +183,10 @@ class AssetGenerator extends Generator {
|
|||
data.set("assetInfo", info);
|
||||
}
|
||||
|
||||
runtimeRequirements.add(RuntimeGlobals.publicPath); // add __webpack_require__.p
|
||||
|
||||
return new RawSource(
|
||||
`${RuntimeGlobals.module}.exports = ${
|
||||
RuntimeGlobals.publicPath
|
||||
} + ${JSON.stringify(filename)};`
|
||||
`${
|
||||
RuntimeGlobals.module
|
||||
}.exports = ${publicPath} + ${JSON.stringify(filename)};`
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -118,8 +118,10 @@ class AssetModulesPlugin {
|
|||
}
|
||||
|
||||
let filename = undefined;
|
||||
let publicPath = undefined;
|
||||
if (type !== "asset/inline") {
|
||||
filename = generatorOptions.filename;
|
||||
publicPath = generatorOptions.publicPath;
|
||||
}
|
||||
|
||||
const AssetGenerator = getAssetGenerator();
|
||||
|
|
@ -127,6 +129,7 @@ class AssetModulesPlugin {
|
|||
return new AssetGenerator(
|
||||
dataUrl,
|
||||
filename,
|
||||
publicPath,
|
||||
generatorOptions.emit !== false
|
||||
);
|
||||
});
|
||||
|
|
|
|||
|
|
@ -271,6 +271,7 @@ const getNormalizedWebpackOptions = config => {
|
|||
/** @type {OutputNormalized} */
|
||||
const result = {
|
||||
assetModuleFilename: output.assetModuleFilename,
|
||||
assetModulePublicPath: output.assetModulePublicPath,
|
||||
charset: output.charset,
|
||||
chunkFilename: output.chunkFilename,
|
||||
chunkFormat: output.chunkFormat,
|
||||
|
|
|
|||
|
|
@ -107,6 +107,9 @@
|
|||
},
|
||||
"filename": {
|
||||
"$ref": "#/definitions/FilenameTemplate"
|
||||
},
|
||||
"publicPath": {
|
||||
"$ref": "#/definitions/AssetModulePublicPath"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
@ -133,6 +136,18 @@
|
|||
}
|
||||
]
|
||||
},
|
||||
"AssetModulePublicPath": {
|
||||
"description": "The publicPath of asset modules.",
|
||||
"anyOf": [
|
||||
{
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"instanceof": "Function",
|
||||
"tsType": "((pathData: import(\"../lib/Compilation\").PathData, assetInfo?: import(\"../lib/Compilation\").AssetInfo) => string)"
|
||||
}
|
||||
]
|
||||
},
|
||||
"AssetParserDataUrlFunction": {
|
||||
"description": "Function that executes for module and should return whenever asset should be inlined as DataUrl.",
|
||||
"instanceof": "Function",
|
||||
|
|
@ -178,6 +193,9 @@
|
|||
},
|
||||
"filename": {
|
||||
"$ref": "#/definitions/FilenameTemplate"
|
||||
},
|
||||
"publicPath": {
|
||||
"$ref": "#/definitions/AssetModulePublicPath"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
@ -2487,6 +2505,9 @@
|
|||
"assetModuleFilename": {
|
||||
"$ref": "#/definitions/AssetModuleFilename"
|
||||
},
|
||||
"assetModulePublicPath": {
|
||||
"$ref": "#/definitions/AssetModulePublicPath"
|
||||
},
|
||||
"auxiliaryComment": {
|
||||
"cli": {
|
||||
"exclude": true
|
||||
|
|
@ -2670,6 +2691,9 @@
|
|||
"assetModuleFilename": {
|
||||
"$ref": "#/definitions/AssetModuleFilename"
|
||||
},
|
||||
"assetModulePublicPath": {
|
||||
"$ref": "#/definitions/AssetModulePublicPath"
|
||||
},
|
||||
"charset": {
|
||||
"$ref": "#/definitions/Charset"
|
||||
},
|
||||
|
|
|
|||
|
|
@ -282,6 +282,7 @@ describe("Defaults", () => {
|
|||
},
|
||||
"output": Object {
|
||||
"assetModuleFilename": "[hash][ext][query]",
|
||||
"assetModulePublicPath": undefined,
|
||||
"charset": true,
|
||||
"chunkFilename": "[name].js",
|
||||
"chunkFormat": "array-push",
|
||||
|
|
|
|||
|
|
@ -496,7 +496,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.output has an unknown property 'ecmaVersion'. These properties are valid:
|
||||
object { assetModuleFilename?, auxiliaryComment?, charset?, chunkFilename?, chunkFormat?, chunkLoadTimeout?, chunkLoading?, chunkLoadingGlobal?, clean?, compareBeforeEmit?, crossOriginLoading?, devtoolFallbackModuleFilenameTemplate?, devtoolModuleFilenameTemplate?, devtoolNamespace?, enabledChunkLoadingTypes?, enabledLibraryTypes?, enabledWasmLoadingTypes?, environment?, filename?, globalObject?, hashDigest?, hashDigestLength?, hashFunction?, hashSalt?, hotUpdateChunkFilename?, hotUpdateGlobal?, hotUpdateMainFilename?, iife?, importFunctionName?, importMetaName?, library?, libraryExport?, libraryTarget?, module?, path?, pathinfo?, publicPath?, scriptType?, sourceMapFilename?, sourcePrefix?, strictModuleErrorHandling?, strictModuleExceptionHandling?, umdNamedDefine?, uniqueName?, wasmLoading?, webassemblyModuleFilename?, workerChunkLoading?, workerWasmLoading? }
|
||||
object { assetModuleFilename?, assetModulePublicPath?, auxiliaryComment?, charset?, chunkFilename?, chunkFormat?, chunkLoadTimeout?, chunkLoading?, chunkLoadingGlobal?, clean?, compareBeforeEmit?, crossOriginLoading?, devtoolFallbackModuleFilenameTemplate?, devtoolModuleFilenameTemplate?, devtoolNamespace?, enabledChunkLoadingTypes?, enabledLibraryTypes?, enabledWasmLoadingTypes?, environment?, filename?, globalObject?, hashDigest?, hashDigestLength?, hashFunction?, hashSalt?, hotUpdateChunkFilename?, hotUpdateGlobal?, hotUpdateMainFilename?, iife?, importFunctionName?, importMetaName?, library?, libraryExport?, libraryTarget?, module?, path?, pathinfo?, publicPath?, scriptType?, sourceMapFilename?, sourcePrefix?, strictModuleErrorHandling?, strictModuleExceptionHandling?, umdNamedDefine?, uniqueName?, wasmLoading?, webassemblyModuleFilename?, workerChunkLoading?, workerWasmLoading? }
|
||||
-> Options affecting the output of the compilation. \`output\` options tell webpack how to write the compiled files to disk.
|
||||
Did you mean output.environment (output.ecmaVersion was a temporary configuration option during webpack 5 beta)?"
|
||||
`)
|
||||
|
|
|
|||
|
|
@ -933,6 +933,19 @@ Object {
|
|||
"multiple": false,
|
||||
"simpleType": "string",
|
||||
},
|
||||
"module-generator-asset-public-path": Object {
|
||||
"configs": Array [
|
||||
Object {
|
||||
"description": "The publicPath of asset modules.",
|
||||
"multiple": false,
|
||||
"path": "module.generator.asset.publicPath",
|
||||
"type": "string",
|
||||
},
|
||||
],
|
||||
"description": "The publicPath of asset modules.",
|
||||
"multiple": false,
|
||||
"simpleType": "string",
|
||||
},
|
||||
"module-generator-asset-resource-emit": Object {
|
||||
"configs": Array [
|
||||
Object {
|
||||
|
|
@ -959,6 +972,19 @@ Object {
|
|||
"multiple": false,
|
||||
"simpleType": "string",
|
||||
},
|
||||
"module-generator-asset-resource-public-path": Object {
|
||||
"configs": Array [
|
||||
Object {
|
||||
"description": "The publicPath of asset modules.",
|
||||
"multiple": false,
|
||||
"path": "module.generator.asset/resource.publicPath",
|
||||
"type": "string",
|
||||
},
|
||||
],
|
||||
"description": "The publicPath of asset modules.",
|
||||
"multiple": false,
|
||||
"simpleType": "string",
|
||||
},
|
||||
"module-no-parse": Object {
|
||||
"configs": Array [
|
||||
Object {
|
||||
|
|
@ -4039,6 +4065,19 @@ Object {
|
|||
"multiple": false,
|
||||
"simpleType": "string",
|
||||
},
|
||||
"output-asset-module-public-path": Object {
|
||||
"configs": Array [
|
||||
Object {
|
||||
"description": "The publicPath of asset modules.",
|
||||
"multiple": false,
|
||||
"path": "output.assetModulePublicPath",
|
||||
"type": "string",
|
||||
},
|
||||
],
|
||||
"description": "The publicPath of asset modules.",
|
||||
"multiple": false,
|
||||
"simpleType": "string",
|
||||
},
|
||||
"output-charset": Object {
|
||||
"configs": Array [
|
||||
Object {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,5 @@
|
|||
import url from "../_images/file.png";
|
||||
|
||||
it("should import asset with output.assetModulePublicPath", () => {
|
||||
expect(url).toEqual("/assets/file.png");
|
||||
});
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
/** @type {import("../../../../").Configuration} */
|
||||
module.exports = {
|
||||
mode: "development",
|
||||
output: {
|
||||
assetModulePublicPath: "/assets/",
|
||||
assetModuleFilename: "file[ext]"
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.png$/,
|
||||
type: "asset"
|
||||
}
|
||||
]
|
||||
}
|
||||
};
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
import url from "../_images/file.png";
|
||||
|
||||
it("should import asset with module.generator.asset.publicPath", () => {
|
||||
expect(url).toEqual("assets/file.png");
|
||||
});
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
/** @type {import("../../../../").Configuration} */
|
||||
module.exports = {
|
||||
mode: "development",
|
||||
output: {
|
||||
assetModuleFilename: "file[ext]"
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.png$/,
|
||||
type: "asset"
|
||||
}
|
||||
],
|
||||
generator: {
|
||||
asset: {
|
||||
publicPath: "assets/"
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
import url from "../_images/file.png";
|
||||
|
||||
it("should import asset with rule.generator.publicPath", () => {
|
||||
expect(url).toEqual("assets/file.png");
|
||||
});
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
/** @type {import("../../../../").Configuration} */
|
||||
module.exports = {
|
||||
mode: "development",
|
||||
output: {
|
||||
assetModuleFilename: "file[ext]"
|
||||
},
|
||||
module: {
|
||||
rules: [
|
||||
{
|
||||
test: /\.png$/,
|
||||
type: "asset",
|
||||
generator: {
|
||||
publicPath: () => {
|
||||
return "assets/";
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
};
|
||||
|
|
@ -308,6 +308,11 @@ declare interface AssetResourceGeneratorOptions {
|
|||
* Specifies the filename template of output files on disk. You must **not** specify an absolute path here, but the path may contain folders separated by '/'! The specified path is joined with the value of the 'output.path' option to determine the location on disk.
|
||||
*/
|
||||
filename?: string | ((pathData: PathData, assetInfo?: AssetInfo) => string);
|
||||
|
||||
/**
|
||||
* The publicPath of asset modules.
|
||||
*/
|
||||
publicPath?: string | ((pathData: PathData, assetInfo?: AssetInfo) => string);
|
||||
}
|
||||
declare abstract class AsyncDependenciesBlock extends DependenciesBlock {
|
||||
groupOptions: RawChunkGroupOptions & { name?: string } & {
|
||||
|
|
@ -7205,6 +7210,13 @@ declare interface Output {
|
|||
| string
|
||||
| ((pathData: PathData, assetInfo?: AssetInfo) => string);
|
||||
|
||||
/**
|
||||
* The publicPath of asset modules.
|
||||
*/
|
||||
assetModulePublicPath?:
|
||||
| string
|
||||
| ((pathData: PathData, assetInfo?: AssetInfo) => string);
|
||||
|
||||
/**
|
||||
* Add a comment in the UMD wrapper.
|
||||
*/
|
||||
|
|
@ -7482,6 +7494,13 @@ declare interface OutputNormalized {
|
|||
| string
|
||||
| ((pathData: PathData, assetInfo?: AssetInfo) => string);
|
||||
|
||||
/**
|
||||
* The publicPath of asset modules.
|
||||
*/
|
||||
assetModulePublicPath?:
|
||||
| string
|
||||
| ((pathData: PathData, assetInfo?: AssetInfo) => string);
|
||||
|
||||
/**
|
||||
* Add charset attribute for script tag.
|
||||
*/
|
||||
|
|
|
|||
Loading…
Reference in New Issue