Reuse arrays in visitor keys (#18386)
This commit is contained in:
1 parent
c45fef106e
commit
d3eb2b2d08
21 files changed
+273
-60
No files matched your search
@@ -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;
|
||||
},
|
||||
|
||||
@@ -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 };
|
||||
},
|
||||
);
|
||||
|
||||
Reference in new issue
Block a user