Reuse arrays in visitor keys (#18386)

This commit is contained in:
fisker Cheung authored and GitHub committed 2025-12-01 19:33:56 +08:00
1 parent c45fef106e
commit d3eb2b2d08
21 files changed
+273 -60

No files matched your search

+4 -1
View File
@@ -598,7 +598,10 @@ const pluginFiles = [
"const LOCAL_DEBUG = false &&",
);
text = text.replace(/(?<=\n)export .*?;/u, "export { preprocess };");
text = text.replace(
/(?<=\n)export .*?;/u,
"export { preprocess, getVoidTags, visitorKeys };",
);
return text;
},
+74 -18
View File
@@ -1,33 +1,89 @@
import assert from "node:assert";
import path from "node:path";
import url from "node:url";
import { isValidIdentifier } from "@babel/types";
import { outdent } from "outdent";
import serialize from "serialize-javascript";
function serializeModule(module) {
return Object.entries(module)
.map(([specifier, value]) => {
const code =
value instanceof RegExp
? `/${value.source}/${value.flags}`
: serialize(value, { space: 2, unsafe: true });
if (specifier === "default") {
return `export default ${code};`;
}
if (!isValidIdentifier(specifier)) {
throw new Error(`${specifier} is not a valid specifier`);
}
return `export const ${specifier} = ${code};`;
})
.join("\n");
}
function serializeVisitorKeys(module) {
const specifiers = Object.keys(module);
assert.deepEqual(specifiers, ["default"]);
const references = new Map();
const properties = Object.entries(module.default);
for (const [, keys] of properties) {
if (!references.has(keys)) {
references.set(keys, 1);
} else {
references.set(keys, references.get(keys) + 1);
}
}
const variables = [];
const propertiesText = [];
for (const [type, keys] of properties) {
const isSingleReference = references.get(keys) === 1;
const key = isValidIdentifier(type) ? type : JSON.stringify(type);
if (isSingleReference) {
propertiesText.push(` ${key}: ${JSON.stringify(keys)},`);
} else {
if (!variables.includes(keys)) {
variables.push(keys);
}
const index = variables.indexOf(keys);
propertiesText.push(` ${key}: vk[${index}],`);
}
}
const code = outdent`
const vk = [
${variables.map((keys) => ` ${JSON.stringify(keys)},`).join("\n")}
];
export default {
${propertiesText.join("\n")}
};
`;
return code;
}
export default function esbuildPluginEvaluate() {
return {
name: "evaluate",
setup(build) {
build.onLoad(
{ filter: /\.evaluate\.[cm]?js$/, namespace: "file" },
async ({ path }) => {
const module = await import(url.pathToFileURL(path));
const text = Object.entries(module)
.map(([specifier, value]) => {
const code =
value instanceof RegExp
? `/${value.source}/${value.flags}`
: serialize(value, { space: 2 });
async ({ path: filePath }) => {
const module = await import(url.pathToFileURL(filePath));
const isVisitorKeys =
path.basename(filePath, path.extname(filePath)) ===
"visitor-keys.evaluate";
if (specifier === "default") {
return `export default ${code};`;
}
const text = isVisitorKeys
? serializeVisitorKeys(module)
: serializeModule(module);
if (!isValidIdentifier(specifier)) {
throw new Error(`${specifier} is not a valid specifier`);
}
return `export const ${specifier} = ${code};`;
})
.join("\n");
return { contents: text };
},
);