UNPKG

esbuild-plugin-extract-helpers

Version:

Esbuild plugin to extract cjs helpers (like tslib)

109 lines (108 loc) 3.06 kB
// 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 };