
這裡我們會示範 bun 打包的精髓之一,一體化處理,在古早的年代有 Gulp
這類東西,我們一體化的操作,對於 CI/CD 或是自己搞一套腳本去 build 一整套留流程
是沒有問題的,這裡我們會展示一些深入的進階用法,上乾貨!
這裏 bun 可以寫 typescript 腳本以實現利用 typescript/javascript 去 build 相關指令
這個好處是,可以整合到 js/ts 腳本裡面去做執行,對 CI/CD 也好,或是一些工作流程很有用處
舉個例子我們建構的腳本 : build.ts
const result = await Bun.build({
entrypoints: ["./src/index.tsx"],
outdir: "./build",
target: "browser",
minify: true,
sourcemap: "external",
splitting: true, // 開啟 code splitting
});
if (!result.success) {
console.error("Build failed");
for (const message of result.logs) {
console.error(message);
}
process.exit(1);
}
for (const output of result.outputs) {
console.log(output.path, output.loader, output.kind);
}
構建出來的 outputs 是 BuildArtifact 物件,它們是 Blob 加上額外屬性,所以可以直接餵給 HTTP
const { outputs } = await Bun.build({
entrypoints: ["./src/index.tsx"],
outdir: "./build",
});
Bun.serve({
port: 3000,
fetch(req) {
const url = new URL(req.url);
const file = outputs.find(o => o.path.endsWith(url.pathname));
if (file) return new Response(file); // Bun 自動設定 Content-Type / ETag
return new Response("Not found", { status: 404 });
},
});
這樣可以建構一整個工具鏈
const router = new Bun.FileSystemRouter({
style: "nextjs",
dir: "./pages",
});
const entrypoints = Object.values(router.routes);
await Bun.build({
entrypoints,
outdir: "./build",
target: "browser",
});
我們可以把 bun plugin 同時用在 Bundler runtime 上面,實現 build pipline
如果早期 js 的使用者有用過 Gulp 之類的,現在 bun 已經可以內建實現相關應用
plugin 的範例如下,我們這裡假設作為 yaml loader 去做處理
import { plugin } from "bun";
plugin({
name: "yaml-loader",
setup(build) {
build.onLoad({ filter: /\.yaml$/ }, async (args) => {
const text = await Bun.file(args.path).text();
// 這裡可以用任何 yaml parser 轉成 JS object
return {
contents: `export default ${JSON.stringify(text)}`,
loader: "js",
};
});
},
});
上面有提及,我這直接上示範
# 把 TS/JS 直接編譯成單一可執行檔,內建 Bun runtime
bun build ./cli.ts --compile --outfile demo-cli
# 執行
./demo-cli
我們這裡展示如何一體化使用 bun 去處理 bundler 相關的解法,
我們下回會講到奧義篇,會講到一些進階以外的技巧
iThome鐵人賽