diff --git a/README.md b/README.md
index d1130dee..ef342341 100644
--- a/README.md
+++ b/README.md
@@ -97,7 +97,7 @@ type sources =
Default: `true`
-By default every loadable attribute (for example - ``) is imported (`const img = require('./image.png')` or `import img from "./image.png""`).
+By default every loadable attribute (for example - ``) is imported (`const img = require('./image.png')` or `new URL("./image.png", import.meta.url)`).
You may need to specify loaders for images in your configuration (recommended [`asset modules`](https://webpack.js.org/guides/asset-modules/)).
Supported tags and attributes:
diff --git a/src/index.js b/src/index.js
index 36920f01..f98efda2 100644
--- a/src/index.js
+++ b/src/index.js
@@ -24,9 +24,23 @@ export default async function loader(content) {
const imports = [];
const replacements = [];
+ let isSupportAbsoluteURL = false;
+
+ // TODO enable by default in the next major release
+ if (
+ this._compilation &&
+ this._compilation.options &&
+ this._compilation.options.experiments &&
+ this._compilation.options.experiments.buildHttp
+ ) {
+ isSupportAbsoluteURL = true;
+ }
+
if (options.sources) {
plugins.push(
sourcesPlugin({
+ isSupportAbsoluteURL,
+ isSupportDataURL: options.esModule,
sources: options.sources,
resourcePath: this.resourcePath,
context: this.context,
diff --git a/src/plugins/sources-plugin.js b/src/plugins/sources-plugin.js
index 5aec1d9b..c4759d4e 100644
--- a/src/plugins/sources-plugin.js
+++ b/src/plugins/sources-plugin.js
@@ -98,6 +98,8 @@ export default (options) =>
attributeStartOffset: sourceCodeLocation.attrs[name].startOffset,
attributeEndOffset: sourceCodeLocation.attrs[name].endOffset,
value: attribute.value,
+ isSupportAbsoluteURL: options.isSupportAbsoluteURL,
+ isSupportDataURL: options.isSupportDataURL,
isValueQuoted,
valueEndOffset,
valueStartOffset,
diff --git a/src/utils.js b/src/utils.js
index 41a2a361..81dc9c0f 100644
--- a/src/utils.js
+++ b/src/utils.js
@@ -378,7 +378,15 @@ export function parseSrc(input) {
const WINDOWS_ABS_PATH_REGEXP = /^[a-zA-Z]:[\\/]|^\\\\/;
-export function isUrlRequestable(url) {
+function isDataUrl(url) {
+ if (/^data:/i.test(url)) {
+ return true;
+ }
+
+ return false;
+}
+
+export function isURLRequestable(url, options = {}) {
// Protocol-relative URLs
if (/^\/\//.test(url)) {
return false;
@@ -389,8 +397,26 @@ export function isUrlRequestable(url) {
return true;
}
+ if (isDataUrl(url) && options.isSupportDataURL) {
+ try {
+ decodeURIComponent(url);
+ } catch (ignoreError) {
+ return false;
+ }
+
+ return true;
+ }
+
+ if (/^file:/i.test(url)) {
+ return true;
+ }
+
// Absolute URLs
if (/^[a-z][a-z0-9+.-]*:/i.test(url) && !WINDOWS_ABS_PATH_REGEXP.test(url)) {
+ if (/^https?:/i.test(url)) {
+ return options.isSupportAbsoluteURL;
+ }
+
return false;
}
@@ -483,7 +509,7 @@ export function requestify(context, request) {
return newRequest;
}
- if (/^file:/i.test(newRequest)) {
+ if (/^[a-z]+:/i.test(newRequest)) {
return newRequest;
}
@@ -710,7 +736,12 @@ export function srcType(options) {
);
}
- if (!isUrlRequestable(source.value)) {
+ if (
+ !isURLRequestable(source.value, {
+ isSupportDataURL: options.isSupportDataURL,
+ isSupportAbsoluteURL: options.isSupportAbsoluteURL,
+ })
+ ) {
return [];
}
@@ -750,7 +781,12 @@ export function srcsetType(options) {
);
}
- if (!isUrlRequestable(source.value)) {
+ if (
+ !isURLRequestable(source.value, {
+ isSupportDataURL: options.isSupportDataURL,
+ isSupportAbsoluteURL: options.isSupportAbsoluteURL,
+ })
+ ) {
return false;
}
@@ -832,53 +868,6 @@ function metaContentType(options) {
return srcType(options);
}
-// function webpackImportType(options) {
-// let source;
-//
-// try {
-// source = trimASCIIWhitespace(options.value);
-// } catch (error) {
-// throw new HtmlSourceError(
-// `Bad value for attribute "${options.attribute}" on element "${options.tag}": ${error.message}`,
-// options.attributeStartOffset,
-// options.attributeEndOffset,
-// options.html
-// );
-// }
-//
-// try {
-// source = c0ControlCodesExclude(source);
-// } catch (error) {
-// throw new HtmlSourceError(
-// `Bad value for attribute "${options.attribute}" on element "${options.tag}": ${error.message}`,
-// options.attributeStartOffset,
-// options.attributeEndOffset,
-// options.html
-// );
-// }
-//
-// if (!isUrlRequestable(source.value)) {
-// return [];
-// }
-//
-// const { startOffset } = options.startTag;
-// let { endOffset } = options.startTag;
-//
-// if (options.endTag) {
-// ({ endOffset } = options.endTag);
-// }
-//
-// return [
-// {
-// format: 'import',
-// runtime: false,
-// value: source.value,
-// startOffset,
-// endOffset,
-// },
-// ];
-// }
-
const defaultSources = new Map([
[
"audio",
diff --git a/test/__snapshots__/esModule-option.test.js.snap b/test/__snapshots__/esModule-option.test.js.snap
index 4cb00359..e4a261f3 100644
--- a/test/__snapshots__/esModule-option.test.js.snap
+++ b/test/__snapshots__/esModule-option.test.js.snap
@@ -16,20 +16,22 @@ var ___HTML_LOADER_IMPORT_7___ = new URL("./example.ogg", import.meta.url);
var ___HTML_LOADER_IMPORT_8___ = new URL("./example.pdf", import.meta.url);
var ___HTML_LOADER_IMPORT_9___ = new URL("./example.vtt", import.meta.url);
var ___HTML_LOADER_IMPORT_10___ = new URL("./style.file.css", import.meta.url);
-var ___HTML_LOADER_IMPORT_11___ = new URL("./image image.png", import.meta.url);
-var ___HTML_LOADER_IMPORT_12___ = new URL("./module.file.js", import.meta.url);
-var ___HTML_LOADER_IMPORT_13___ = new URL("./fallback.file.js", import.meta.url);
-var ___HTML_LOADER_IMPORT_14___ = new URL("aliasImageWithSpace", import.meta.url);
-var ___HTML_LOADER_IMPORT_15___ = new URL("./webpack.svg", import.meta.url);
-var ___HTML_LOADER_IMPORT_16___ = new URL("./pixel.png?url", import.meta.url);
-var ___HTML_LOADER_IMPORT_17___ = new URL("./site.webmanifest", import.meta.url);
-var ___HTML_LOADER_IMPORT_18___ = new URL("./browserconfig.xml", import.meta.url);
-var ___HTML_LOADER_IMPORT_19___ = new URL("./favicon.ico", import.meta.url);
-var ___HTML_LOADER_IMPORT_20___ = new URL("./sound.mp3", import.meta.url);
-var ___HTML_LOADER_IMPORT_21___ = new URL("./video.mp4", import.meta.url);
-var ___HTML_LOADER_IMPORT_22___ = new URL("./nested/image3.png", import.meta.url);
-var ___HTML_LOADER_IMPORT_23___ = new URL("/nested/image3.png", import.meta.url);
-var ___HTML_LOADER_IMPORT_24___ = new URL("./noscript.png", import.meta.url);
+var ___HTML_LOADER_IMPORT_11___ = new URL("data:image/png;base64, iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==", import.meta.url);
+var ___HTML_LOADER_IMPORT_12___ = new URL("./image image.png", import.meta.url);
+var ___HTML_LOADER_IMPORT_13___ = new URL("./module.file.js", import.meta.url);
+var ___HTML_LOADER_IMPORT_14___ = new URL("./fallback.file.js", import.meta.url);
+var ___HTML_LOADER_IMPORT_15___ = new URL("aliasImageWithSpace", import.meta.url);
+var ___HTML_LOADER_IMPORT_16___ = new URL("./webpack.svg", import.meta.url);
+var ___HTML_LOADER_IMPORT_17___ = new URL("./pixel.png?url", import.meta.url);
+var ___HTML_LOADER_IMPORT_18___ = new URL("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAUAAAAFCAYAAACNbyblAAAAHElEQVQI12P4//8/w38GIAXDIBKE0DHxgljNBAAO9TXL0Y4OHwAAAABJRU5ErkJggg==", import.meta.url);
+var ___HTML_LOADER_IMPORT_19___ = new URL("./site.webmanifest", import.meta.url);
+var ___HTML_LOADER_IMPORT_20___ = new URL("./browserconfig.xml", import.meta.url);
+var ___HTML_LOADER_IMPORT_21___ = new URL("./favicon.ico", import.meta.url);
+var ___HTML_LOADER_IMPORT_22___ = new URL("./sound.mp3", import.meta.url);
+var ___HTML_LOADER_IMPORT_23___ = new URL("./video.mp4", import.meta.url);
+var ___HTML_LOADER_IMPORT_24___ = new URL("./nested/image3.png", import.meta.url);
+var ___HTML_LOADER_IMPORT_25___ = new URL("/nested/image3.png", import.meta.url);
+var ___HTML_LOADER_IMPORT_26___ = new URL("./noscript.png", import.meta.url);
// Module
var ___HTML_LOADER_REPLACEMENT_0___ = ___HTML_LOADER_GET_SOURCE_FROM_IMPORT___(___HTML_LOADER_IMPORT_0___);
var ___HTML_LOADER_REPLACEMENT_1___ = ___HTML_LOADER_GET_SOURCE_FROM_IMPORT___(___HTML_LOADER_IMPORT_0___, { maybeNeedQuotes: true });
@@ -46,16 +48,16 @@ var ___HTML_LOADER_REPLACEMENT_11___ = ___HTML_LOADER_GET_SOURCE_FROM_IMPORT___(
var ___HTML_LOADER_REPLACEMENT_12___ = ___HTML_LOADER_GET_SOURCE_FROM_IMPORT___(___HTML_LOADER_IMPORT_11___);
var ___HTML_LOADER_REPLACEMENT_13___ = ___HTML_LOADER_GET_SOURCE_FROM_IMPORT___(___HTML_LOADER_IMPORT_12___);
var ___HTML_LOADER_REPLACEMENT_14___ = ___HTML_LOADER_GET_SOURCE_FROM_IMPORT___(___HTML_LOADER_IMPORT_13___);
-var ___HTML_LOADER_REPLACEMENT_15___ = ___HTML_LOADER_GET_SOURCE_FROM_IMPORT___(___HTML_LOADER_IMPORT_14___, { maybeNeedQuotes: true });
-var ___HTML_LOADER_REPLACEMENT_16___ = ___HTML_LOADER_GET_SOURCE_FROM_IMPORT___(___HTML_LOADER_IMPORT_14___);
-var ___HTML_LOADER_REPLACEMENT_17___ = ___HTML_LOADER_GET_SOURCE_FROM_IMPORT___(___HTML_LOADER_IMPORT_0___, { hash: "#hash" });
-var ___HTML_LOADER_REPLACEMENT_18___ = ___HTML_LOADER_GET_SOURCE_FROM_IMPORT___(___HTML_LOADER_IMPORT_0___, { hash: "#hash", maybeNeedQuotes: true });
-var ___HTML_LOADER_REPLACEMENT_19___ = ___HTML_LOADER_GET_SOURCE_FROM_IMPORT___(___HTML_LOADER_IMPORT_0___, { hash: "#", maybeNeedQuotes: true });
-var ___HTML_LOADER_REPLACEMENT_20___ = ___HTML_LOADER_GET_SOURCE_FROM_IMPORT___(___HTML_LOADER_IMPORT_0___, { hash: "#foo" });
-var ___HTML_LOADER_REPLACEMENT_21___ = ___HTML_LOADER_GET_SOURCE_FROM_IMPORT___(___HTML_LOADER_IMPORT_0___, { hash: "#bar" });
-var ___HTML_LOADER_REPLACEMENT_22___ = ___HTML_LOADER_GET_SOURCE_FROM_IMPORT___(___HTML_LOADER_IMPORT_0___, { hash: "#baz" });
-var ___HTML_LOADER_REPLACEMENT_23___ = ___HTML_LOADER_GET_SOURCE_FROM_IMPORT___(___HTML_LOADER_IMPORT_14___, { hash: "#hash", maybeNeedQuotes: true });
-var ___HTML_LOADER_REPLACEMENT_24___ = ___HTML_LOADER_GET_SOURCE_FROM_IMPORT___(___HTML_LOADER_IMPORT_15___);
+var ___HTML_LOADER_REPLACEMENT_15___ = ___HTML_LOADER_GET_SOURCE_FROM_IMPORT___(___HTML_LOADER_IMPORT_14___);
+var ___HTML_LOADER_REPLACEMENT_16___ = ___HTML_LOADER_GET_SOURCE_FROM_IMPORT___(___HTML_LOADER_IMPORT_15___, { maybeNeedQuotes: true });
+var ___HTML_LOADER_REPLACEMENT_17___ = ___HTML_LOADER_GET_SOURCE_FROM_IMPORT___(___HTML_LOADER_IMPORT_15___);
+var ___HTML_LOADER_REPLACEMENT_18___ = ___HTML_LOADER_GET_SOURCE_FROM_IMPORT___(___HTML_LOADER_IMPORT_0___, { hash: "#hash" });
+var ___HTML_LOADER_REPLACEMENT_19___ = ___HTML_LOADER_GET_SOURCE_FROM_IMPORT___(___HTML_LOADER_IMPORT_0___, { hash: "#hash", maybeNeedQuotes: true });
+var ___HTML_LOADER_REPLACEMENT_20___ = ___HTML_LOADER_GET_SOURCE_FROM_IMPORT___(___HTML_LOADER_IMPORT_0___, { hash: "#", maybeNeedQuotes: true });
+var ___HTML_LOADER_REPLACEMENT_21___ = ___HTML_LOADER_GET_SOURCE_FROM_IMPORT___(___HTML_LOADER_IMPORT_0___, { hash: "#foo" });
+var ___HTML_LOADER_REPLACEMENT_22___ = ___HTML_LOADER_GET_SOURCE_FROM_IMPORT___(___HTML_LOADER_IMPORT_0___, { hash: "#bar" });
+var ___HTML_LOADER_REPLACEMENT_23___ = ___HTML_LOADER_GET_SOURCE_FROM_IMPORT___(___HTML_LOADER_IMPORT_0___, { hash: "#baz" });
+var ___HTML_LOADER_REPLACEMENT_24___ = ___HTML_LOADER_GET_SOURCE_FROM_IMPORT___(___HTML_LOADER_IMPORT_15___, { hash: "#hash", maybeNeedQuotes: true });
var ___HTML_LOADER_REPLACEMENT_25___ = ___HTML_LOADER_GET_SOURCE_FROM_IMPORT___(___HTML_LOADER_IMPORT_16___);
var ___HTML_LOADER_REPLACEMENT_26___ = ___HTML_LOADER_GET_SOURCE_FROM_IMPORT___(___HTML_LOADER_IMPORT_17___);
var ___HTML_LOADER_REPLACEMENT_27___ = ___HTML_LOADER_GET_SOURCE_FROM_IMPORT___(___HTML_LOADER_IMPORT_18___);
@@ -65,7 +67,9 @@ var ___HTML_LOADER_REPLACEMENT_30___ = ___HTML_LOADER_GET_SOURCE_FROM_IMPORT___(
var ___HTML_LOADER_REPLACEMENT_31___ = ___HTML_LOADER_GET_SOURCE_FROM_IMPORT___(___HTML_LOADER_IMPORT_22___);
var ___HTML_LOADER_REPLACEMENT_32___ = ___HTML_LOADER_GET_SOURCE_FROM_IMPORT___(___HTML_LOADER_IMPORT_23___);
var ___HTML_LOADER_REPLACEMENT_33___ = ___HTML_LOADER_GET_SOURCE_FROM_IMPORT___(___HTML_LOADER_IMPORT_24___);
-var code = "\\n\\n
My First Heading
\\nMy first paragraph.
\\nAn Unordered HTML List
\\n\\n\\n - Coffee
\\n - Tea
\\n - Milk
\\n
\\n\\nAn Ordered HTML List
\\n\\n\\n - Coffee
\\n - Tea
\\n - Milk
\\n
\\n\\n<" + "script>console.log({\\"json\\": \\"with \\\\\\"quotes\\\\\\" in value\\"})<" + "/script>\\n\\n\\n\\nFoo
\\n\\n\\nBAR
\\n\\n\\n\\n<" + "script> console.log(1 + 2 + \`\${3 + 3}\`) <" + "/script>\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n<" + "script src=\\"" + ___HTML_LOADER_REPLACEMENT_4___ + "\\"><" + "/script>\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n\\n