From 61f9a69a60196abdc85afaa8658faf7736cf08a9 Mon Sep 17 00:00:00 2001
From: Alexander Akait <4567934+alexander-akait@users.noreply.github.com>
Date: Thu, 25 Jul 2024 18:50:52 +0300
Subject: [PATCH] feat: reduce runtime code
---
src/index.js | 5 +-
src/plugins/sources-plugin.js | 13 +-
src/runtime/getUrl.js | 16 +-
src/utils.js | 95 +-
.../esModule-option.test.js.snap | 1121 ++--
test/__snapshots__/loader.test.js.snap | 792 ++-
.../minimize-option.test.js.snap | 1262 ++---
.../postprocessor-option.test.js.snap | 12 +-
.../preprocessor-option.test.js.snap | 18 +-
.../__snapshots__/sources-option.test.js.snap | 4653 ++++++++---------
.../runtime/__snapshots__/getUrl.test.js.snap | 62 -
test/runtime/getUrl.test.js | 97 +-
12 files changed, 3540 insertions(+), 4606 deletions(-)
diff --git a/src/index.js b/src/index.js
index f67c0c4a..fff8dae7 100644
--- a/src/index.js
+++ b/src/index.js
@@ -80,8 +80,9 @@ export default async function loader(content) {
html = await options.postprocessor(html, this);
}
- const importCode = getImportCode(html, this, imports, options);
- const moduleCode = getModuleCode(html, replacements, {
+ const importCode = getImportCode(html, imports, options);
+ const moduleCode = getModuleCode(html, replacements, this, {
+ esModule: options.esModule,
isTemplateLiteralSupported,
});
const exportCode = getExportCode(html, options);
diff --git a/src/plugins/sources-plugin.js b/src/plugins/sources-plugin.js
index 28ce1d3c..9ed9eab8 100644
--- a/src/plugins/sources-plugin.js
+++ b/src/plugins/sources-plugin.js
@@ -139,15 +139,7 @@ export default (options) =>
let offset = 0;
for (const source of sources) {
- const {
- name,
- value,
- isValueQuoted,
- format,
- runtime,
- startOffset,
- endOffset,
- } = source;
+ const { name, value, isValueQuoted, startOffset, endOffset } = source;
let request = value;
@@ -172,7 +164,7 @@ export default (options) =>
importName = `___HTML_LOADER_IMPORT_${imports.size}___`;
imports.set(request, importName);
- options.imports.push({ format, importName, request });
+ options.imports.push({ importName, request });
}
const replacementKey = JSON.stringify({ request, isValueQuoted, hash });
@@ -187,7 +179,6 @@ export default (options) =>
importName,
hash,
isValueQuoted,
- runtime,
});
}
diff --git a/src/runtime/getUrl.js b/src/runtime/getUrl.js
index 2bc48ac9..f2b3b2cb 100644
--- a/src/runtime/getUrl.js
+++ b/src/runtime/getUrl.js
@@ -1,22 +1,12 @@
-module.exports = (url, options) => {
- if (!options) {
- // eslint-disable-next-line no-param-reassign
- options = {};
- }
-
+module.exports = (url, maybeNeedQuotes) => {
if (!url) {
return url;
}
// eslint-disable-next-line no-underscore-dangle, no-param-reassign
- url = String(url.__esModule ? url.default : url);
-
- if (options.hash) {
- // eslint-disable-next-line no-param-reassign
- url += options.hash;
- }
+ url = String(url);
- if (options.maybeNeedQuotes && /[\t\n\f\r "'=<>`]/.test(url)) {
+ if (maybeNeedQuotes && /[\t\n\f\r "'=<>`]/.test(url)) {
return `"${url}"`;
}
diff --git a/src/utils.js b/src/utils.js
index 4ed05467..fb2300e8 100644
--- a/src/utils.js
+++ b/src/utils.js
@@ -1218,43 +1218,21 @@ export function getFilter(filter) {
};
}
-const GET_SOURCE_FROM_IMPORT_NAME = "___HTML_LOADER_GET_SOURCE_FROM_IMPORT___";
-
-export function getImportCode(html, loaderContext, imports, options) {
+export function getImportCode(html, imports, options) {
if (imports.length === 0) {
return "";
}
- // TODO simplify in the next major release
- const getURLRuntime = require.resolve("./runtime/getUrl.js");
- const context = loaderContext.context || loaderContext.rootContext;
- const fileURLToHelper =
- typeof loaderContext.utils !== "undefined" &&
- typeof loaderContext.utils.contextify === "function"
- ? loaderContext.utils.contextify(context, getURLRuntime)
- : contextify(context, getURLRuntime);
-
- let code = options.esModule
- ? `import ${GET_SOURCE_FROM_IMPORT_NAME} from "${fileURLToHelper}";\n`
- : `var ${GET_SOURCE_FROM_IMPORT_NAME} = require("${fileURLToHelper}");\n`;
+ let code = "";
for (const item of imports) {
- const { format, importName, request } = item;
+ const { importName, request } = item;
- switch (format) {
- case "import":
- code += options.esModule
- ? `import ${importName} from ${JSON.stringify(request)};\n`
- : `var ${importName} = require(${JSON.stringify(request)});\n`;
- break;
- case "url":
- default:
- code += options.esModule
- ? `var ${importName} = new URL(${JSON.stringify(
- request,
- )}, import.meta.url);\n`
- : `var ${importName} = require(${JSON.stringify(request)});\n`;
- }
+ code += options.esModule
+ ? `var ${importName} = new URL(${JSON.stringify(
+ request,
+ )}, import.meta.url);\n`
+ : `var ${importName} = require(${JSON.stringify(request)});\n`;
}
return `// Imports\n${code}`;
@@ -1279,36 +1257,31 @@ export function convertToTemplateLiteral(str) {
return `\`${escapedString}\``;
}
-export function getModuleCode(html, replacements, options) {
+const GET_SOURCE_FROM_IMPORT_NAME = "___HTML_LOADER_GET_SOURCE_FROM_IMPORT___";
+
+export function getModuleCode(html, replacements, loaderContext, options) {
let code = html;
- let replacersCode = "";
const { isTemplateLiteralSupported } = options;
+ let needHelperImport = false;
+
for (const item of replacements) {
- const { runtime, importName, replacementName, isValueQuoted, hash } = item;
+ const { importName, replacementName, isValueQuoted, hash } = item;
- if (typeof runtime === "undefined" || runtime === true) {
- const getUrlOptions = []
- .concat(hash ? [`hash: ${JSON.stringify(hash)}`] : [])
- .concat(isValueQuoted ? [] : "maybeNeedQuotes: true");
- const preparedOptions =
- getUrlOptions.length > 0 ? `, { ${getUrlOptions.join(", ")} }` : "";
+ if (!isValueQuoted && !needHelperImport) {
+ needHelperImport = true;
+ }
- replacersCode += `var ${replacementName} = ${GET_SOURCE_FROM_IMPORT_NAME}(${importName}${preparedOptions});\n`;
+ const name = !isValueQuoted
+ ? `${GET_SOURCE_FROM_IMPORT_NAME}(${importName}${!isValueQuoted ? ", true" : ""})`
+ : importName;
- code = code.replace(new RegExp(replacementName, "g"), () =>
- isTemplateLiteralSupported
- ? `\${${replacementName}}`
- : `" + ${replacementName} + "`,
- );
- } else {
- code = code.replace(new RegExp(replacementName, "g"), () =>
- isTemplateLiteralSupported
- ? `\${${replacementName}}`
- : `" + ${replacementName} + "`,
- );
- }
+ code = code.replace(new RegExp(replacementName, "g"), () =>
+ isTemplateLiteralSupported
+ ? `\${${name}}${typeof hash !== "undefined" ? hash : ""}`
+ : `" + ${name}${typeof hash !== "undefined" ? ` + ${JSON.stringify(hash)}` : ""} + "`,
+ );
}
// Replaces "" to "<" + "script>" or "<" + "/script>".
@@ -1316,7 +1289,23 @@ export function getModuleCode(html, replacements, options) {
isTemplateLiteralSupported ? `\${"<" + "${s}"}` : `<" + "${s}`,
);
- return `// Module\n${replacersCode}var code = ${code};\n`;
+ code = `// Module\nvar code = ${code};\n`;
+
+ if (needHelperImport) {
+ // TODO simplify in the next major release
+ const getURLRuntime = require.resolve("./runtime/getUrl.js");
+ const context = loaderContext.context || loaderContext.rootContext;
+ const fileURLToHelper =
+ typeof loaderContext.utils !== "undefined" &&
+ typeof loaderContext.utils.contextify === "function"
+ ? loaderContext.utils.contextify(context, getURLRuntime)
+ : contextify(context, getURLRuntime);
+ code = options.esModule
+ ? `import ${GET_SOURCE_FROM_IMPORT_NAME} from "${fileURLToHelper}";\n${code}`
+ : `var ${GET_SOURCE_FROM_IMPORT_NAME} = require("${fileURLToHelper}");\n${code}`;
+ }
+
+ return code;
}
export function getExportCode(html, options) {
diff --git a/test/__snapshots__/esModule-option.test.js.snap b/test/__snapshots__/esModule-option.test.js.snap
index 6fc82434..b9adfd40 100644
--- a/test/__snapshots__/esModule-option.test.js.snap
+++ b/test/__snapshots__/esModule-option.test.js.snap
@@ -4,7 +4,6 @@ exports[`'esModule' option should use a CommonJS export by default: errors 1`] =
exports[`'esModule' option should use a CommonJS export by default: module 1`] = `
"// Imports
-import ___HTML_LOADER_GET_SOURCE_FROM_IMPORT___ from "../../src/runtime/getUrl.js";
var ___HTML_LOADER_IMPORT_0___ = new URL("./image.png", import.meta.url);
var ___HTML_LOADER_IMPORT_1___ = new URL("/image.png", import.meta.url);
var ___HTML_LOADER_IMPORT_2___ = new URL("aliasImg", import.meta.url);
@@ -33,44 +32,8 @@ 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);
var ___HTML_LOADER_IMPORT_27___ = new URL("./😀abc.png", import.meta.url);
+import ___HTML_LOADER_GET_SOURCE_FROM_IMPORT___ from "../../src/runtime/getUrl.js";
// 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 });
-var ___HTML_LOADER_REPLACEMENT_2___ = ___HTML_LOADER_GET_SOURCE_FROM_IMPORT___(___HTML_LOADER_IMPORT_1___);
-var ___HTML_LOADER_REPLACEMENT_3___ = ___HTML_LOADER_GET_SOURCE_FROM_IMPORT___(___HTML_LOADER_IMPORT_2___);
-var ___HTML_LOADER_REPLACEMENT_4___ = ___HTML_LOADER_GET_SOURCE_FROM_IMPORT___(___HTML_LOADER_IMPORT_3___);
-var ___HTML_LOADER_REPLACEMENT_5___ = ___HTML_LOADER_GET_SOURCE_FROM_IMPORT___(___HTML_LOADER_IMPORT_4___, { hash: "#icon-chevron-with-circle-up" });
-var ___HTML_LOADER_REPLACEMENT_6___ = ___HTML_LOADER_GET_SOURCE_FROM_IMPORT___(___HTML_LOADER_IMPORT_5___);
-var ___HTML_LOADER_REPLACEMENT_7___ = ___HTML_LOADER_GET_SOURCE_FROM_IMPORT___(___HTML_LOADER_IMPORT_6___);
-var ___HTML_LOADER_REPLACEMENT_8___ = ___HTML_LOADER_GET_SOURCE_FROM_IMPORT___(___HTML_LOADER_IMPORT_7___);
-var ___HTML_LOADER_REPLACEMENT_9___ = ___HTML_LOADER_GET_SOURCE_FROM_IMPORT___(___HTML_LOADER_IMPORT_8___);
-var ___HTML_LOADER_REPLACEMENT_10___ = ___HTML_LOADER_GET_SOURCE_FROM_IMPORT___(___HTML_LOADER_IMPORT_9___);
-var ___HTML_LOADER_REPLACEMENT_11___ = ___HTML_LOADER_GET_SOURCE_FROM_IMPORT___(___HTML_LOADER_IMPORT_10___);
-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___);
-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___);
-var ___HTML_LOADER_REPLACEMENT_28___ = ___HTML_LOADER_GET_SOURCE_FROM_IMPORT___(___HTML_LOADER_IMPORT_19___);
-var ___HTML_LOADER_REPLACEMENT_29___ = ___HTML_LOADER_GET_SOURCE_FROM_IMPORT___(___HTML_LOADER_IMPORT_20___);
-var ___HTML_LOADER_REPLACEMENT_30___ = ___HTML_LOADER_GET_SOURCE_FROM_IMPORT___(___HTML_LOADER_IMPORT_21___);
-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 ___HTML_LOADER_REPLACEMENT_34___ = ___HTML_LOADER_GET_SOURCE_FROM_IMPORT___(___HTML_LOADER_IMPORT_25___);
-var ___HTML_LOADER_REPLACEMENT_35___ = ___HTML_LOADER_GET_SOURCE_FROM_IMPORT___(___HTML_LOADER_IMPORT_26___);
-var ___HTML_LOADER_REPLACEMENT_36___ = ___HTML_LOADER_GET_SOURCE_FROM_IMPORT___(___HTML_LOADER_IMPORT_27___);
var code = \`
My First Heading
@@ -104,134 +67,134 @@ var code = \`
\${"<" + "script"}> console.log(1 + 2 + \\\`\\\${3 + 3}\\\`) \${"<" + "/script"}>
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
-\${"<" + "script"} src="\${___HTML_LOADER_REPLACEMENT_4___}">\${"<" + "/script"}>
+\${"<" + "script"} src="\${___HTML_LOADER_IMPORT_3___}">\${"<" + "/script"}>
-
+
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+" src="\${___HTML_LOADER_IMPORT_0___}" alt="Elva dressed as a fairy">
-