diff --git a/src/index.js b/src/index.js index e420cb45..154f5fea 100644 --- a/src/index.js +++ b/src/index.js @@ -13,6 +13,7 @@ const { SINGLE_DOT_PATH_SEGMENT, compareModulesByIdentifier, getUndoPath, + BASE_URI, } = require("./utils"); /** @typedef {import("schema-utils/declarations/validate").Schema} Schema */ @@ -1372,6 +1373,7 @@ class MiniCssExtractPlugin { const undoPath = getUndoPath(filename, compiler.outputPath, false); + // replacements content = content.replace(new RegExp(ABSOLUTE_PUBLIC_PATH, "g"), ""); content = content.replace( new RegExp(SINGLE_DOT_PATH_SEGMENT, "g"), @@ -1379,6 +1381,14 @@ class MiniCssExtractPlugin { ); content = content.replace(new RegExp(AUTO_PUBLIC_PATH, "g"), undoPath); + const entryOptions = chunk.getEntryOptions(); + const baseUriReplacement = + (entryOptions && entryOptions.baseUri) || undoPath; + content = content.replace( + new RegExp(BASE_URI, "g"), + baseUriReplacement + ); + if (module.sourceMap) { source.add( new SourceMapSource( diff --git a/src/loader.js b/src/loader.js index 885c2828..7aacf582 100644 --- a/src/loader.js +++ b/src/loader.js @@ -5,6 +5,7 @@ const { evalModuleCode, AUTO_PUBLIC_PATH, ABSOLUTE_PUBLIC_PATH, + BASE_URI, SINGLE_DOT_PATH_SEGMENT, stringifyRequest, } = require("./utils"); @@ -300,6 +301,7 @@ function pitch(request) { { layer: options.layer, publicPath: /** @type {string} */ (publicPathForExtract), + baseUri: `${BASE_URI}/`, }, /** * @param {Error | null | undefined} error diff --git a/src/utils.js b/src/utils.js index 2784f8ee..416b38c1 100644 --- a/src/utils.js +++ b/src/utils.js @@ -86,6 +86,7 @@ function compareModulesByIdentifier(a, b) { const MODULE_TYPE = "css/mini-extract"; const AUTO_PUBLIC_PATH = "__mini_css_extract_plugin_public_path_auto__"; const ABSOLUTE_PUBLIC_PATH = "webpack:///mini-css-extract-plugin/"; +const BASE_URI = "webpack://"; const SINGLE_DOT_PATH_SEGMENT = "__mini_css_extract_plugin_single_dot_path_segment__"; @@ -212,6 +213,7 @@ module.exports = { MODULE_TYPE, AUTO_PUBLIC_PATH, ABSOLUTE_PUBLIC_PATH, + BASE_URI, SINGLE_DOT_PATH_SEGMENT, stringifyRequest, getUndoPath, diff --git a/test/cases/base-uri-in-entry/expected/webpack-5-importModule/asset/roboto-v18-latin-300.ttf b/test/cases/base-uri-in-entry/expected/webpack-5-importModule/asset/roboto-v18-latin-300.ttf new file mode 100644 index 00000000..a22188ee Binary files /dev/null and b/test/cases/base-uri-in-entry/expected/webpack-5-importModule/asset/roboto-v18-latin-300.ttf differ diff --git a/test/cases/base-uri-in-entry/expected/webpack-5-importModule/index.css b/test/cases/base-uri-in-entry/expected/webpack-5-importModule/index.css new file mode 100644 index 00000000..67fd017a --- /dev/null +++ b/test/cases/base-uri-in-entry/expected/webpack-5-importModule/index.css @@ -0,0 +1,7 @@ +@font-face { + font-family: Roboto-plp; + font-style: normal; + font-weight: 400; + src: url(my-scheme://uri/assets/asset/roboto-v18-latin-300.ttf) format("truetype"); +} + diff --git a/test/cases/base-uri-in-entry/expected/webpack-5-importModule/index.mjs b/test/cases/base-uri-in-entry/expected/webpack-5-importModule/index.mjs new file mode 100644 index 00000000..7a7efa51 --- /dev/null +++ b/test/cases/base-uri-in-entry/expected/webpack-5-importModule/index.mjs @@ -0,0 +1,3 @@ +var __webpack_exports__ = {}; + + diff --git a/test/cases/base-uri-in-entry/expected/webpack-5/asset/roboto-v18-latin-300.ttf b/test/cases/base-uri-in-entry/expected/webpack-5/asset/roboto-v18-latin-300.ttf new file mode 100644 index 00000000..a22188ee Binary files /dev/null and b/test/cases/base-uri-in-entry/expected/webpack-5/asset/roboto-v18-latin-300.ttf differ diff --git a/test/cases/base-uri-in-entry/expected/webpack-5/index.css b/test/cases/base-uri-in-entry/expected/webpack-5/index.css new file mode 100644 index 00000000..b8de74d0 --- /dev/null +++ b/test/cases/base-uri-in-entry/expected/webpack-5/index.css @@ -0,0 +1,7 @@ +@font-face { + font-family: Roboto-plp; + font-style: normal; + font-weight: 400; + src: url(/assets/asset/roboto-v18-latin-300.ttf) format("truetype"); +} + diff --git a/test/cases/base-uri-in-entry/expected/webpack-5/index.mjs b/test/cases/base-uri-in-entry/expected/webpack-5/index.mjs new file mode 100644 index 00000000..7a7efa51 --- /dev/null +++ b/test/cases/base-uri-in-entry/expected/webpack-5/index.mjs @@ -0,0 +1,3 @@ +var __webpack_exports__ = {}; + + diff --git a/test/cases/base-uri-in-entry/fonts/roboto-v18-latin-300.ttf b/test/cases/base-uri-in-entry/fonts/roboto-v18-latin-300.ttf new file mode 100644 index 00000000..a22188ee Binary files /dev/null and b/test/cases/base-uri-in-entry/fonts/roboto-v18-latin-300.ttf differ diff --git a/test/cases/base-uri-in-entry/index.js b/test/cases/base-uri-in-entry/index.js new file mode 100644 index 00000000..1bebc0ca --- /dev/null +++ b/test/cases/base-uri-in-entry/index.js @@ -0,0 +1 @@ +import "./main.css"; diff --git a/test/cases/base-uri-in-entry/main.css b/test/cases/base-uri-in-entry/main.css new file mode 100644 index 00000000..fe723a22 --- /dev/null +++ b/test/cases/base-uri-in-entry/main.css @@ -0,0 +1,6 @@ +@font-face { + font-family: Roboto-plp; + font-style: normal; + font-weight: 400; + src: url("./fonts/roboto-v18-latin-300.ttf") format("truetype"); +} diff --git a/test/cases/base-uri-in-entry/webpack.config.js b/test/cases/base-uri-in-entry/webpack.config.js new file mode 100644 index 00000000..b1d82c60 --- /dev/null +++ b/test/cases/base-uri-in-entry/webpack.config.js @@ -0,0 +1,48 @@ +import Self from "../../../src"; + +/** + * @type {import('webpack').Configuration} + */ +module.exports = { + mode: "production", + devtool: false, + entry: { + index: { + import: "./index.js", + baseUri: "my-scheme://uri", + }, + }, + optimization: { + minimize: false, + }, + output: { + module: true, + assetModuleFilename: "asset/[name][ext]", + chunkFormat: "module", + chunkLoading: "import", + }, + experiments: { + outputModule: true, + }, + module: { + rules: [ + { + test: /\.css$/i, + use: [ + { + loader: Self.loader, + }, + "css-loader", + ], + }, + { + test: /\.ttf$/i, + type: "asset/resource", + generator: { + publicPath: "/assets/", + }, + }, + ], + }, + plugins: [new Self({ experimentalUseImportModule: true })], +}; diff --git a/test/cases/base-uri/expected/asset/roboto-v18-latin-300.ttf b/test/cases/base-uri/expected/asset/roboto-v18-latin-300.ttf new file mode 100644 index 00000000..a22188ee Binary files /dev/null and b/test/cases/base-uri/expected/asset/roboto-v18-latin-300.ttf differ diff --git a/test/cases/base-uri/expected/index.css b/test/cases/base-uri/expected/index.css new file mode 100644 index 00000000..b8de74d0 --- /dev/null +++ b/test/cases/base-uri/expected/index.css @@ -0,0 +1,7 @@ +@font-face { + font-family: Roboto-plp; + font-style: normal; + font-weight: 400; + src: url(/assets/asset/roboto-v18-latin-300.ttf) format("truetype"); +} + diff --git a/test/cases/base-uri/expected/index.mjs b/test/cases/base-uri/expected/index.mjs new file mode 100644 index 00000000..7a7efa51 --- /dev/null +++ b/test/cases/base-uri/expected/index.mjs @@ -0,0 +1,3 @@ +var __webpack_exports__ = {}; + + diff --git a/test/cases/base-uri/fonts/roboto-v18-latin-300.ttf b/test/cases/base-uri/fonts/roboto-v18-latin-300.ttf new file mode 100644 index 00000000..a22188ee Binary files /dev/null and b/test/cases/base-uri/fonts/roboto-v18-latin-300.ttf differ diff --git a/test/cases/base-uri/index.js b/test/cases/base-uri/index.js new file mode 100644 index 00000000..1bebc0ca --- /dev/null +++ b/test/cases/base-uri/index.js @@ -0,0 +1 @@ +import "./main.css"; diff --git a/test/cases/base-uri/main.css b/test/cases/base-uri/main.css new file mode 100644 index 00000000..fe723a22 --- /dev/null +++ b/test/cases/base-uri/main.css @@ -0,0 +1,6 @@ +@font-face { + font-family: Roboto-plp; + font-style: normal; + font-weight: 400; + src: url("./fonts/roboto-v18-latin-300.ttf") format("truetype"); +} diff --git a/test/cases/base-uri/webpack.config.js b/test/cases/base-uri/webpack.config.js new file mode 100644 index 00000000..7027b9d5 --- /dev/null +++ b/test/cases/base-uri/webpack.config.js @@ -0,0 +1,45 @@ +import Self from "../../../src"; + +/** + * @type {import('webpack').Configuration} + */ +module.exports = { + mode: "production", + devtool: false, + entry: { + index: "./index.js", + }, + optimization: { + minimize: false, + }, + output: { + module: true, + assetModuleFilename: "asset/[name][ext]", + chunkFormat: "module", + chunkLoading: "import", + }, + experiments: { + outputModule: true, + }, + module: { + rules: [ + { + test: /\.css$/i, + use: [ + { + loader: Self.loader, + }, + "css-loader", + ], + }, + { + test: /\.ttf$/i, + type: "asset/resource", + generator: { + publicPath: "/assets/", + }, + }, + ], + }, + plugins: [new Self({ experimentalUseImportModule: true })], +}; diff --git a/types/utils.d.ts b/types/utils.d.ts index 6653c58c..3f8cb8ee 100644 --- a/types/utils.d.ts +++ b/types/utils.d.ts @@ -37,6 +37,7 @@ export function compareModulesByIdentifier(a: Module, b: Module): 0 | 1 | -1; export const MODULE_TYPE: "css/mini-extract"; export const AUTO_PUBLIC_PATH: "__mini_css_extract_plugin_public_path_auto__"; export const ABSOLUTE_PUBLIC_PATH: "webpack:///mini-css-extract-plugin/"; +export const BASE_URI: "webpack://"; export const SINGLE_DOT_PATH_SEGMENT: "__mini_css_extract_plugin_single_dot_path_segment__"; /** * @param {LoaderContext} loaderContext