diff options
author | 2023-05-16 10:47:00 -0700 | |
---|---|---|
committer | 2023-05-16 10:47:00 -0700 | |
commit | 366eba78f0b9b2c58cdd46b906275fc8382da977 (patch) | |
tree | 8966c3964aeacc4a7f61a69164467e9ebf37b6e1 /docs | |
parent | 60bc804c58b18e99763b2d05e81bafa46800092f (diff) | |
download | bun-366eba78f0b9b2c58cdd46b906275fc8382da977.tar.gz bun-366eba78f0b9b2c58cdd46b906275fc8382da977.tar.zst bun-366eba78f0b9b2c58cdd46b906275fc8382da977.zip |
Tweaks to bundler docs (#2867)
* WIP
* Fix typo
* Updates
* Document --compile
* Add bundler benchmark
* Remove esbuild
* Add bench to docs
* Add buttons
* Updates
Diffstat (limited to 'docs')
-rw-r--r-- | docs/bundler/executables.md | 33 | ||||
-rw-r--r-- | docs/bundler/migration.md | 2 | ||||
-rw-r--r-- | docs/cli/build.md | 194 | ||||
-rw-r--r-- | docs/index.md | 2 | ||||
-rw-r--r-- | docs/nav.ts | 3 |
5 files changed, 208 insertions, 26 deletions
diff --git a/docs/bundler/executables.md b/docs/bundler/executables.md new file mode 100644 index 000000000..9a0fc639e --- /dev/null +++ b/docs/bundler/executables.md @@ -0,0 +1,33 @@ +Bun's bundler implements a `--compile` flag for generating a standalone binary from a TypeScript or JavaScript file. + +{% codetabs %} + +```bash +$ bun build ./cli.ts --compile --outfile mycli +``` + +```ts#cli.ts +console.log("Hello world!"); +``` + +{% /codetabs %} + +This bundles `cli.ts` into an executable that can be executed directly: + +``` +$ ./mycli +Hello world! +``` + +All imported files and packages are bundled into the executable, along with a copy of the Bun runtime. All built-in Bun and Node.js APIs are supported. + +{% callout %} + +**Note** — Currently, the `--compile` flag can only accept a single entrypoint at a time and does not support the following flags: + +- `--outdir` — use `outfile` instead. +- `--external` +- `--splitting` +- `--publicPath` + +{% /callout %} diff --git a/docs/bundler/migration.md b/docs/bundler/migration.md index e76d50103..1bf9d52dc 100644 --- a/docs/bundler/migration.md +++ b/docs/bundler/migration.md @@ -6,7 +6,7 @@ Bun's bundler API is inspired heavily by [esbuild](https://esbuild.github.io/). There are a few behavioral differences to note. -- **Bundling by default**. Unlike esbuild, Bun _always bundles by default_. This is why the `--bundle` flag isn't necessary in the Bun example. To transpile each file individually, use [`Bun.Transpiler`](/docs/api/transpiler.md). +- **Bundling by default**. Unlike esbuild, Bun _always bundles by default_. This is why the `--bundle` flag isn't necessary in the Bun example. To transpile each file individually, use [`Bun.Transpiler`](/docs/api/transpiler). - **It's just a bundler**. Unlike esbuild, Bun's bundler does not include a built-in development server or file watcher. It's just a bundler. The bundler is intended for use in conjunction with `Bun.serve` and other runtime APIs to achieve the same effect. As such, all options relating to HTTP/file watching are not applicable. ## Performance diff --git a/docs/cli/build.md b/docs/cli/build.md index f7113ae9f..e0cd36651 100644 --- a/docs/cli/build.md +++ b/docs/cli/build.md @@ -15,6 +15,10 @@ $ bun build ./index.tsx --outdir ./build {% /codetabs %} +It's fast. The numbers below represent performance on esbuild's [three.js benchmark](https://github.com/oven-sh/bun/tree/main/bench/bundle). + +{% image src="/images/bundler-speed.png" caption="Bundling 10 copies of three.js from scratch, with sourcemaps and minification" /%} + ## Why bundle? The bundler is a key piece of infrastructure in the JavaScript ecosystem. As a brief overview of why bundling is so important: @@ -207,7 +211,7 @@ Refer to the [Bundler > Loaders](/docs/bundler/loaders#file) page for more compl ### Plugins -The behavior described in this table can be overridden with [plugins](/docs/bundler/plugins). Refer to the [Bundler > Loaders](/docs/bundler/plugins) page for complete documentation. +The behavior described in this table can be overridden or extended with [plugins](/docs/bundler/plugins). Refer to the [Bundler > Loaders](/docs/bundler/plugins) page for complete documentation. ## API @@ -217,9 +221,9 @@ The behavior described in this table can be overridden with [plugins](/docs/bund {% codetabs group="a" %} -```ts #JavaScript +```ts#JavaScript const result = await Bun.build({ - entrypoints: ['./index.ts'] + entrypoints: ["./index.ts"], }); // => { success: boolean, outputs: BuildArtifact[], logs: BuildMessage[] } ``` @@ -253,11 +257,11 @@ $ bun build --entrypoints ./index.ts --outdir ./out {% /codetabs %} -If `outdir` is not passed to the JavaScript API, bundled code will not be written to disk. Bundled files are returned in an array of `BuildArtifact` objects. These objects are Blobs with extra properties. +If `outdir` is not passed to the JavaScript API, bundled code will not be written to disk. Bundled files are returned in an array of `BuildArtifact` objects. These objects are Blobs with extra properties; see [Outputs](#outputs) for complete documentation. ```ts const result = await Bun.build({ - entrypoints: ['./index.ts'] + entrypoints: ["./index.ts"], }); for (const result of result.outputs) { @@ -272,7 +276,7 @@ for (const result of result.outputs) { } ``` -When `outdir` is set, the `.path` on `BuildArtifact` will be the absolute path to where it was written to. +When `outdir` is set, the `path` property on a `BuildArtifact` will be the absolute path to where it was written to. ### `target` @@ -312,6 +316,8 @@ Depending on the target, Bun will apply different module resolution rules and op All bundles generated with `target: "bun"` are marked with a special `// @bun` pragma, which indicates to the Bun runtime that there's no need to re-transpile the file before execution. + If any entrypoints contains a Bun shebang (`#!/usr/bin/env bun`) the bundler will default to `target: "bun"` instead of `"browser`. + --- - `node` @@ -319,6 +325,10 @@ Depending on the target, Bun will apply different module resolution rules and op {% /table %} +{% callout %} + +{% /callout %} + ### `format` Specifies the module format to be used in the generated bundles. @@ -1051,18 +1061,133 @@ $ bun build ./index.tsx --outdir ./out --loader .png:dataurl --loader .txt:file {% /codetabs %} +## Outputs + +The `Bun.build` function returns a `Promise<BuildOutput>`, defined as: + +```ts +interface BuildOutput { + outputs: BuildArtifact[]; + success: boolean; + logs: Array<object>; // see docs for details +} -## Error handling +interface BuildArtifact extends Blob { + kind: "entry-point" | "chunk" | "asset" | "sourcemap"; + path: string; + loader: Loader; + hash: string | null; + sourcemap: BuildArtifact | null; +} +``` -`Bun.build` only throws if invalid options are provided. You should read the `success` and `logs` properties of the result to determine whether the build was successful. +The `outputs` array contains all the files that were generated by the build. Each artifact implements the `Blob` interface. + +```ts +const build = Bun.build({ + /* */ +}); + +for (const output of build.outputs) { + await output.arrayBuffer(); // => ArrayBuffer + await output.text(); // string +} +``` + +Each artifact also contains the following properties: + +{% table %} + +--- + +- `kind` +- What kind of build output this file is. A build generates bundled entrypoints, code-split "chunks", sourcemaps, and copied assets (like images). + +--- + +- `path` +- Absolute path to the file on disk + +--- + +- `loader` +- The loader was used to interpret the file. See [Bundler > Loaders](/docs/bundler/loaders) to see how Bun maps file extensions to the appropriate built-in loader. + +--- + +- `hash` +- The hash of the file contents. Always defined for assets. + +--- + +- `sourcemap` +- The sourcemap file corresponding to this file, if generated. Only defined for entrypoints and chunks. + +{% /table %} + +Similar to `BunFile`, `BuildArtifact` objects can be passed directly into `new Response()`. + +```ts +const build = Bun.build({ + /* */ +}); + +const artifact = build.outputs[0]; + +// Content-Type header is automatically set +return new Response(artifact); +``` + +The Bun runtime implements special pretty-printing of `BuildArtifact` object to make debugging easier. + +{% codetabs %} + +```ts#Build_script +// build.ts +const build = Bun.build({/* */}); + +const artifact = build.outputs[0]; +console.log(artifact); +``` + +```sh#Shell_output +$ bun run build.ts +BuildArtifact (entry-point) { + path: "./index.js", + loader: "tsx", + kind: "entry-point", + hash: "824a039620219640", + Blob (114 bytes) { + type: "text/javascript;charset=utf-8" + }, + sourcemap: null +} +``` + +{% /codetabs %} + +### Executables + +Bun supports "compiling" a JavaScript/TypeScript entrypoint into a standalone executable. This executable contains a copy of the Bun binary. + +```sh +$ bun build ./cli.tsx --outfile mycli --compile +$ ./mycli +``` + +Refer to [Bundler > Executables](/docs/bundler/executables) for complete documentation. + +## Logs and errors + +`Bun.build` only throws if invalid options are provided. Read the `success` property to determine if the build was successful; the `logs` property will contain additional details. ```ts const result = await Bun.build({ - entrypoints: ['./index.tsx'], - outdir: './out', + entrypoints: ["./index.tsx"], + outdir: "./out", }); -if(!result.success) { +if (!result.success) { console.error("Build failed"); for (const message of result.logs) { // Bun will pretty print the message object @@ -1089,7 +1214,7 @@ class ResolveMessage extends BuildMessage { } ``` -If you want to throw an error from a failed build, consider passing the logs to an `AggregateError`. If uncaught, Bun will pretty print the contained messages nicely. +If you want to throw an error from a failed build, consider passing the logs to an `AggregateError`. If uncaught, Bun will pretty-print the contained messages nicely. ```ts if (!result.success) { @@ -1143,24 +1268,43 @@ interface BuildArtifact extends Blob { path: string; loader: Loader; hash?: string; - kind: "entry-point" | "chunk" | "asset" | "sourecemap"; + kind: "entry-point" | "chunk" | "asset" | "sourcemap"; sourcemap?: BuildArtifact; } -type Loader = - | "js" - | "jsx" - | "ts" - | "tsx" - | "json" - | "toml" - | "file" - | "napi" - | "wasm" - | "text"; +type Loader = "js" | "jsx" | "ts" | "tsx" | "json" | "toml" | "file" | "napi" | "wasm" | "text"; + +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; +} ``` -<!-- +<!-- interface BuildManifest { inputs: { [path: string]: { diff --git a/docs/index.md b/docs/index.md index b0bff82f1..6b5891cdf 100644 --- a/docs/index.md +++ b/docs/index.md @@ -25,6 +25,8 @@ Get started with one of the quick links below, or read on to learn more about Bu {% arrowbutton href="/docs/installation" text="Install Bun" /%} {% arrowbutton href="/docs/quickstart" text="Do the quickstart" /%} {% arrowbutton href="/docs/cli/install" text="Install a package" /%} +{% arrowbutton href="//docs/templates" text="Use a project template" /%} +{% arrowbutton href="/docs/cli/build" text="Bundle code for production" /%} {% arrowbutton href="/docs/api/http" text="Build an HTTP server" /%} {% arrowbutton href="/docs/api/websockets" text="Build a Websocket server" /%} {% arrowbutton href="/docs/api/file-io" text="Read and write files" /%} diff --git a/docs/nav.ts b/docs/nav.ts index f1dd92c35..448d661af 100644 --- a/docs/nav.ts +++ b/docs/nav.ts @@ -166,6 +166,9 @@ export default { page("bundler/plugins", "Plugins", { description: `Implement custom loaders and module resolution logic with Bun's plugin system.`, }), + page("bundler/executables", "Executables", { + description: "Compile a TypeScript or JavaScript file to a standalone cross-platform executable", + }), page("bundler/migration", "Migration", { description: `Guides for migrating from other bundlers to Bun.`, }), |