import Build from "/snippets/cli/build.mdx";
Bun 의 빠른 네이티브 번들러는 bun build CLI 명령 또는 Bun.build() JavaScript API 를 통해 사용할 수 있습니다.
한눈에 보기
- JS API:
await Bun.build({ entrypoints, outdir }) - CLI:
bun build <entry> --outdir ./out - 감시:
--watch로 점진적 재빌드 - 타겟:
--target browser|bun|node - 형식:
--format esm|cjs|iife(cjs/iife 는 실험적)
JavaScript
await Bun.build({
entrypoints: ['./index.tsx'],
outdir: './build',
});CLI
bun build ./index.tsx --outdir ./build빠릅니다. 아래 숫자는 esbuild 의 three.js 벤치마크 에 대한 성능을 나타냅니다.

왜 번들링을 하나요?
번들러는 JavaScript 생태계의 핵심 인프라입니다. 번들링이 왜 중요한지 간략히 살펴보겠습니다:
- HTTP 요청 감소.
node_modules의 단일 패키지는 수백 개의 파일로 구성될 수 있으며, 대규모 애플리케이션은 수십 개의 이러한 종속성을 가질 수 있습니다. 각 파일을 별도의 HTTP 요청으로 로드하는 것은 금방 감당할 수 없게 되므로 번들러는 애플리케이션 소스 코드를 단일 요청으로 로드할 수 있는 더 적은 수의 자체 포함 "번들"로 변환하는 데 사용됩니다. - 코드 변환. 최신 앱은 TypeScript, JSX 및 CSS 모듈과 같은 언어나 도구로 일반적으로 구축되며, 이 모두는 브라우저에서 소비되기 전에 일반 JavaScript 및 CSS 로 변환되어야 합니다. 번들러는 이러한 변환을 구성하는 자연스러운 장소입니다.
- 프레임워크 기능. 프레임워크는 파일 시스템 라우팅, 클라이언트 - 서버 코드 공동 위치 (예:
getServerSideProps또는 Remix 로더) 및 서버 컴포넌트와 같은 일반적인 패턴을 구현하기 위해 번들러 플러그인 및 코드 변환에 의존합니다. - 풀스택 애플리케이션. Bun 의 번들러는 단일 명령으로 서버 및 클라이언트 코드를 모두 처리할 수 있어 최적화된 프로덕션 빌드 및 단일 파일 실행 파일을 가능하게 합니다. 빌드 타임 HTML 가져오기를 사용하면 프론트엔드 자산과 백엔드 서버를 포함한 전체 애플리케이션을 단일 배포 단위로 번들링할 수 있습니다.
번들러 API 로 바로 들어가겠습니다.
NOTE
Bun 번들러는 타입 체킹 또는 타입 선언 생성을 위해 `tsc` 를 대체하도록 의도되지 않았습니다.기본 예제
첫 번째 번들을 만들어 보겠습니다. 다음 두 파일이 있으며, 이는 간단한 클라이언트 측 렌더링 React 앱을 구현합니다.
import * as ReactDOM from "react-dom/client";
import { Component } from "./Component";
const root = ReactDOM.createRoot(document.getElementById("root")!);
root.render(<Component message="Sup!" />);export function Component(props: { message: string }) {
return <h1>{props.message}</h1>;
}여기서 index.tsx 는 애플리케이션의 "진입점"입니다. 일반적으로 이는 서버를 시작하거나 - 이 경우 React root 를 초기화하는 - 일부 사이드 이펙트를 수행하는 스크립트입니다. TypeScript 및 JSX 를 사용하므로 브라우저로 전송하기 전에 코드를 번들링해야 합니다.
번들을 생성하려면:
await Bun.build({
entrypoints: ["./index.tsx"],
outdir: "./out",
});bun build ./index.tsx --outdir ./outentrypoints 에 지정된 각 파일에 대해 Bun 은 새 번들을 생성합니다. 이 번들은 ./out 디렉토리 (현재 작업 디렉토리에서 해결됨) 에 디스크에 기록됩니다. 빌드를 실행한 후 파일 시스템은 다음과 같습니다:
.
├── index.tsx
├── Component.tsx
└── out
└── index.jsout/index.js 의 내용은 다음과 같습니다:
// out/index.js
// ...
// 약 2 만 줄의 코드
// `react-dom/client` 및 모든 종속성 내용 포함
// $jsxDEV 및 $createRoot 함수가 정의된 곳
// Component.tsx
function Component(props) {
return $jsxDEV(
"p",
{
children: props.message,
},
undefined,
false,
undefined,
this,
);
}
// index.tsx
var rootNode = document.getElementById("root");
var root = $createRoot(rootNode);
root.render(
$jsxDEV(
Component,
{
message: "Sup!",
},
undefined,
false,
undefined,
this,
),
);감시 모드
런타임 및 테스트 러너와 마찬가지로 번들러는 기본적으로 감시 모드를 지원합니다.
bun build ./index.tsx --outdir ./out --watch콘텐츠 타입
Bun 런타임과 마찬가지로 번들러는 다양한 파일 타입을 기본적으로 지원합니다. 다음 표는 번들러의 표준 "로더" 세트를 보여줍니다. 전체 문서는 번들러 > 파일 타입 을 참조하세요.
| 확장자 | 세부 정보 |
|---|---|
.js .jsx .cjs .mjs .mts .cts .ts .tsx | Bun 의 내장 트랜스파일러를 사용하여 파일을 파싱하고 TypeScript/JSX 구문을 일반 JavaScript 로 트랜스파일합니다. 번들러는 데드 코드 제거 및 트리 쉐이킹을 포함한 일련의 기본 변환을 실행합니다. 현재 Bun 은 구문을 다운 변환하지 않습니다. 최근 ECMAScript 구문을 사용하면 번들링된 코드에 반영됩니다. |
.json | JSON 파일은 파싱되어 JavaScript 객체로 번들에 인라인됩니다.js<br/>import pkg from "./package.json";<br/>pkg.name; // => "my-package"<br/> |
.jsonc | 주석이 있는 JSON. 파일은 파싱되어 JavaScript 객체로 번들에 인라인됩니다.js<br/>import config from "./config.jsonc";<br/>config.name; // => "my-config"<br/> |
.toml | TOML 파일은 파싱되어 JavaScript 객체로 번들에 인라인됩니다.js<br/>import config from "./bunfig.toml";<br/>config.logLevel; // => "debug"<br/> |
.yaml .yml | YAML 파일은 파싱되어 JavaScript 객체로 번들에 인라인됩니다.js<br/>import config from "./config.yaml";<br/>config.name; // => "my-app"<br/> |
.txt | 텍스트 파일의 내용이 읽혀서 문자열로 번들에 인라인됩니다.js<br/>import contents from "./file.txt";<br/>console.log(contents); // => "Hello, world!"<br/> |
.html | HTML 파일이 처리되고 참조된 자산 (스크립트, 스타일시트, 이미지) 이 번들링됩니다. |
.css | CSS 파일은 출력 디렉토리의 단일 .css 파일로 함께 번들링됩니다. |
.node .wasm | 이 파일들은 Bun 런타임에서 지원되지만 번들링 중에는 자산으로 처리됩니다. |
자산
번들러가 인식할 수 없는 확장자가 있는 가져오기를 만나면 가져온 파일을 외부 파일로 처리합니다. 참조된 파일은 그대로 outdir 에 복사되고 가져오기는 파일에 대한 경로로 해결됩니다.
// 번들 진입점
import logo from "./logo.svg";
console.log(logo);// 번들링된 출력
var logo = "./logo-a7305bdef.svg";
console.log(logo);파일 로더의 정확한 동작은 naming 및 publicPath 의 영향도 받습니다.
플러그인
이 표에 설명된 동작은 플러그인으로 재정의하거나 확장할 수 있습니다. 완전한 문서는 번들러 > 로더 페이지를 참조하세요.
API
entrypoints
애플리케이션의 진입점에 해당하는 경로 배열입니다. 각 진입점마다 하나의 번들이 생성됩니다.
JavaScript
const result = await Bun.build({
entrypoints: ["./index.ts"]
});CLI
bun build ./index.tsoutdir
출력 파일이 기록될 디렉토리입니다.
JavaScript
const result = await Bun.build({
entrypoints: ['./index.ts'],
outdir: './out'
});
// => { success: boolean, outputs: `BuildArtifact[]`, logs: `BuildMessage[]` }CLI
bun build ./index.ts --outdir ./outoutdir 가 JavaScript API 에 전달되지 않으면 번들링된 코드는 디스크에 기록되지 않습니다. 번들링된 파일은 BuildArtifact 객체 배열로 반환됩니다. 이 객체들은 추가 속성이 있는 Blob 입니다. 완전한 문서는 출력 을 참조하세요.
const result = await Bun.build({
entrypoints: ["./index.ts"],
});
for (const res of result.outputs) {
// blob 으로 소비 가능
await res.text();
// Bun 은 Content-Type 및 Etag 헤더를 설정합니다
new Response(res);
// 수동으로 기록할 수 있지만 이 경우 `outdir` 를 사용해야 합니다.
Bun.write(path.join("out", res.path), res);
}outdir 가 설정되면 BuildArtifact 의 path 속성은 기록된 위치의 절대 경로입니다.
target
번들의 의도된 실행 환경입니다.
JavaScript
await Bun.build({
entrypoints: ['./index.ts'],
outdir: './out',
target: 'browser', // 기본값
})CLI
bun build ./index.ts --outdir ./out --target browser타겟에 따라 Bun 은 다른 모듈 해결 규칙과 최적화를 적용합니다.
기본값. 브라우저에서 실행하도록 의도된 번들을 생성할 때 사용됩니다. 가져오기를 해결할 때 "browser" 내보내기 조건을 우선시합니다. node:events 또는 node:path 와 같은 내장 모듈을 가져오는 것은 작동하지만 fs.readFile 과 같은 일부 함수를 호출하는 것은 작동하지 않습니다.
Bun 런타임에서 실행하도록 의도된 번들을 생성할 때 사용됩니다. 많은 경우 서버 측 코드를 번들링할 필요가 없습니다. 수정 없이 소스 코드를 직접 실행할 수 있습니다. 그러나 서버 코드를 번들링하면 시작 시간을 줄이고 실행 성능을 개선할 수 있습니다. 이는 서버 및 클라이언트 코드가 함께 번들링되는 빌드 타임 HTML 가져오기를 사용한 풀스택 애플리케이션을 빌드할 때 사용하는 타겟입니다.
target: "bun" 으로 생성된 모든 번들에는 특별한 // @bun 프라그마가 표시되어 Bun 런타임에 실행 전에 파일을 다시 트랜스파일할 필요가 없음을 나타냅니다.
진입점에 Bun shebang(#!/usr/bin/env bun) 이 포함되면 번들러는 "browser" 대신 target: "bun" 을 기본값으로 사용합니다.
target: "bun" 과 format: "cjs" 를 함께 사용할 때 // @bun @bun-cjs 프라그마가 추가되며 CommonJS 래퍼 함수는 Node.js 와 호환되지 않습니다.
Node.js 에서 실행하도록 의도된 번들을 생성할 때 사용됩니다. 가져오기를 해결할 때 "node" 내보내기 조건을 우선시하며 .mjs 를 출력합니다. 미래에는 Bun 글로벌 및 기타 내장 bun:* 모듈을 자동으로 폴리필할 것이지만 아직 구현되지 않았습니다.
format
생성된 번들에서 사용할 모듈 형식을 지정합니다.
Bun 은 기본적으로 "esm" 을 사용하며 "cjs" 및 "iife" 에 대한 실험적 지원을 제공합니다.
format: "esm" - ES 모듈
이것은 기본 형식으로, 최상위 await, import.meta 등을 포함한 ES 모듈 구문을 지원합니다.
JavaScript
await Bun.build({
entrypoints: ['./index.tsx'],
outdir: './out',
format: "esm",
})CLI
bun build ./index.tsx --outdir ./out --format esm브라우저에서 ES 모듈 구문을 사용하려면 format 을 "esm" 으로 설정하고 <script type="module"> 태그에 type="module" 이 설정되어 있는지 확인하세요.
format: "cjs" - CommonJS
CommonJS 모듈을 빌드하려면 format 을 "cjs" 로 설정하세요. "cjs" 를 선택하면 기본 타겟이 "browser"(esm) 에서 "node"(cjs) 로 변경됩니다. format: "cjs", target: "node" 로 트랜스파일된 CommonJS 모듈은 Bun 과 Node.js 모두에서 실행할 수 있습니다 (사용 중인 API 가 둘 다 지원된다고 가정).
JavaScript
await Bun.build({
entrypoints: ['./index.tsx'],
outdir: './out',
format: "cjs",
})CLI
bun build ./index.tsx --outdir ./out --format cjsformat: "iife" - IIFE
TODO: globalNames 을 지원하면 문서화.
jsx
JSX 변환 동작을 구성합니다. JSX 가 어떻게 컴파일되는지에 대한 세밀한 제어를 가능하게 합니다.
클래식 런타임 예제 (factory 및 fragment 사용):
await Bun.build({
entrypoints: ["./app.tsx"],
outdir: "./out",
jsx: {
factory: "h",
fragment: "Fragment",
runtime: "classic",
},
});# JSX 구성은 bunfig.toml 또는 tsconfig.json 에서 처리됩니다
bun build ./app.tsx --outdir ./out자동 런타임 예제 (importSource 사용):
await Bun.build({
entrypoints: ["./app.tsx"],
outdir: "./out",
jsx: {
importSource: "preact",
runtime: "automatic",
},
});# JSX 구성은 bunfig.toml 또는 tsconfig.json 에서 처리됩니다
bun build ./app.tsx --outdir ./outsplitting
코드 분할을 활성화할지 여부입니다.
JavaScript
await Bun.build({
entrypoints: ['./index.tsx'],
outdir: './out',
splitting: false, // 기본값
})CLI
bun build ./index.tsx --outdir ./out --splittingtrue 일 때 번들러는 코드 분할을 활성화합니다. 여러 진입점이 동일한 파일, 모듈 또는 파일/모듈 세트를 모두 가져올 때 공유 코드를 별도 번들로 분할하는 것이 종종 유용합니다. 이 공유 번들을 청크라고 합니다. 다음 파일을 고려하세요:
import { shared } from "./shared.ts";import { shared } from "./shared.ts";export const shared = "shared";entry-a.ts 와 entry-b.ts 를 코드 분할 활성화로 번들링하려면:
JavaScript
await Bun.build({
entrypoints: ['./entry-a.ts', './entry-b.ts'],
outdir: './out',
splitting: true,
})CLI
bun build ./entry-a.ts ./entry-b.ts --outdir ./out --splitting이 빌드를 실행하면 다음 파일이 생성됩니다:
.
├── entry-a.tsx
├── entry-b.tsx
├── shared.tsx
└── out
├── entry-a.js
├── entry-b.js
└── chunk-2fce6291bf86559d.js생성된 chunk-2fce6291bf86559d.js 파일에는 공유 코드가 포함됩니다. 충돌을 방지하기 위해 파일 이름에는 기본적으로 콘텐츠 해시가 자동으로 포함됩니다. 이는 naming 으로 커스터마이즈할 수 있습니다.
plugins
번들링 중에 사용할 플러그인 목록입니다.
await Bun.build({
entrypoints: ["./index.tsx"],
outdir: "./out",
plugins: [
/* ... */
],
});Bun 은 Bun 런타임과 번들러 모두를 위한 범용 플러그인 시스템을 구현합니다. 완전한 문서는 플러그인 문서 를 참조하세요.
env
번들링 중 환경 변수 처리 방식을 제어합니다. 내부적으로 이는 define 을 사용하여 환경 변수를 번들에 주입하지만 주입할 환경 변수를 지정하기 더 쉽게 만듭니다.
env: "inline"
process.env.FOO 참조를 실제 환경 변수 값을 포함하는 문자열 리터럴로 변환하여 번들 출력에 환경 변수를 주입합니다.
JavaScript
await Bun.build({
entrypoints: ['./index.tsx'],
outdir: './out',
env: "inline",
})CLI
bun build ./index.tsx --outdir ./out --env inline아래 입력에 대해:
// input.js
console.log(process.env.FOO);
console.log(process.env.BAZ);생성된 번들에는 다음 코드가 포함됩니다:
// output.js
console.log("bar");
console.log("123");env: "PUBLIC_*" (접두사)
지정된 접두사 (* 문자 앞의 부분) 와 일치하는 환경 변수를 인라인하여 process.env.FOO 를 실제 환경 변수 값으로 바꿉니다. 이는 개인 인증 정보를 출력 번들에 주입하는 것을 걱정하지 않고 공개 URL 또는 클라이언트 측 토큰과 같은 것을 선택적으로 인라인하는 데 유용합니다.
JavaScript
await Bun.build({
entrypoints: ['./index.tsx'],
outdir: './out',
// "ACME_PUBLIC_" 로 시작하는 모든 환경 변수 인라인
env: "ACME_PUBLIC_*",
})CLI
bun build ./index.tsx --outdir ./out --env ACME_PUBLIC_*예를 들어, 다음 환경 변수가 주어졌을 때:
FOO=bar BAZ=123 ACME_PUBLIC_URL=https://acme.com그리고 소스 코드:
console.log(process.env.FOO);
console.log(process.env.ACME_PUBLIC_URL);
console.log(process.env.BAZ);생성된 번들에는 다음 코드가 포함됩니다:
console.log(process.env.FOO);
console.log("https://acme.com");
console.log(process.env.BAZ);env: "disable"
환경 변수 주입을 완전히 비활성화합니다.
sourcemap
생성할 소스맵 타입을 지정합니다.
JavaScript
await Bun.build({
entrypoints: ['./index.tsx'],
outdir: './out',
sourcemap: 'linked', // 기본값 'none'
})CLI
bun build ./index.tsx --outdir ./out --sourcemap linked| 값 | 설명 |
|---|---|
"none" | 기본값. 소스맵이 생성되지 않습니다. |
"linked" | //# sourceMappingURL 주석을 사용하여 각 *.js 번들 옆에 별도의 *.js.map 파일이 생성됩니다. --outdir 가 설정되어 있어야 합니다. 이의 기본 URL 은 --public-path 로 커스터마이즈할 수 있습니다.js<br/>// <번들링된 코드 here><br/><br/>//# sourceMappingURL=bundle.js.map<br/> |
"external" | //# sourceMappingURL 주석을 삽입하지 않고 각 *.js 번들 옆에 별도의 *.js.map 파일이 생성됩니다.생성된 번들에는 번들을 해당 소스맵과 연결하는 데 사용할 수 있는 디버그 ID 가 포함됩니다. 이 debugId 는 파일 하단에 주석으로 추가됩니다.js<br/>// <생성된 번들 코드><br/><br/>//# debugId=<DEBUG ID><br/> |
"inline" | 소스맵이 생성되어 base64 페이로드로 생성된 번들 끝에 추가됩니다.js<br/>// <번들링된 코드 here><br/><br/>//# sourceMappingURL=data:application/json;base64,<인코딩된 소스맵 here><br/> |
연관된 *.js.map 소스맵에는 동등한 debugId 속성이 포함된 JSON 파일이 됩니다.
minify
축소를 활성화할지 여부입니다. 기본값 false.
NOTE
`bun` 을 타겟팅할 때 식별자는 기본적으로 축소됩니다.모든 축소 옵션을 활성화하려면:
JavaScript
await Bun.build({
entrypoints: ['./index.tsx'],
outdir: './out',
minify: true, // 기본값 false
})CLI
bun build ./index.tsx --outdir ./out --minify특정 축소를 세밀하게 활성화하려면:
JavaScript
await Bun.build({
entrypoints: ['./index.tsx'],
outdir: './out',
minify: {
whitespace: true,
identifiers: true,
syntax: true,
},
})CLI
bun build ./index.tsx --outdir ./out --minify-whitespace --minify-identifiers --minify-syntaxexternal
외부로 간주할 가져오기 경로 목록입니다. 기본값 [].
JavaScript
await Bun.build({
entrypoints: ['./index.tsx'],
outdir: './out',
external: ["lodash", "react"], // 기본값: []
})CLI
bun build ./index.tsx --outdir ./out --external lodash --external react외부 가져오기는 최종 번들에 포함되지 않는 가져오기입니다. 대신 가져오기 문은 런타임에 해결될 수 있도록 그대로 유지됩니다.
예를 들어, 다음 진입점 파일을 고려하세요:
import _ from "lodash";
import { z } from "zod";
const value = z.string().parse("Hello world!");
console.log(_.upperCase(value));일반적으로 index.tsx 를 번들링하면 "zod" 패키지의 전체 소스 코드가 포함된 번들이 생성됩니다. 대신 가져오기 문을 그대로 유지하려면 외부로 표시할 수 있습니다:
JavaScript
await Bun.build({
entrypoints: ['./index.tsx'],
outdir: './out',
external: ['zod'],
})CLI
bun build ./index.tsx --outdir ./out --external zod생성된 번들은 다음과 같습니다:
import { z } from "zod";
// ...
// "lodash" 패키지의 내용
// `_.upperCase` 함수 포함
var value = z.string().parse("Hello world!");
console.log(_.upperCase(value));모든 가져오기를 외부로 표시하려면 와일드카드 * 를 사용하세요:
JavaScript
await Bun.build({
entrypoints: ['./index.tsx'],
outdir: './out',
external: ['*'],
})CLI
bun build ./index.tsx --outdir ./out --external '*'packages
패키지 종속성을 번들에 포함할지 여부를 제어합니다. 가능한 값: bundle (기본값), external. Bun 은 경로가 ., .. 또는 / 로 시작하지 않는 모든 가져오기를 패키지로 처리합니다.
JavaScript
await Bun.build({
entrypoints: ['./index.ts'],
packages: 'external',
})CLI
bun build ./index.ts --packages externalnaming
생성된 파일 이름을 커스터마이즈합니다. 기본값 ./[dir]/[name].[ext].
JavaScript
await Bun.build({
entrypoints: ['./index.tsx'],
outdir: './out',
naming: "[dir]/[name].[ext]", // 기본값
})CLI
bun build ./index.tsx --outdir ./out --entry-naming "[dir]/[name].[ext]"기본적으로 생성된 번들의 이름은 관련 진입점의 이름을 기반으로 합니다.
.
├── index.tsx
└── out
└── index.js여러 진입점이 있으면 생성된 파일 계층 구조는 진입점의 디렉토리 구조를 반영합니다.
.
├── index.tsx
└── nested
└── index.tsx
└── out
├── index.js
└── nested
└── index.js생성된 파일의 이름과 위치는 naming 필드로 커스터마이즈할 수 있습니다. 이 필드는 다음 토큰이 해당 값으로 대체되는 템플릿 문자열을 허용합니다:
[name]- 확장자 없는 진입점 파일의 이름[ext]- 생성된 번들의 확장자[hash]- 번들 콘텐츠의 해시[dir]- 프로젝트 루트에서 소스 파일의 부모 디렉토리까지의 상대 경로
예를 들어:
| 토큰 | [name] | [ext] | [hash] | [dir] |
|---|---|---|---|---|
./index.tsx | index | js | a1b2c3d4 | "" (빈 문자열) |
./nested/entry.ts | entry | js | c3d4e5f6 | "nested" |
이 토큰들을 결합하여 템플릿 문자열을 만들 수 있습니다. 예를 들어, 생성된 번들 이름에 해시를 포함하려면:
JavaScript
await Bun.build({
entrypoints: ['./index.tsx'],
outdir: './out',
naming: 'files/[dir]/[name]-[hash].[ext]',
})CLI
bun build ./index.tsx --outdir ./out --entry-naming 'files/[dir]/[name]-[hash].[ext]'이 빌드는 다음 파일 구조를 생성합니다:
.
├── index.tsx
└── out
└── files
└── index-a1b2c3d4.jsnaming 필드에 문자열이 제공되면 진입점에 해당하는 번들에만 사용됩니다. 청크 및 복사된 자산의 이름은 영향을 받지 않습니다. JavaScript API 를 사용하면 생성된 각 파일 타입에 대해 별도의 템플릿 문자열을 지정할 수 있습니다.
JavaScript
await Bun.build({
entrypoints: ['./index.tsx'],
outdir: './out',
naming: {
// 기본값
entry: '[dir]/[name].[ext]',
chunk: '[name]-[hash].[ext]',
asset: '[name]-[hash].[ext]',
},
})CLI
bun build ./index.tsx --outdir ./out \
--entry-naming '[dir]/[name].[ext]' \
--chunk-naming '[name]-[hash].[ext]' \
--asset-naming '[name]-[hash].[ext]'root
프로젝트의 루트 디렉토리입니다.
JavaScript
await Bun.build({
entrypoints: ['./pages/a.tsx', './pages/b.tsx'],
outdir: './out',
root: '.',
})CLI
bun build ./pages/a.tsx ./pages/b.tsx --outdir ./out --root .지정되지 않으면 모든 진입점 파일의 첫 번째 공통 조상으로 계산됩니다. 다음 파일 구조를 고려하세요:
.
└── pages
└── index.tsx
└── settings.tsxpages 디렉토리에서 두 진입점을 모두 빌드할 수 있습니다:
JavaScript
await Bun.build({
entrypoints: ['./pages/index.tsx', './pages/settings.tsx'],
outdir: './out',
})CLI
bun build ./pages/index.tsx ./pages/settings.tsx --outdir ./out이것은 다음과 같은 파일 구조를 생성합니다:
.
└── pages
└── index.tsx
└── settings.tsx
└── out
└── index.js
└── settings.jspages 디렉토리는 진입점 파일의 첫 번째 공통 조상이므로 프로젝트 루트로 간주됩니다. 이는 생성된 번들이 out 디렉토리의 최상위 수준에 있음을 의미합니다. out/pages 디렉토리가 없습니다.
이 동작은 root 옵션을 지정하여 재정의할 수 있습니다:
JavaScript
await Bun.build({
entrypoints: ['./pages/index.tsx', './pages/settings.tsx'],
outdir: './out',
root: '.',
})CLI
bun build ./pages/index.tsx ./pages/settings.tsx --outdir ./out --root .. 을 root 로 지정하면 생성된 파일 구조는 다음과 같습니다:
.
└── pages
└── index.tsx
└── settings.tsx
└── out
└── pages
└── index.js
└── settings.jspublicPath
번들링된 코드의 모든 가져오기 경로에 추가될 접두사입니다.
많은 경우 생성된 번들에는 가져오기 문이 포함되지 않습니다. 결국 번들링의 목표는 모든 코드를 단일 파일로 결합하는 것입니다. 그러나 생성된 번들에 가져오기 문이 포함되는 여러 경우가 있습니다.
- 자산 가져오기 —
*.svg와 같은 인식할 수 없는 파일 타입을 가져올 때 번들러는 파일 로더에 위임하며, 이는 파일을 그대로outdir에 복사합니다. 가져오기는 변수로 변환됩니다 - 외부 모듈 — 파일과 모듈은 외부로 표시될 수 있으며, 이 경우 번들에 포함되지 않습니다. 대신 가져오기 문은 최종 번드에 유지됩니다.
- 청킹.
splitting이 활성화되면 번들러는 여러 진입점 간에 공유되는 코드를 나타내는 별도 "청크" 파일을 생성할 수 있습니다.
이러한 경우 중 하나에서 최종 번들에는 다른 파일에 대한 경로가 포함될 수 있습니다. 기본적으로 이 가져오기는 상대적입니다. 다음은 간단한 자산 가져오기의 예입니다:
import logo from "./logo.svg";
console.log(logo);var logo = "./logo.svg";
console.log(logo);publicPath 를 설정하면 모든 파일 경로에 지정된 값이 접두사로 추가됩니다.
JavaScript
await Bun.build({
entrypoints: ['./index.tsx'],
outdir: './out',
publicPath: 'https://cdn.example.com/', // 기본값은 undefined
})CLI
bun build ./index.tsx --outdir ./out --public-path 'https://cdn.example.com/'출력 파일은 이제 다음과 같습니다:
var logo = "https://cdn.example.com/logo-a7305bdef.svg";define
빌드 타임에 교체될 전역 식별자 맵입니다. 이 객체의 키는 식별자 이름이며, 값은 인라인될 JSON 문자열입니다.
JavaScript
await Bun.build({
entrypoints: ['./index.tsx'],
outdir: './out',
define: {
STRING: JSON.stringify("value"),
"nested.boolean": "true",
},
})CLI
bun build ./index.tsx --outdir ./out --define STRING='"value"' --define nested.boolean=trueloader
파일 확장자를 내장 로더 이름에 매핑하는 맵입니다. 이는 특정 파일을 어떻게 로드할지 빠르게 커스터마이즈하는 데 사용할 수 있습니다.
JavaScript
await Bun.build({
entrypoints: ['./index.tsx'],
outdir: './out',
loader: {
".png": "dataurl",
".txt": "file",
},
})CLI
bun build ./index.tsx --outdir ./out --loader .png:dataurl --loader .txt:filebanner
최종 번들에 추가될 배너로, react 를 위한 use client 와 같은 지시문 또는 코드에 대한 라이선스와 같은 주석 블록일 수 있습니다.
JavaScript
await Bun.build({
entrypoints: ['./index.tsx'],
outdir: './out',
banner: 'use client;'
})CLI
bun build ./index.tsx --outdir ./out --banner 'use client";'footer
최종 번들에 추가될 푸터로, 라이선스에 대한 주석 블록이나 재미있는 이스터 에그일 수 있습니다.
JavaScript
await Bun.build({
entrypoints: ['./index.tsx'],
outdir: './out',
footer: '// built with love in SF'
})CLI
bun build ./index.tsx --outdir ./out --footer '// built with love in SF'drop
번들에서 함수 호출을 제거합니다. 예를 들어 --drop=console 은 console.log 에 대한 모든 호출을 제거합니다. 해당 인수가 사이드 이펙트가 있을 수 있더라도 호출에 대한 인수도 제거됩니다. debugger 를 드롭하면 모든 debugger 문이 제거됩니다.
JavaScript
await Bun.build({
entrypoints: ['./index.tsx'],
outdir: './out',
drop: ["console", "debugger", "anyIdentifier.or.propertyAccess"],
})CLI
bun build ./index.tsx --outdir ./out --drop console --drop debuggerOutputs
Bun.build 함수는 Promise<BuildOutput> 를 반환하며, 다음과 같이 정의됩니다:
interface BuildOutput {
outputs: BuildArtifact[];
success: boolean;
logs: Array<object>; // 세부 정보는 문서 참조
}
interface BuildArtifact extends Blob {
kind: "entry-point" | "chunk" | "asset" | "sourcemap";
path: string;
loader: Loader;
hash: string | null;
sourcemap: BuildArtifact | null;
}outputs 배열에는 빌드에서 생성된 모든 파일이 포함됩니다. 각 아티팩트는 Blob 인터페이스를 구현합니다.
const build = await Bun.build({
/* */
});
for (const output of build.outputs) {
await output.arrayBuffer(); // => ArrayBuffer
await output.bytes(); // => Uint8Array
await output.text(); // string
}각 아티팩트에는 다음 속성도 포함됩니다:
| 속성 | 설명 |
|---|---|
kind | 이 파일이 어떤 종류의 빌드 출력인지. 빌드는 번들링된 진입점, 코드 분할 "청크", 소스맵, 바이트코드 및 복사된 자산 (이미지 등) 을 생성합니다. |
path | 디스크 상의 파일 절대 경로 |
loader | 파일을 해석하는 데 사용된 로더. Bun 이 파일 확장자를 적절한 내장 로더에 매핑하는 방법은 번들러 > 로더 를 참조하세요. |
hash | 파일 콘텐츠의 해시. 자산의 경우 항상 정의됩니다. |
sourcemap | 생성된 경우 이 파일에 해당하는 소스맵 파일. 진입점 및 청크에 대해서만 정의됩니다. |
BunFile 과 유사하게 BuildArtifact 객체는 new Response() 에 직접 전달할 수 있습니다.
const build = await Bun.build({
/* */
});
const artifact = build.outputs[0];
// Content-Type 헤더가 자동으로 설정됩니다
return new Response(artifact);Bun 런타임은 디버깅을 더 쉽게 만들기 위해 BuildArtifact 객체의 특별한 pretty-printing 을 구현합니다.
// build.ts
const build = await Bun.build({
/* */
});
const artifact = build.outputs[0];
console.log(artifact);bun run build.ts
BuildArtifact (entry-point) {
path: "./index.js",
loader: "tsx",
kind: "entry-point",
hash: "824a039620219640",
Blob (74756 bytes) {
type: "text/javascript;charset=utf-8"
},
sourcemap: BuildArtifact (sourcemap) {
path: "./index.js.map",
loader: "file",
kind: "sourcemap",
hash: "e7178cda3e72e301",
Blob (24765 bytes) {
type: "application/json;charset=utf-8"
},
sourcemap: null
}
}Bytecode
bytecode: boolean 옵션은 JavaScript/TypeScript 진입점에 대한 바이트코드를 생성하는 데 사용할 수 있습니다. 이는 대규모 애플리케이션의 시작 시간을 크게 개선할 수 있습니다. "cjs" 형식만 지원되며, "target": "bun" 만 지원되며 일치하는 Bun 버전에 종속됩니다. 이는 각 진입점에 해당하는 .jsc 파일을 추가합니다.
JavaScript
await Bun.build({
entrypoints: ["./index.tsx"],
outdir: "./out",
bytecode: true,
})CLI
bun build ./index.tsx --outdir ./out --bytecodeExecutables
Bun 은 JavaScript/TypeScript 진입점을 스탠드얼론 실행 파일로 "컴파일"하는 것을 지원합니다. 이 실행 파일에는 Bun 바이너리의 사본이 포함됩니다.
bun build ./cli.tsx --outfile mycli --compile
./mycli완전한 문서는 번들러 > 실행 파일 을 참조하세요.
Logs and errors
실패 시 Bun.build 는 AggregateError 로 거부된 promise 를 반환합니다. 이는 오류 목록의 예쁜 출력을 위해 콘솔에 로그되거나 try/catch 블록으로 프로그래밍 방식으로 읽을 수 있습니다.
try {
const result = await Bun.build({
entrypoints: ["./index.tsx"],
outdir: "./out",
});
} catch (e) {
// TypeScript 는 catch 절에 주석을 허용하지 않습니다
const error = e as AggregateError;
console.error("Build Failed");
// 예제: 내장 포맷터 사용
console.error(error);
// 예제: 실패를 JSON 문자열로 직렬화
console.error(JSON.stringify(error, null, 2));
}대부분의 경우 명시적인 try/catch 가 필요하지 않습니다. Bun 은 잡히지 않은 예외를 깔끔하게 출력하므로 Bun.build 호출에 최상위 await 를 사용하는 것으로 충분합니다.
error.errors 의 각 항목은 BuildMessage 또는 ResolveMessage (Error 의 하위 클래스) 의 인스턴스로, 각 오류에 대한 자세한 정보를 포함합니다.
class BuildMessage {
name: string;
position?: Position;
message: string;
level: "error" | "warning" | "info" | "debug" | "verbose";
}
class ResolveMessage extends BuildMessage {
code: string;
referrer: string;
specifier: string;
importKind: ImportKind;
}빌드 성공 시 반환된 객체에는 번들러 경고 및 정보 메시지를 포함하는 logs 속성이 있습니다.
const result = await Bun.build({
entrypoints: ["./index.tsx"],
outdir: "./out",
});
if (result.logs.length > 0) {
console.warn("빌드가 경고와 함께 성공했습니다:");
for (const message of result.logs) {
// Bun 은 메시지 객체를 예쁘게 출력합니다
console.warn(message);
}
}Reference
interface Bun {
build(options: BuildOptions): Promise<BuildOutput>;
}
interface BuildConfig {
entrypoints: string[]; // 파일 경로 목록
outdir?: string; // 출력 디렉토리
target?: Target; // 기본값: "browser"
/**
* 출력 모듈 형식. 최상위 await 는 `"esm"` 에 대해서만 지원됩니다.
*
* 가능:
* - `"esm"`
* - `"cjs"` (**실험적**)
* - `"iife"` (**실험적**)
*
* @default "esm"
*/
format?: "esm" | "cjs" | "iife";
/**
* JSX 변환 동작을 제어하기 위한 JSX 구성 객체
*/
jsx?: {
runtime?: "automatic" | "classic";
importSource?: string;
factory?: string;
fragment?: string;
sideEffects?: boolean;
development?: boolean;
};
naming?:
| string
| {
chunk?: string;
entry?: string;
asset?: string;
};
root?: string; // 프로젝트 루트
splitting?: boolean; // 기본값 true, 코드 분할 활성화
plugins?: BunPlugin[];
external?: string[];
packages?: "bundle" | "external";
publicPath?: string;
define?: Record<string, string>;
loader?: { [k in string]: Loader };
sourcemap?: "none" | "linked" | "inline" | "external" | boolean; // 기본값: "none", true -> "inline"
/**
* 가져오기를 해결할 때 사용되는 package.json `exports` 조건
*
* `bun build` 또는 `bun run` 의 `--conditions` 와 동일합니다.
*
* https://nodejs.org/api/packages.html#exports
*/
conditions?: Array<string> | string;
/**
* 번들링 중 환경 변수 처리 방식을 제어합니다.
*
* 다음 중 하나:
* - `"inline"`: `process.env.FOO` 참조를 실제 환경 변수 값을 포함하는 문자열 리터럴로 변환하여 번들 출력에 환경 변수를 주입합니다
* - `"disable"`: 환경 변수 주입을 완전히 비활성화합니다
* - `*` 로 끝나는 문자열: 주어진 접두사와 일치하는 환경 변수를 인라인합니다.
* 예를 들어 `"MY_PUBLIC_*"` 는 "MY_PUBLIC_" 로 시작하는 환경 변수만 포함합니다
*/
env?: "inline" | "disable" | `${string}*`;
minify?:
| boolean
| {
whitespace?: boolean;
syntax?: boolean;
identifiers?: boolean;
};
/**
* @__PURE__ 및 package.json "sideEffects" 필드와 같은 데드 코드 제거/트리 쉐이킹 주석을 무시합니다. 이는 라이브러리의 잘못된 주석에 대한 임시 해결책으로만 사용해야 합니다.
*/
ignoreDCEAnnotations?: boolean;
/**
* minify.whitespace 가 true 여도 @__PURE__ 주석을 강제로 생성합니다.
*/
emitDCEAnnotations?: boolean;
/**
* 출력에 대한 바이트코드를 생성합니다. 이는 콜드 시작 시간을 극적으로 개선할 수 있지만 최종 출력을 더 크게 만들고 메모리 사용량을 약간 증가시킵니다.
*
* 바이트코드는 현재 CommonJS(`format: "cjs"`) 에 대해서만 지원됩니다.
*
* `target: "bun"` 이어야 합니다
* @default false
*/
bytecode?: boolean;
/**
* "use client"; 와 같이 번들링된 코드에 배너를 추가합니다
*/
banner?: string;
/**
* 번들링된 코드에 푸터를 추가합니다. 예를 들어 주석 블록 like
*
* `// made with bun!`
*/
footer?: string;
/**
* 일치하는 속성 액세스에 대한 함수 호출을 제거합니다.
*/
drop?: string[];
/**
* - `true` 로 설정하면 빌드 실패가发生时 AggregateError 로 반환된 promise 가 거부됩니다.
* - `false` 로 설정하면 `{success: false}` 인 {@link BuildOutput} 를 반환합니다
*
* @default true
*/
throw?: boolean;
/**
* 경로 해결에 사용할 커스텀 tsconfig.json 파일 경로.
* CLI 의 `--tsconfig-override` 와 동일합니다.
*/
tsconfig?: string;
outdir?: string;
}
interface BuildOutput {
outputs: BuildArtifact[];
success: boolean;
logs: Array<BuildMessage | ResolveMessage>;
}
interface BuildArtifact extends Blob {
path: string;
loader: Loader;
hash: string | null;
kind: "entry-point" | "chunk" | "asset" | "sourcemap" | "bytecode";
sourcemap: BuildArtifact | null;
}
type Loader =
| "js"
| "jsx"
| "ts"
| "tsx"
| "css"
| "json"
| "jsonc"
| "toml"
| "yaml"
| "text"
| "file"
| "napi"
| "wasm"
| "html";
interface BuildOutput {
outputs: BuildArtifact[];
success: boolean;
logs: Array<BuildMessage | ResolveMessage>;
}
declare class ResolveMessage {
readonly name: "ResolveMessage";
readonly position: Position | null;
readonly code: string;
readonly message: string;
readonly referrer: string;
readonly specifier: string;
readonly importKind:
| "entry_point"
| "stmt"
| "require"
| "import"
| "dynamic"
| "require_resolve"
| "at"
| "at_conditional"
| "url"
| "internal";
readonly level: "error" | "warning" | "info" | "debug" | "verbose";
toString(): string;
}