fix: css url public path

This commit is contained in:
Alexander Akait 2024-06-10 22:03:14 +03:00 committed by GitHub
commit 0c5879aa67
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
15 changed files with 469 additions and 95 deletions

View File

@ -1113,12 +1113,11 @@ class RuntimeTemplate {
/** /**
* @param {Object} options options object * @param {Object} options options object
* @param {Module} options.module the module * @param {Module} options.module the module
* @param {string} options.publicPath the public path
* @param {RuntimeSpec=} options.runtime runtime * @param {RuntimeSpec=} options.runtime runtime
* @param {CodeGenerationResults} options.codeGenerationResults the code generation results * @param {CodeGenerationResults} options.codeGenerationResults the code generation results
* @returns {string} the url of the asset * @returns {string} the url of the asset
*/ */
assetUrl({ publicPath, runtime, module, codeGenerationResults }) { assetUrl({ runtime, module, codeGenerationResults }) {
if (!module) { if (!module) {
return "data:,"; return "data:,";
} }
@ -1128,8 +1127,8 @@ class RuntimeTemplate {
); );
const url = data.get("url"); const url = data.get("url");
if (url) return url.toString(); if (url) return url.toString();
const filename = data.get("filename"); const assetPath = data.get("assetPathForCss");
return publicPath + filename; return assetPath;
} }
} }

View File

@ -12,6 +12,7 @@ const ConcatenationScope = require("../ConcatenationScope");
const Generator = require("../Generator"); const Generator = require("../Generator");
const { ASSET_MODULE_TYPE } = require("../ModuleTypeConstants"); const { ASSET_MODULE_TYPE } = require("../ModuleTypeConstants");
const RuntimeGlobals = require("../RuntimeGlobals"); const RuntimeGlobals = require("../RuntimeGlobals");
const CssUrlDependency = require("../dependencies/CssUrlDependency");
const createHash = require("../util/createHash"); const createHash = require("../util/createHash");
const { makePathsRelative } = require("../util/identifier"); const { makePathsRelative } = require("../util/identifier");
const nonNumericOnlyHash = require("../util/nonNumericOnlyHash"); const nonNumericOnlyHash = require("../util/nonNumericOnlyHash");
@ -321,6 +322,7 @@ class AssetGenerator extends Generator {
} }
); );
let assetPath; let assetPath;
let assetPathForCss;
if (this.publicPath !== undefined) { if (this.publicPath !== undefined) {
const { path, info } = const { path, info } =
runtimeTemplate.compilation.getAssetPathWithInfo( runtimeTemplate.compilation.getAssetPathWithInfo(
@ -335,12 +337,24 @@ class AssetGenerator extends Generator {
); );
assetInfo = mergeAssetInfo(assetInfo, info); assetInfo = mergeAssetInfo(assetInfo, info);
assetPath = JSON.stringify(path + filename); assetPath = JSON.stringify(path + filename);
assetPathForCss = path + filename;
} else { } else {
runtimeRequirements.add(RuntimeGlobals.publicPath); // add __webpack_require__.p runtimeRequirements.add(RuntimeGlobals.publicPath); // add __webpack_require__.p
assetPath = runtimeTemplate.concatenation( assetPath = runtimeTemplate.concatenation(
{ expr: RuntimeGlobals.publicPath }, { expr: RuntimeGlobals.publicPath },
filename filename
); );
const compilation = runtimeTemplate.compilation;
const path =
compilation.outputOptions.publicPath === "auto"
? CssUrlDependency.PUBLIC_PATH_AUTO
: compilation.getAssetPath(
compilation.outputOptions.publicPath,
{
hash: compilation.hash
}
);
assetPathForCss = path + filename;
} }
assetInfo = { assetInfo = {
sourceFilename, sourceFilename,
@ -371,6 +385,7 @@ class AssetGenerator extends Generator {
data.set("fullContentHash", fullHash); data.set("fullContentHash", fullHash);
data.set("filename", filename); data.set("filename", filename);
data.set("assetInfo", assetInfo); data.set("assetInfo", assetInfo);
data.set("assetPathForCss", assetPathForCss);
} }
content = assetPath; content = assetPath;
} }

