--define 標志可以與 bun build 和 bun build --compile 一起使用,將構建時常量注入到你的應用程序中。這對於將構建版本、時間戳或配置標志等元數據直接嵌入到編譯後的可執行文件中特別有用。
sh
bun build --compile --define BUILD_VERSION='"1.2.3"' --define BUILD_TIME='"2024-01-15T10:30:00Z"' src/index.ts --outfile myapp為什麼要使用構建時常量?
構建時常量直接嵌入到編譯後的代碼中,使它們:
- 零運行時開銷 - 無需環境變量查找或文件讀取
- 不可變 - 值在編譯時就被嵌入到二進制文件中
- 可優化 - 死代碼消除可以移除未使用的分支
- 安全 - 無需管理外部依賴或配置文件
這類似於 C/C++ 中的 gcc -D 或 #define,但用於 JavaScript/TypeScript。
基本用法
使用 bun build
sh
# 使用構建時常量打包
bun build --define BUILD_VERSION='"1.0.0"' --define NODE_ENV='"production"' src/index.ts --outdir ./dist使用 bun build --compile
sh
# 編譯為帶構建時常量的可執行文件
bun build --compile --define BUILD_VERSION='"1.0.0"' --define BUILD_TIME='"2024-01-15T10:30:00Z"' src/cli.ts --outfile mycliJavaScript API
ts
await Bun.build({
entrypoints: ["./src/index.ts"],
outdir: "./dist",
define: {
BUILD_VERSION: '"1.0.0"',
BUILD_TIME: '"2024-01-15T10:30:00Z"',
DEBUG: "false",
},
});常見用例
版本信息
將版本和構建元數據直接嵌入到你的可執行文件中:
ts
// 這些常量在構建時被替換
declare const BUILD_VERSION: string;
declare const BUILD_TIME: string;
declare const GIT_COMMIT: string;
export function getVersion() {
return {
version: BUILD_VERSION,
buildTime: BUILD_TIME,
commit: GIT_COMMIT,
};
}sh
bun build --compile \
--define BUILD_VERSION='"1.2.3"' \
--define BUILD_TIME='"2024-01-15T10:30:00Z"' \
--define GIT_COMMIT='"abc123"' \
src/cli.ts --outfile mycli功能標志
使用構建時常量啟用/禁用功能:
ts
// 在構建時替換
declare const ENABLE_ANALYTICS: boolean;
declare const ENABLE_DEBUG: boolean;
function trackEvent(event: string) {
if (ENABLE_ANALYTICS) {
// 如果 ENABLE_ANALYTICS 為 false,整個塊將被移除
console.log("追蹤:", event);
}
}
if (ENABLE_DEBUG) {
console.log("調試模式已啟用");
}sh
# 生產構建 - 啟用分析,禁用調試
bun build --compile --define ENABLE_ANALYTICS=true --define ENABLE_DEBUG=false src/app.ts --outfile app-prod
# 開發構建 - 兩者都啟用
bun build --compile --define ENABLE_ANALYTICS=false --define ENABLE_DEBUG=true src/app.ts --outfile app-dev配置
在構建時替換配置對象:
ts
declare const CONFIG: {
apiUrl: string;
timeout: number;
retries: number;
};
// CONFIG 在構建時被替換為實際對象
const response = await fetch(CONFIG.apiUrl, {
timeout: CONFIG.timeout,
});sh
bun build --compile --define 'CONFIG={"apiUrl":"https://api.example.com","timeout":5000,"retries":3}' src/app.ts --outfile app高級模式
特定環境的構建
為不同環境創建不同的可執行文件:
json
{
"scripts": {
"build:dev": "bun build --compile --define NODE_ENV='\"development\"' --define API_URL='\"http://localhost:3000\"' src/app.ts --outfile app-dev",
"build:staging": "bun build --compile --define NODE_ENV='\"staging\"' --define API_URL='\"https://staging.example.com\"' src/app.ts --outfile app-staging",
"build:prod": "bun build --compile --define NODE_ENV='\"production\"' --define API_URL='\"https://api.example.com\"' src/app.ts --outfile app-prod"
}
}使用 shell 命令獲取動態值
從 shell 命令生成構建時常量:
sh
# 使用 git 獲取當前提交和時間戳
bun build --compile \
--define BUILD_VERSION="\"$(git describe --tags --always)\"" \
--define BUILD_TIME="\"$(date -u +%Y-%m-%dT%H:%M:%SZ)\"" \
--define GIT_COMMIT="\"$(git rev-parse HEAD)\"" \
src/cli.ts --outfile mycli構建自動化腳本
創建一個自動注入構建元數據的構建腳本:
ts
// build.ts
import { $ } from "bun";
const version = await $`git describe --tags --always`.text();
const buildTime = new Date().toISOString();
const gitCommit = await $`git rev-parse HEAD`.text();
await Bun.build({
entrypoints: ["./src/cli.ts"],
outdir: "./dist",
define: {
BUILD_VERSION: JSON.stringify(version.trim()),
BUILD_TIME: JSON.stringify(buildTime),
GIT_COMMIT: JSON.stringify(gitCommit.trim()),
},
});
console.log(`已構建版本 ${version.trim()}`);重要注意事項
值格式
值必須是有效的 JSON,將被解析並內聯為 JavaScript 表達式:
sh
# ✅ 字符串必須使用 JSON 引號
--define VERSION='"1.0.0"'
# ✅ 數字是 JSON 字面量
--define PORT=3000
# ✅ 布爾值是 JSON 字面量
--define DEBUG=true
# ✅ 對象和數組(使用單引號包裹 JSON)
--define 'CONFIG={"host":"localhost","port":3000}'
# ✅ 數組也可以使用
--define 'FEATURES=["auth","billing","analytics"]'
# ❌ 這不起作用 - 字符串缺少引號
--define VERSION=1.0.0屬性鍵
你可以使用屬性訪問模式作為鍵,而不僅僅是簡單標識符:
sh
# ✅ 將 process.env.NODE_ENV 替換為 "production"
--define 'process.env.NODE_ENV="production"'
# ✅ 將 process.env.API_KEY 替換為實際密鑰
--define 'process.env.API_KEY="abc123"'
# ✅ 替換嵌套屬性
--define 'window.myApp.version="1.0.0"'
# ✅ 替換數組訪問
--define 'process.argv[2]="--production"'這對於環境變量特別有用:
ts
// 編譯前
if (process.env.NODE_ENV === "production") {
console.log("生產模式");
}
// 使用 --define 'process.env.NODE_ENV="production"' 編譯後
if ("production" === "production") {
console.log("生產模式");
}
// 優化後
console.log("生產模式");TypeScript 聲明
對於 TypeScript 項目,聲明你的常量以避免類型錯誤:
ts
// types/build-constants.d.ts
declare const BUILD_VERSION: string;
declare const BUILD_TIME: string;
declare const NODE_ENV: "development" | "staging" | "production";
declare const DEBUG: boolean;跨平台兼容性
當為多平台構建時,常量工作方式相同:
sh
# Linux
bun build --compile --target=bun-linux-x64 --define PLATFORM='"linux"' src/app.ts --outfile app-linux
# macOS
bun build --compile --target=bun-darwin-x64 --define PLATFORM='"darwin"' src/app.ts --outfile app-macos
# Windows
bun build --compile --target=bun-windows-x64 --define PLATFORM='"windows"' src/app.ts --outfile app-windows.exe