esbuild-plugin-extract-helpers
Version:
Esbuild plugin to extract cjs helpers (like tslib)
109 lines (108 loc) • 3.06 kB
JavaScript
// src/main/ts/plugin.ts
import path from "node:path";
import fs from "node:fs/promises";
import {
transformFile,
writeFiles,
getOutputFiles,
renderList,
parseContentsLayout
} from "esbuild-plugin-utils";
var extractHelpersPlugin = (options = {}) => {
return {
name: "extract-helpers",
setup(build) {
const {
absWorkingDir = process.cwd(),
outdir,
cwd = outdir || absWorkingDir,
include = /./,
exclude = /^$/,
helper = "esblib.cjs"
} = { ...build.initialOptions, ...options };
const opts = {
cwd,
include,
exclude,
helper
};
build.onEnd(async (result) => onEnd(result, opts));
}
};
};
var onEnd = async (result, opts) => {
const outputFiles = await getOutputFiles(result.outputFiles, opts.cwd);
const helpers = /* @__PURE__ */ new Map();
const helperRe = /^var (__\w+) = /;
const hook = {
on: "end",
pattern: opts.include,
// eslint-disable-next-line sonarjs/cognitive-complexity
transform(c, p) {
const { lines, header, body } = parseContentsLayout(c.trim());
const headerSize = header ? header.split("\n").length : 0;
const output = [];
const helperPath = getRelativePath(opts.cwd, p, opts.helper);
const capture = () => {
helpers.set(ref, helper);
helper = "";
ref = "";
};
let refs = [];
let helper = "";
let ref = "";
for (const line of lines.slice(headerSize)) {
if (ref) {
helper += line + "\n";
if (line.endsWith(";") && !line.startsWith(" ")) capture();
} else {
const match = helperRe.exec(line);
if (match) {
ref = match[1];
refs.push(ref);
helper = line + "\n";
if (line.endsWith(";")) capture();
} else {
output.push(line);
}
}
}
if (refs.length === 0) return c;
refs = refs.filter((r) => output.some((l) => l.includes(r)));
return formatFile(header, output, refs, helperPath);
}
};
const transformedFiles = (await Promise.all(outputFiles.map(async (file) => transformFile(file, [hook], opts.cwd)))).filter(Boolean);
await writeFiles(transformedFiles);
await fs.writeFile(path.join(opts.cwd, opts.helper), formatHelpers(helpers), "utf-8");
};
var getRelativePath = (from, to, ref) => {
const link = path.relative(from, path.join(path.dirname(to), ref));
return link.startsWith(".") ? link : "./" + link;
};
var formatHelpers = (helpers) => `
${[...helpers.values()].join("\n")}
module.exports = {
${renderList([...helpers.keys()])}
};
`;
var formatFile = (header, lines, refs, helperPath) => {
const body = lines.join("\n");
const helpers = `const {
${renderList(refs)}
} = require('${helperPath}');
`;
return [
header,
helpers,
body
].filter(Boolean).join("\n");
};
export {
extractHelpersPlugin as default,
extractHelpersPlugin,
formatFile,
formatHelpers,
getRelativePath,
onEnd
};