repositories / pi-ext
pi-ext
bugabingas pi extensions
owned by admin
scripts/build/bundle.ts
Rawimport { build } from "rolldown";
import { type ExtensionBuildSpec, isExternal } from "./spec.ts";
export interface BundleOptions {
release?: boolean;
}
export interface BundleResult {
/** Entry output files relative to the output directory. */
entries: string[];
/** Every emitted file relative to the output directory. */
files: string[];
}
/**
* Bundle one extension into `outDir`.
* Chunks stay flat in the package root so `import.meta.url` relative resource
* lookups resolve identically from the entry and from any chunk.
*/
export async function bundleExtension(
spec: ExtensionBuildSpec,
outDir: string,
options: BundleOptions = {},
): Promise<BundleResult> {
const result = await build({
input: spec.entries,
cwd: spec.dir,
platform: "node",
// Source imports sibling modules as `./x.js`; the file on disk is `x.ts`.
resolve: { extensionAlias: { ".js": [".ts", ".js"] } },
external: (id, _parent, isResolved) =>
isResolved ? false : isExternal(id, spec.externals),
logLevel: "warn",
onLog(level, log, defaultHandler) {
if (level === "warn" && /import\.meta|circular/iu.test(log.message))
return;
defaultHandler(level, log);
},
output: {
dir: outDir,
format: "esm",
entryFileNames: "[name].js",
chunkFileNames: "[name]-[hash].js",
hashCharacters: "base36",
sourcemap: !options.release,
minify: Boolean(options.release),
},
});
const files: string[] = [];
const entries: string[] = [];
for (const output of result.output) {
files.push(output.fileName);
if (output.type === "chunk" && output.isEntry)
entries.push(output.fileName);
if (output.type === "chunk" && output.sourcemapFileName)
files.push(output.sourcemapFileName);
}
return { entries, files };
}