View File

@ -5,7 +5,12 @@
"use strict"; "use strict";
const { ConcatSource, PrefixSource } = require("webpack-sources"); const {
ConcatSource,
PrefixSource,
ReplaceSource,
CachedSource
} = require("webpack-sources");
const CssModule = require("../CssModule"); const CssModule = require("../CssModule");
const HotUpdateChunk = require("../HotUpdateChunk"); const HotUpdateChunk = require("../HotUpdateChunk");
const { const {
@ -26,6 +31,7 @@ const StaticExportsDependency = require("../dependencies/StaticExportsDependency
const { compareModulesByIdentifier } = require("../util/comparators"); const { compareModulesByIdentifier } = require("../util/comparators");
const createSchemaValidation = require("../util/create-schema-validation"); const createSchemaValidation = require("../util/create-schema-validation");
const createHash = require("../util/createHash"); const createHash = require("../util/createHash");
const { getUndoPath } = require("../util/identifier");
const memoize = require("../util/memoize"); const memoize = require("../util/memoize");
const nonNumericOnlyHash = require("../util/nonNumericOnlyHash"); const nonNumericOnlyHash = require("../util/nonNumericOnlyHash");
const CssExportsGenerator = require("./CssExportsGenerator"); const CssExportsGenerator = require("./CssExportsGenerator");
@ -39,6 +45,7 @@ const CssParser = require("./CssParser");
/** @typedef {import("../CodeGenerationResults")} CodeGenerationResults */ /** @typedef {import("../CodeGenerationResults")} CodeGenerationResults */
/** @typedef {import("../Compilation")} Compilation */ /** @typedef {import("../Compilation")} Compilation */
/** @typedef {import("../Compiler")} Compiler */ /** @typedef {import("../Compiler")} Compiler */
/** @typedef {import("../CssModule").Inheritance} Inheritance */
/** @typedef {import("../DependencyTemplate").CssExportsData} CssExportsData */ /** @typedef {import("../DependencyTemplate").CssExportsData} CssExportsData */
/** @typedef {import("../Module")} Module */ /** @typedef {import("../Module")} Module */
/** @typedef {import("../util/memoize")} Memoize */ /** @typedef {import("../util/memoize")} Memoize */
@ -161,6 +168,11 @@ const LZWEncode = str => {
const plugin = "CssModulesPlugin"; const plugin = "CssModulesPlugin";
class CssModulesPlugin { class CssModulesPlugin {
constructor() {
/** @type {WeakMap<Source, { undoPath: string, inheritance: Inheritance, source: CachedSource }>} */
this._moduleCache = new WeakMap();
}
/** /**
* Apply the plugin * Apply the plugin
* @param {Compiler} compiler the compiler instance * @param {Compiler} compiler the compiler instance
@ -356,6 +368,23 @@ class CssModulesPlugin {
/** @type {CssModule[] | undefined} */ /** @type {CssModule[] | undefined} */
const modules = orderedCssModulesPerChunk.get(chunk); const modules = orderedCssModulesPerChunk.get(chunk);
const { path: filename, info } = compilation.getPathWithInfo(
CssModulesPlugin.getChunkFilenameTemplate(
chunk,
compilation.outputOptions
),
{
hash,
runtime: chunk.runtime,
chunk,
contentHashType: "css"
}
);
const undoPath = getUndoPath(
filename,
compilation.outputOptions.path,
false
);
if (modules !== undefined) { if (modules !== undefined) {
result.push({ result.push({
render: () => render: () =>
@ -366,18 +395,11 @@ class CssModulesPlugin {
uniqueName: compilation.outputOptions.uniqueName, uniqueName: compilation.outputOptions.uniqueName,
cssHeadDataCompression: cssHeadDataCompression:
compilation.outputOptions.cssHeadDataCompression, compilation.outputOptions.cssHeadDataCompression,
undoPath,
modules modules
}), }),
filenameTemplate: CssModulesPlugin.getChunkFilenameTemplate( filename,
chunk, info,
compilation.outputOptions
),
pathOptions: {
hash,
runtime: chunk.runtime,
chunk,
contentHashType: "css"
},
identifier: `css${chunk.id}`, identifier: `css${chunk.id}`,
hash: chunk.contentHash.css hash: chunk.contentHash.css
}); });
@ -572,10 +594,144 @@ class CssModulesPlugin {
]; ];
} }
/**
* @param {Object} options options
* @param {string[]} options.metaData meta data
* @param {string} options.undoPath undo path for public path auto
* @param {Chunk} options.chunk chunk
* @param {ChunkGraph} options.chunkGraph chunk graph
* @param {CodeGenerationResults} options.codeGenerationResults code generation results
* @param {CssModule} options.module css module
* @returns {Source} css module source
*/
renderModule({
metaData,
undoPath,
chunk,
chunkGraph,
codeGenerationResults,
module
}) {
const codeGenResult = codeGenerationResults.get(module, chunk.runtime);
const moduleSourceContent =
/** @type {Source} */
(
codeGenResult.sources.get("css") ||
codeGenResult.sources.get("css-import")
);
const cacheEntry = this._moduleCache.get(moduleSourceContent);
/** @type {Inheritance} */
let inheritance = [[module.cssLayer, module.supports, module.media]];
if (module.inheritance) {
inheritance.push(...module.inheritance);
}
let source;
if (
cacheEntry &&
cacheEntry.undoPath === undoPath &&
cacheEntry.inheritance.every(([layer, supports, media], i) => {
const item = inheritance[i];
if (Array.isArray(item)) {
return layer === item[0] && supports === item[1] && media === item[2];
}
return false;
})
) {
source = cacheEntry.source;
} else {
const moduleSourceCode = /** @type {string} */ (
moduleSourceContent.source()
);
const publicPathAutoRegex = new RegExp(
CssUrlDependency.PUBLIC_PATH_AUTO,
"g"
);
/** @type {Source} */
let moduleSource = new ReplaceSource(moduleSourceContent);
let match;
while ((match = publicPathAutoRegex.exec(moduleSourceCode))) {
/** @type {ReplaceSource} */ (moduleSource).replace(
match.index,
(match.index += match[0].length - 1),
undoPath
);
}
for (let i = 0; i < inheritance.length; i++) {
const layer = inheritance[i][0];
const supports = inheritance[i][1];
const media = inheritance[i][2];
if (media) {
moduleSource = new ConcatSource(
`@media ${media} {\n`,
new PrefixSource("\t", moduleSource),
"}\n"
);
}
if (supports) {
moduleSource = new ConcatSource(
`@supports (${supports}) {\n`,
new PrefixSource("\t", moduleSource),
"}\n"
);
}
// Layer can be anonymous
if (layer !== undefined && layer !== null) {
moduleSource = new ConcatSource(
`@layer${layer ? ` ${layer}` : ""} {\n`,
new PrefixSource("\t", moduleSource),
"}\n"
);
}
}
if (moduleSource) {
moduleSource = new ConcatSource(moduleSource, "\n");
}
source = new CachedSource(moduleSource);
this._moduleCache.set(moduleSourceContent, {
inheritance,
undoPath,
source
});
}
/** @type {CssExportsData | undefined} */
const cssExportsData =
codeGenResult.data && codeGenResult.data.get("css-exports");
const exports = cssExportsData && cssExportsData.exports;
const esModule = cssExportsData && cssExportsData.esModule;
let moduleId = chunkGraph.getModuleId(module) + "";
// When `optimization.moduleIds` is `named` the module id is a path, so we need to normalize it between platforms
if (typeof moduleId === "string") {
moduleId = moduleId.replace(/\\/g, "/");
}
metaData.push(
`${
exports
? Array.from(
exports,
([n, v]) => `${escapeCss(n)}:${escapeCss(v)}/`
).join("")
: ""
}${esModule ? "&" : ""}${escapeCss(moduleId)}`
);
return source;
}
/** /**
* @param {Object} options options * @param {Object} options options
* @param {string | undefined} options.uniqueName unique name * @param {string | undefined} options.uniqueName unique name
* @param {boolean | undefined} options.cssHeadDataCompression compress css head data * @param {boolean | undefined} options.cssHeadDataCompression compress css head data
* @param {string} options.undoPath undo path for public path auto
* @param {Chunk} options.chunk chunk * @param {Chunk} options.chunk chunk
* @param {ChunkGraph} options.chunkGraph chunk graph * @param {ChunkGraph} options.chunkGraph chunk graph
* @param {CodeGenerationResults} options.codeGenerationResults code generation results * @param {CodeGenerationResults} options.codeGenerationResults code generation results
@ -585,6 +741,7 @@ class CssModulesPlugin {
renderChunk({ renderChunk({
uniqueName, uniqueName,
cssHeadDataCompression, cssHeadDataCompression,
undoPath,
chunk, chunk,
chunkGraph, chunkGraph,
codeGenerationResults, codeGenerationResults,
@ -595,78 +752,15 @@ class CssModulesPlugin {
const metaData = []; const metaData = [];
for (const module of modules) { for (const module of modules) {
try { try {
const codeGenResult = codeGenerationResults.get(module, chunk.runtime); const moduleSource = this.renderModule({
metaData,
let moduleSource = undoPath,
/** @type {Source} */ chunk,
( chunkGraph,
codeGenResult.sources.get("css") || codeGenerationResults,
codeGenResult.sources.get("css-import") module
); });
source.add(moduleSource);
let inheritance = [[module.cssLayer, module.supports, module.media]];
if (module.inheritance) {
inheritance.push(...module.inheritance);
}
for (let i = 0; i < inheritance.length; i++) {
const layer = inheritance[i][0];
const supports = inheritance[i][1];
const media = inheritance[i][2];
if (media) {
moduleSource = new ConcatSource(
`@media ${media} {\n`,
new PrefixSource("\t", moduleSource),
"}\n"
);
}
if (supports) {
moduleSource = new ConcatSource(
`@supports (${supports}) {\n`,
new PrefixSource("\t", moduleSource),
"}\n"
);
}
// Layer can be anonymous
if (layer !== undefined && layer !== null) {
moduleSource = new ConcatSource(
`@layer${layer ? ` ${layer}` : ""} {\n`,
new PrefixSource("\t", moduleSource),
"}\n"
);
}
}
if (moduleSource) {
source.add(moduleSource);
source.add("\n");
}
/** @type {CssExportsData | undefined} */
const cssExportsData =
codeGenResult.data && codeGenResult.data.get("css-exports");
const exports = cssExportsData && cssExportsData.exports;
const esModule = cssExportsData && cssExportsData.esModule;
let moduleId = chunkGraph.getModuleId(module) + "";
// When `optimization.moduleIds` is `named` the module id is a path, so we need to normalize it between platforms
if (typeof moduleId === "string") {
moduleId = moduleId.replace(/\\/g, "/");
}
metaData.push(
`${
exports
? Array.from(
exports,
([n, v]) => `${escapeCss(n)}:${escapeCss(v)}/`
).join("")
: ""
}${esModule ? "&" : ""}${escapeCss(moduleId)}`
);
} catch (e) { } catch (e) {
/** @type {Error} */ /** @type {Error} */
(e).message += `\nduring rendering of css ${module.identifier()}`; (e).message += `\nduring rendering of css ${module.identifier()}`;

View File

@ -126,6 +126,7 @@ CssUrlDependency.Template = class CssUrlDependencyTemplate extends (
{ moduleGraph, runtimeTemplate, codeGenerationResults } { moduleGraph, runtimeTemplate, codeGenerationResults }
) { ) {
const dep = /** @type {CssUrlDependency} */ (dependency); const dep = /** @type {CssUrlDependency} */ (dependency);
const module = /** @type {Module} */ (moduleGraph.getModule(dep));
/** @type {string | undefined} */ /** @type {string | undefined} */
let newValue; let newValue;
@ -134,8 +135,7 @@ CssUrlDependency.Template = class CssUrlDependencyTemplate extends (
case "string": case "string":
newValue = cssEscapeString( newValue = cssEscapeString(
runtimeTemplate.assetUrl({ runtimeTemplate.assetUrl({
publicPath: "", module,
module: /** @type {Module} */ (moduleGraph.getModule(dep)),
codeGenerationResults codeGenerationResults
}) })
); );
@ -143,8 +143,7 @@ CssUrlDependency.Template = class CssUrlDependencyTemplate extends (
case "url": case "url":
newValue = `url(${cssEscapeString( newValue = `url(${cssEscapeString(
runtimeTemplate.assetUrl({ runtimeTemplate.assetUrl({
publicPath: "", module,
module: /** @type {Module} */ (moduleGraph.getModule(dep)),
codeGenerationResults codeGenerationResults
}) })
)})`; )})`;
@ -161,4 +160,6 @@ CssUrlDependency.Template = class CssUrlDependencyTemplate extends (
makeSerializable(CssUrlDependency, "webpack/lib/dependencies/CssUrlDependency"); makeSerializable(CssUrlDependency, "webpack/lib/dependencies/CssUrlDependency");
CssUrlDependency.PUBLIC_PATH_AUTO = "__WEBPACK_CSS_PUBLIC_PATH_AUTO__";
module.exports = CssUrlDependency; module.exports = CssUrlDependency;

View File

@ -4183,3 +4183,84 @@ Object {
"n": " green url(img.09a1a1112c577c279435.png) xyz", "n": " green url(img.09a1a1112c577c279435.png) xyz",
} }
`; `;
exports[`ConfigCacheTestCases css urls-css-filename exported tests should generate correct url public path with css filename 1`] = `
Object {
"getPropertyValue": [Function],
"nested-dir": " url(../../bundle0/assets/img2.png)",
"nested-nested-dir": " url(../../bundle0/assets/img3.png)",
"same-dir": " url(../../bundle0/assets/img1.png)",
}
`;
exports[`ConfigCacheTestCases css urls-css-filename exported tests should generate correct url public path with css filename 2`] = `
Object {
"getPropertyValue": [Function],
"nested-dir": " url(../../bundle0/assets/img3.png)",
"outer-dir": " url(../../bundle0/assets/img1.png)",
"same-dir": " url(../../bundle0/assets/img2.png)",
}
`;
exports[`ConfigCacheTestCases css urls-css-filename exported tests should generate correct url public path with css filename 3`] = `
Object {
"getPropertyValue": [Function],
"outer-dir": " url(../../bundle0/assets/img2.png)",
"outer-outer-dir": " url(../../bundle0/assets/img1.png)",
"same-dir": " url(../../bundle0/assets/img3.png)",
}
`;
exports[`ConfigCacheTestCases css urls-css-filename exported tests should generate correct url public path with css filename 4`] = `
Object {
"getPropertyValue": [Function],
"nested-dir": " url(https://test.cases/path/bundle1/assets/img2.png)",
"nested-nested-dir": " url(https://test.cases/path/bundle1/assets/img3.png)",
"same-dir": " url(https://test.cases/path/bundle1/assets/img1.png)",
}
`;
exports[`ConfigCacheTestCases css urls-css-filename exported tests should generate correct url public path with css filename 5`] = `
Object {
"getPropertyValue": [Function],
"nested-dir": " url(https://test.cases/path/bundle1/assets/img3.png)",
"outer-dir": " url(https://test.cases/path/bundle1/assets/img1.png)",
"same-dir": " url(https://test.cases/path/bundle1/assets/img2.png)",
}
`;
exports[`ConfigCacheTestCases css urls-css-filename exported tests should generate correct url public path with css filename 6`] = `
Object {
"getPropertyValue": [Function],
"outer-dir": " url(https://test.cases/path/bundle1/assets/img2.png)",
"outer-outer-dir": " url(https://test.cases/path/bundle1/assets/img1.png)",
"same-dir": " url(https://test.cases/path/bundle1/assets/img3.png)",
}
`;
exports[`ConfigCacheTestCases css urls-css-filename exported tests should generate correct url public path with css filename 7`] = `
Object {
"getPropertyValue": [Function],
"nested-dir": " url(https://test.cases/path/bundle2/assets/img2.png)",
"nested-nested-dir": " url(https://test.cases/path/bundle2/assets/img3.png)",
"same-dir": " url(https://test.cases/path/bundle2/assets/img1.png)",
}
`;
exports[`ConfigCacheTestCases css urls-css-filename exported tests should generate correct url public path with css filename 8`] = `
Object {
"getPropertyValue": [Function],
"nested-dir": " url(https://test.cases/path/bundle2/assets/img3.png)",
"outer-dir": " url(https://test.cases/path/bundle2/assets/img1.png)",
"same-dir": " url(https://test.cases/path/bundle2/assets/img2.png)",
}
`;
exports[`ConfigCacheTestCases css urls-css-filename exported tests should generate correct url public path with css filename 9`] = `
Object {
"getPropertyValue": [Function],
"outer-dir": " url(https://test.cases/path/bundle2/assets/img2.png)",
"outer-outer-dir": " url(https://test.cases/path/bundle2/assets/img1.png)",
"same-dir": " url(https://test.cases/path/bundle2/assets/img3.png)",
}
`;

View File

@ -4183,3 +4183,84 @@ Object {
"n": " green url(img.09a1a1112c577c279435.png) xyz", "n": " green url(img.09a1a1112c577c279435.png) xyz",
} }
`; `;
exports[`ConfigTestCases css urls-css-filename exported tests should generate correct url public path with css filename 1`] = `
Object {
"getPropertyValue": [Function],
"nested-dir": " url(../../bundle0/assets/img2.png)",
"nested-nested-dir": " url(../../bundle0/assets/img3.png)",
"same-dir": " url(../../bundle0/assets/img1.png)",
}
`;
exports[`ConfigTestCases css urls-css-filename exported tests should generate correct url public path with css filename 2`] = `
Object {
"getPropertyValue": [Function],
"nested-dir": " url(../../bundle0/assets/img3.png)",
"outer-dir": " url(../../bundle0/assets/img1.png)",
"same-dir": " url(../../bundle0/assets/img2.png)",
}
`;
exports[`ConfigTestCases css urls-css-filename exported tests should generate correct url public path with css filename 3`] = `
Object {
"getPropertyValue": [Function],
"outer-dir": " url(../../bundle0/assets/img2.png)",
"outer-outer-dir": " url(../../bundle0/assets/img1.png)",
"same-dir": " url(../../bundle0/assets/img3.png)",
}
`;
exports[`ConfigTestCases css urls-css-filename exported tests should generate correct url public path with css filename 4`] = `
Object {
"getPropertyValue": [Function],
"nested-dir": " url(https://test.cases/path/bundle1/assets/img2.png)",
"nested-nested-dir": " url(https://test.cases/path/bundle1/assets/img3.png)",
"same-dir": " url(https://test.cases/path/bundle1/assets/img1.png)",
}
`;
exports[`ConfigTestCases css urls-css-filename exported tests should generate correct url public path with css filename 5`] = `
Object {
"getPropertyValue": [Function],
"nested-dir": " url(https://test.cases/path/bundle1/assets/img3.png)",
"outer-dir": " url(https://test.cases/path/bundle1/assets/img1.png)",
"same-dir": " url(https://test.cases/path/bundle1/assets/img2.png)",
}
`;
exports[`ConfigTestCases css urls-css-filename exported tests should generate correct url public path with css filename 6`] = `
Object {
"getPropertyValue": [Function],
"outer-dir": " url(https://test.cases/path/bundle1/assets/img2.png)",
"outer-outer-dir": " url(https://test.cases/path/bundle1/assets/img1.png)",
"same-dir": " url(https://test.cases/path/bundle1/assets/img3.png)",
}
`;
exports[`ConfigTestCases css urls-css-filename exported tests should generate correct url public path with css filename 7`] = `
Object {
"getPropertyValue": [Function],
"nested-dir": " url(https://test.cases/path/bundle2/assets/img2.png)",
"nested-nested-dir": " url(https://test.cases/path/bundle2/assets/img3.png)",
"same-dir": " url(https://test.cases/path/bundle2/assets/img1.png)",
}
`;
exports[`ConfigTestCases css urls-css-filename exported tests should generate correct url public path with css filename 8`] = `
Object {
"getPropertyValue": [Function],
"nested-dir": " url(https://test.cases/path/bundle2/assets/img3.png)",
"outer-dir": " url(https://test.cases/path/bundle2/assets/img1.png)",
"same-dir": " url(https://test.cases/path/bundle2/assets/img2.png)",
}
`;
exports[`ConfigTestCases css urls-css-filename exported tests should generate correct url public path with css filename 9`] = `
Object {
"getPropertyValue": [Function],
"outer-dir": " url(https://test.cases/path/bundle2/assets/img2.png)",
"outer-outer-dir": " url(https://test.cases/path/bundle2/assets/img1.png)",
"same-dir": " url(https://test.cases/path/bundle2/assets/img3.png)",
}
`;

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

View File

@ -0,0 +1,7 @@
@import "./nested/index.css";
h1 {
same-dir: url('./img1.png');
nested-dir: url('./nested/img2.png');
nested-nested-dir: url('./nested/nested/img3.png');
}

View File

@ -0,0 +1,22 @@
it(`should generate correct url public path with css filename`, done => {
const h1 = document.createElement('h1');
document.body.appendChild(h1);
const h2 = document.createElement('h2');
document.body.appendChild(h1);
const h3 = document.createElement('h3');
document.body.appendChild(h1);
import("./index.css").then(x => {
try {
expect(x).toEqual(nsObj({}));
const style1 = getComputedStyle(h1);
expect(style1).toMatchSnapshot();
const style2 = getComputedStyle(h2);
expect(style2).toMatchSnapshot();
const style3 = getComputedStyle(h3);
expect(style3).toMatchSnapshot();
done();
} catch (e) {
done(e);
}
}, done);
});

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

View File

@ -0,0 +1,7 @@
@import "./nested/index.css";
h2 {
same-dir: url('./img2.png');
nested-dir: url('./nested/img3.png');
outer-dir: url('../img1.png');
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 76 KiB

View File

@ -0,0 +1,5 @@
h3 {
same-dir: url('./img3.png');
outer-dir: url('../img2.png');
outer-outer-dir: url('../../img1.png');
}

View File

@ -0,0 +1,66 @@
/** @type {import("../../../../").Configuration} */
const common = {
target: "web",
mode: "development",
devtool: false,
experiments: {
css: true
},
optimization: {
splitChunks: {
cacheGroups: {
assetFixHack: {
type: "asset/resource",
chunks: "all",
name: "main",
enforce: true
},
assetFixHack1: {
type: "asset/inline",
chunks: "all",
name: "main",
enforce: true
}
}
}
}
};
/** @type {import("../../../../").Configuration} */
module.exports = [
{
...common,
output: {
publicPath: "auto",
cssChunkFilename: "bundle0/css/[name].css",
assetModuleFilename: "bundle0/assets/[name][ext]"
}
},
{
...common,
output: {
publicPath: "https://test.cases/path/",
cssChunkFilename: "bundle1/css/[name].css",
assetModuleFilename: "bundle1/assets/[name][ext]"
}
},
{
...common,
output: {
cssChunkFilename: "bundle2/css/[name].css"
},
module: {
rules: [
{
test: /\.png$/i,
type: "asset/resource",
generator: {
filename: "[name][ext]",
outputPath: "bundle2/assets/",
publicPath: "https://test.cases/path/bundle2/assets/"
}
}
]
}
}
];

4
types.d.ts vendored
View File

@ -12958,10 +12958,6 @@ declare abstract class RuntimeTemplate {
* the module * the module
*/ */
module: Module; module: Module;
/**
* the public path
*/
publicPath: string;
/** /**
* runtime * runtime
*/ */