import type { BuildConfig, BunPlugin, PluginBuilder } from "bun"; import { parseArgs } from "node:util"; import { readdir, rm } from "node:fs/promises"; import { join } from "node:path"; import type { FileImporter } from "sass"; import { HTMLComponents } from "@mini-strap/components"; const { values } = parseArgs({ args: Bun.argv, options: { production: { type: "boolean", short: "p", default: false, }, filter: { type: "string", short: "f", default: "all", }, output: { type: "string", short: "o", default: "static", }, }, strict: true, allowPositionals: true, }); const outdir = values.output ?? "./static"; const nodeModuleImporter: FileImporter<"async"> = { findFileUrl(url) { if (url.startsWith("@")) { return new URL(import.meta.resolve(url)); } return null; }, }; const sassPlugin: BunPlugin = { name: "Sass Loader", async setup(build: PluginBuilder) { const sass = await import("sass"); build.onLoad({ filter: /\.scss$/ }, async ({ path }) => { // read and compile it with the sass compiler const result = await sass.compileAsync(path, { importers: [nodeModuleImporter], }); return { loader: "css", contents: result.css, }; }); }, }; const assets: BuildConfig[] = []; const filter = values.filter ?? "all"; if (["all", "sass"].includes(filter)) { assets.push({ entrypoints: ["./sass/style.scss"], outdir: `${outdir}/css`, naming: "[name].css", plugins: [sassPlugin], minify: values.production, // On by default in Bun v1.2+ html: true, experimentalCss: true, }); } if (["all", "js", "ts"].includes(filter)) { assets.push({ entrypoints: ["./js/index.ts"], outdir: `${outdir}/js`, target: "browser", splitting: values.production, minify: values.production, }); } if (["all", "html"].includes(filter)) { assets.push({ entrypoints: Object.values(HTMLComponents), outdir: "./templates/ext-components", target: "browser", naming: { // default values entry: "[name].[ext]", asset: "[name].[ext]", chunk: "[name]-[hash].[ext]", }, // On by default in Bun v1.2+ html: true, experimentalCss: true, }); } const out = await Promise.all( assets.map(async (item) => { const result = await Bun.build(item); if (!result.success) { throw new AggregateError(result.logs, "Build failed"); } return result; }), ); async function deleteJsFiles(folder: string) { const files = await readdir(folder); const jsFiles = files.filter((file) => file.endsWith(".js")); await Promise.all(jsFiles.map((file) => rm(join(folder, file)))); } await deleteJsFiles("./templates/ext-components"); console.log(`${Bun.color("#a6da95", "ansi")}Assets succesfully build!\x1b[0m`);