diff options
-rw-r--r-- | README.md | 6 | ||||
-rw-r--r-- | docs/bundler/loaders.md | 14 | ||||
-rw-r--r-- | docs/bundler/migration.md | 1127 | ||||
-rw-r--r-- | docs/bundler/plugins.md | 22 | ||||
-rw-r--r-- | docs/cli/build.md | 172 | ||||
-rw-r--r-- | docs/nav.ts | 5 | ||||
-rw-r--r-- | docs/runtime/index.md | 2 | ||||
-rw-r--r-- | docs/runtime/loaders.md | 2 | ||||
-rw-r--r-- | packages/bun-types/bun.d.ts | 2 |
9 files changed, 1279 insertions, 73 deletions
@@ -48,7 +48,7 @@ bunx cowsay 'Hello, world!' # execute a package Bun supports Linux (x64 & arm64) and macOS (x64 & Apple Silicon). > **Linux users** — Kernel version 5.6 or higher is strongly recommended, but the minimum is 5.1. -> +> > **Windows users** — Bun does not currently provide a native Windows build. We're working on this; progress can be tracked at [this issue](https://github.com/oven-sh/bun/issues/43). In the meantime, use one of the installation methods below for Windows Subsystem for Linux. ```sh @@ -67,7 +67,6 @@ docker pull oven/bun docker run --rm --init --ulimit memlock=-1:-1 oven/bun ``` - ### Upgrade To upgrade to the latest version of Bun, run: @@ -100,7 +99,7 @@ bun upgrade --canary - [Runtime](https://bun.sh/docs/runtime/index) - [Module resolution](https://bun.sh/docs/runtime/modules) - [Hot & live reloading](https://bun.sh/docs/runtime/hot) - - [Plugins](https://bun.sh/docs/runtime/plugins) + - [Plugins](https://bun.sh/docs/bundler/plugins) - Ecosystem - [Node.js](https://bun.sh/docs/ecosystem/nodejs) - [TypeScript](https://bun.sh/docs/ecosystem/typescript) @@ -127,7 +126,6 @@ bun upgrade --canary - [DNS](https://bun.sh/docs/api/dns) - [Node-API](https://bun.sh/docs/api/node-api) - ## Contributing Refer to the [Project > Development](https://bun.sh/docs/project/development) guide to start contributing to Bun. diff --git a/docs/bundler/loaders.md b/docs/bundler/loaders.md index 7cac75648..5c88fbc9b 100644 --- a/docs/bundler/loaders.md +++ b/docs/bundler/loaders.md @@ -222,7 +222,7 @@ If a value is specified for `publicPath`, the import will use value as a prefix {% callout %} The location and file name of the copied file is determined by the value of [`naming.asset`](/docs/cli/build#naming). -{% callout %} +{% /callout %} This loader is copied into the `outdir` as-is. The name of the copied file is determined using the value of `naming.asset`. {% details summary="Fixing TypeScript import errors" %} @@ -232,3 +232,15 @@ If you're using TypeScript, you may get an error like this: // TypeScript error // Cannot find module './logo.svg' or its corresponding type declarations. ``` + +This can be fixed by creating `*.d.ts` file anywhere in your project (any name will work) with the following contents: + +```ts +declare module "*.svg" { + const content: string; + export default content; +} +``` + +This tells TypeScript that any default imports from `.svg` should be treated as a string. +{% /details %} diff --git a/docs/bundler/migration.md b/docs/bundler/migration.md new file mode 100644 index 000000000..260acf1ba --- /dev/null +++ b/docs/bundler/migration.md @@ -0,0 +1,1127 @@ +Bun's bundler API is inspired heavily by [esbuild](https://esbuild.github.io/). Migrating to Bun's bundler from esbuild should be relatively painless. This guide will briefly explain why you might consider migrating to Bun's bundler and provide a side-by-side API comparison reference for those who are already familiar with esbuild's API. + +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). +- **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 + +This is the simplest reason to migrate to Bun's bundler. With an performance-minded API inspired by esbuild coupled with the extensively optimized Zig-based JS/TS parser, Bun's bundler is roughly 50% faster than esbuild on most benchmarks. + +IMAGE HERE + +## CLI API + +Bun and esbuild both provide a command-line interface. + +```bash +$ esbuild <entrypoint> --outdir=out --bundle +$ bun build <entrypoint> --outdir=out +``` + +In Bun's CLI, simple boolean flags like `--minify` do not accept an argument. Other flags like `--outdir <path>` do accept an argument; these flags can be written as `--outdir out` or `--outdir=out`. Some flags like `--define` can be specified several times: `--define foo=bar --define bar=baz`. + +{% table %} + +- `esbuild` +- `bun build` + +--- + +- `--bundle` +- n/a +- Not necessary, `bun build` always bundles. + +--- + +- `--define:K=V` +- `--define K=V` +- Small syntax difference; no colon. + + ```bash + $ esbuild --define:foo=bar + $ bun build --define foo=bar + ``` + +--- + +- `--external:<pkg>` +- `--external <pkg>` +- Small syntax difference; no colon. + + ```bash + $ esbuild --external:react + $ bun build --external react + ``` + +--- + +- `--format` +- `--format` +- Bun only supports `"esm"` currently but other module formats are planned. esbuild defaults to `"iife"`. + +--- + +- `--loader` +- `--loader` +- Bun supports a different set of built-in loaders than esbuild; see [Bundler > Loaders](/docs/bundler/loaders) for a complete reference. The esbuild loaders `dataurl`, `binary`, `base64`, `copy`, and `empty` are not yet implemented. + + The syntax for `--loader` is slightly different. + + ```bash + $ esbuild app.ts --bundle --loader:.svg=text + $ bun build app.ts --loader .svg:text + ``` + +--- + +- `--minify` +- `--minify` +- No differences + +--- + +- `--outdir` +- `--outdir` +- No differences + +--- + +- `--outfile` +- `--outfile` + +--- + +- `--packages` +- n/a +- Not supported + +--- + +- `--platform` +- `--target` +- Renamed to `--target` for consistency with tsconfig + +--- + +- `--serve` +- n/a +- Not applicable + +--- + +- `--sourcemap` +- `--sourcemap` +- No differences + +--- + +- `--splitting` +- `--splitting` +- No differences + +--- + +- `--target` +- n/a +- No supported. Bun's bundler performs no syntactic downleveling at this time. + +--- + +- `--watch` +- n/a +- Not applicable. + +--- + +- `--allow-overwrite` +- n/a +- Overwriting is always allowed + +--- + +- `--analyze` +- n/a +- Not supported. Use `--manifest` to generate a manifest file. + +--- + +- `--asset-names` +- `--asset-naming` +- Renamed for consistency with `naming` in JS API + +--- + +- `--banner` +- n/a +- Not supported + +--- + +- `--certfile` +- n/a +- Not applicable, Bun's bundler does + +--- + +- `--charset=utf8` +- n/a +- Not supported + +--- + +- `--chunk-names` +- `--chunk-naming` +- Renamed for consistency with `naming` in JS API + +--- + +- `--color` +- n/a +- Always enabled + +--- + +- `--drop` +- n/a +- Not supported + +--- + +- `--entry-names` +- `--entry-naming` +- Renamed for consistency with `naming` in JS API + +--- + +- `--footer` +- n/a +- Not supported + +--- + +- `--global-name` +- n/a +- Not applicable, Bun does not support `iife` output at this time. + +--- + +- `--ignore-annotations` +- n/a +- Not supported + +--- + +- `--inject` +- n/a +- Not supported + +--- + +- `--jsx` +- `--jsx-runtime <runtime>` +- Supports `"automatic"` (uses `jsx` transform) and `"classic"` (uses `React.createElement`) + +--- + +- `--jsx-dev` +- n/a +- Bun reads `compilerOptions.jsx` from `tsconfig.json` to determine a default. If `compilerOptions.jsx` is `"react-jsx"`, or if `NODE_ENV=production`, Bun will use the `jsx` transform. Otherwise, it uses `jsxDEV`. For any to Bun uses `jsxDEV`. The bundler does not support `preserve`. + +--- + +- `--jsx-factory` +- `--jsx-factory` + +--- + +- `--jsx-fragment` +- `--jsx-fragment` + +--- + +- `--jsx-import-source` +- `--jsx-import-source` + +--- + +- `--jsx-side-effects` +- n/a +- JSX is always assumed to be side-effect-free. + +--- + +- `--keep-names` +- n/a +- Not supported + +--- + +- `--keyfile` +- n/a +- Not applicable + +--- + +- `--legal-comments` +- n/a +- Not supported + +--- + +- `--log-level` +- n/a +- Not supported. This can be set in `bunfig.toml` as `logLevel`. + +--- + +- `--log-limit` +- n/a +- Not supported + +--- + +- `--log-override:X=Y` +- n/a +- Not supported + +--- + +- `--main-fields` +- n/a +- Not supported + +--- + +- `--mangle-cache` +- n/a +- Not supported + +--- + +- `--mangle-props` +- n/a +- Not supported + +--- + +- `--mangle-quoted` +- n/a +- Not supported + +--- + +- `--metafile` +- `--manifest` + +--- + +- `--minify-whitespace` +- `--minify-whitespace` + +--- + +- `--minify-identifiers` +- `--minify-identifiers` + +--- + +- `--minify-syntax` +- `--minify-syntax` + +--- + +- `--out-extension` +- n/a +- Not supported + +--- + +- `--outbase` +- `--root` +- Not supported + +--- + +- `--preserve-symlinks` +- n/a +- Not supported + +--- + +- `--public-path` +- `--public-path` + +--- + +- `--pure` +- n/a +- Not supported + +--- + +- `--reserve-props` +- n/a +- Not supported + +--- + +- `--resolve-extensions` +- n/a +- Not supported + +--- + +- `--servedir` +- n/a +- Not applicable + +--- + +- `--source-root` +- n/a +- Not supported + +--- + +- `--sourcefile` +- n/a +- Not supported. Bun does not support `stdin` input yet. + +--- + +- `--sourcemap` +- `--sourcemap` +- No differences + +--- + +- `--sources-content` +- n/a +- Not supported + +--- + +- `--supported` +- n/a +- Not supported + +--- + +- `--tree-shaking` +- n/a +- Always `true` + +--- + +- `--tsconfig` +- `--tsconfig-override` + +--- + +- `--version` +- n/a +- Run `bun --version` to see the version of Bun. + +{% /table %} + +## JavaScript API + +{% table %} + +- `esbuild.build()` +- `Bun.build()` + +--- + +- `absWorkingDir` +- n/a +- Always set to `process.cwd()` + +--- + +- `alias` +- n/a +- Not supported + +--- + +- `allowOverwrite` +- n/a +- Always `true` + +--- + +- `assetNames` +- `naming.asset` +- Uses same templating syntax as esbuild, but `[ext]` must be included explicitly. + + ```ts + Bun.build({ + entrypoints: ["./index.tsx"], + naming: { + asset: "[name].[ext]", + }, + }); + ``` + +--- + +- `banner` +- n/a +- Not supported + +--- + +- `bundle` +- n/a +- Always `true` + +--- + +- `charset` +- n/a +- Not supported + +--- + +- `chunkNames` +- `naming.chunk` +- Uses same templating syntax as esbuild, but `[ext]` must be included explicitly. + + ```ts + Bun.build({ + entrypoints: ["./index.tsx"], + naming: { + chunk: "[name].[ext]", + }, + }); + ``` + +--- + +- `color` +- n/a +- Bun returns logs in the `logs` property of the build result. + +--- + +- `conditions` +- n/a +- Not supported. Export conditions priority is determined by `target`. + +--- + +- `define` +- `define` +- Not supported in JS API + +--- + +- `drop` +- n/a +- Not supported + +--- + +- `entryNames` +- `naming` or `naming.entry` +- Bun supports a `naming` key that can either be a string or an object. Uses same templating syntax as esbuild, but `[ext]` must be included explicitly. + + ```ts + Bun.build({ + entrypoints: ["./index.tsx"], + // when string, this is equivalent to entryNames + naming: "[name].[ext]", + + // granular naming options + naming: { + entry: "[name].[ext]", + asset: "[name].[ext]", + chunk: "[name].[ext]", + }, + }); + ``` + +--- + +- `entryPoints` +- `entrypoints` +- Capitalization difference + +--- + +- `external` +- `external` +- No differences + +--- + +- `footer` +- n/a +- Not supported + +--- + +- `format` +- `format` +- Only supports `"esm"` currently. Support for `"cjs"` and `"iife"` is planned. + +--- + +- `globalName` +- n/a +- Not supported + +--- + +- `ignoreAnnotations` +- n/a +- Not supported + +--- + +- `inject` +- n/a +- Not supported + +--- + +- `jsx` +- `jsx` +- Not supported in JS API, configure in `tsconfig.json` + +--- + +- `jsxDev` +- `jsxDev` +- Not supported in JS API, configure in `tsconfig.json` + +--- + +- `jsxFactory` +- `jsxFactory` +- Not supported in JS API, configure in `tsconfig.json` + +--- + +- `jsxFragment` +- `jsxFragment` +- Not supported in JS API, configure in `tsconfig.json` + +--- + +- `jsxImportSource` +- `jsxImportSource` +- Not supported in JS API, configure in `tsconfig.json` + +--- + +- `jsxSideEffects` +- `jsxSideEffects` +- Not supported in JS API, configure in `tsconfig.json` + +--- + +- `keepNames` +- n/a +- Not supported + +--- + +- `legalComments` +- n/a +- Not supported + +--- + +- `loader` +- n/a +- Not supported in JS API + +--- + +- `logLevel` +- n/a +- Not supported + +--- + +- `logLimit` +- n/a +- Not supported + +--- + +- `logOverride` +- n/a +- Not supported + +--- + +- `mainFields` +- n/a +- Not supported + +--- + +- `mangleCache` +- n/a +- Not supported + +--- + +- `mangleProps` +- n/a +- Not supported + +--- + +- `mangleQuoted` +- n/a +- Not supported + +--- + +- `metafile` +- `manifest` +- When `manifest` is `true`, the result of `Bun.build()` will contain a `manifest` property. The manifest is compatible with esbuild's metafile format. + +--- + +- `minify` +- `minify` +- In Bun, `minify` can be a boolean or an object. + + ```ts + Bun.build({ + entrypoints: ['./index.tsx'], + // enable all minification + minify: true + + // granular options + minify: { + identifiers: true, + syntax: true, + whitespace: true + } + }) + ``` + +--- + +- `minifyIdentifiers` +- `minify.identifiers` +- See `minify` + +--- + +- `minifySyntax` +- `minify.syntax` +- See `minify` + +--- + +- `minifyWhitespace` +- `minify.whitespace` +- See `minify` + +--- + +- `nodePaths` +- n/a +- Not supported + +--- + +- `outExtension` +- n/a +- Not supported + +--- + +- `outbase` +- `root` +- Different name + +--- + +- `outdir` +- `outdir` +- No differences + +--- + +- `outfile` +- `outfile` +- No differences + +--- + +- `packages` +- n/a +- Not supported, use `external` + +--- + +- `platform` +- `target` +- Supports `"bun"`, `"node"`, and `"browser"` (the default) + +--- + +- `plugins` +- `plugins` +- Bun's plugin API is a subset of esbuild's. Some esbuild plugins will work out of the box with Bun. + +--- + +- `preserveSymlinks` +- n/a +- Not supported + +--- + +- `publicPath` +- `publicPath` +- No differences + +--- + +- `pure` +- n/a +- Not supported + +--- + +- `reserveProps` +- n/a +- Not supported + +--- + +- `resolveExtensions` +- n/a +- Not supported + +--- + +- `sourceRoot` +- n/a +- Not supported + +--- + +- `sourcemap` +- `sourcemap` +- Supports `"inline"`, `"external"`, and `"none"` + +--- + +- `sourcesContent` +- n/a +- Not supported + +--- + +- `splitting` +- `splitting` +- No differences + +--- + +- `stdin` +- n/a +- Not supported + +--- + +- `supported` +- n/a +- Not supported + +--- + +- `target` +- n/a +- No support for syntax downleveling + +--- + +- `treeShaking` +- n/a +- Always `true` + +--- + +- `tsconfig` +- n/a +- Not supported + +--- + +- `write` +- n/a +- Set to `true` if `outdir`/`outfile` is set, otherwise `false` + +--- + +{% /table %} + +## Plugin API + +Bun's plugin API is designed to be esbuild compatible. Bun doesn't support esbuild's entire plugin API surface, but the core functionality is implemented. Many third-party `esbuild` plugins will work out of the box with Bun. + +{% callout %} +Long term, we aim for feature parity with esbuild's API, so if something doesn't work please file an issue to help us prioritize. + +{% /callout %} + +Plugins in Bun and esbuild are defined with a `builder` object. + +```ts +import type { BunPlugin } from "bun"; + +const myPlugin: BunPlugin = { + name: "my-plugin", + setup(builder) { + // define plugin + }, +}; +``` + +The `builder` object provides some methods for hooking into parts of the bundling process. Bun implements `onResolve` and `onLoad`; it does not yet implement the esbuild hooks `onStart`, `onEnd`, and `onDispose`, or the `initialOptions` and `resolve` utilities. + +```ts +import type { BunPlugin } from "bun"; +const myPlugin: BunPlugin = { + name: "my-plugin", + setup(builder) { + builder.onResolve( + { + /* onResolve.options */ + }, + args => { + return { + /* onResolve.results */ + }; + }, + ); + builder.onLoad( + { + /* onLoad.options */ + }, + args => { + return { + /* onLoad.results */ + }; + }, + ); + }, +}; +``` + +### `onResolve` + +#### `options` + +{% table %} + +- 🟢 +- `filter` + +--- + +- 🟢 +- `namespace` + +{% /table %} + +#### `arguments` + +{% table %} + +- 🟢 +- `path` + +--- + +- 🟢 +- `importer` + +--- + +- 🔴 +- `namespace` + +--- + +- 🔴 +- `resolveDir` + +--- + +- 🔴 +- `kind` + +--- + +- 🔴 +- `pluginData` + +{% /table %} + +#### `results` + +{% table %} + +- 🟢 +- `namespace` + +--- + +- 🟢 +- `path` + +--- + +- 🔴 +- `errors` + +--- + +- 🔴 +- `external` + +--- + +- 🔴 +- `pluginData` + +--- + +- 🔴 +- `pluginName` + +--- + +- 🔴 +- `sideEffects` + +--- + +- 🔴 +- `suffix` + +--- + +- 🔴 +- `warnings` + +--- + +- 🔴 +- `watchDirs` + +--- + +- 🔴 +- `watchFiles` + +{% /table %} + +### `onLoad` + +#### `options` + +{% table %} + +--- + +- 🟢 +- `filter` + +--- + +- 🟢 +- `namespace` + +{% /table %} + +#### `arguments` + +{% table %} + +--- + +- 🟢 +- `path` + +--- + +- 🔴 +- `namespace` + +--- + +- 🔴 +- `suffix` + +--- + +- 🔴 +- `pluginData` + +{% /table %} + +#### `results` + +{% table %} + +--- + +- 🟢 +- `contents` + +--- + +- 🟢 +- `loader` + +--- + +- 🔴 +- `errors` + +--- + +- 🔴 +- `pluginData` + +--- + +- 🔴 +- `pluginName` + +--- + +- 🔴 +- `resolveDir` + +--- + +- 🔴 +- `warnings` + +--- + +- 🔴 +- `watchDirs` + +--- + +- 🔴 +- `watchFiles` + +{% /table %} diff --git a/docs/bundler/plugins.md b/docs/bundler/plugins.md index 68d2b3107..c652e0583 100644 --- a/docs/bundler/plugins.md +++ b/docs/bundler/plugins.md @@ -63,7 +63,7 @@ console.log(config); {% /details %} -## Third party plugins +## Third-party plugins By convention, third-party plugins intended for consumption should export a factory function that accepts some configuration and returns a plugin object. @@ -164,7 +164,7 @@ releaseYear: 2023 Note that the returned object has a `loader` property. This tells Bun which of its internal loaders should be used to handle the result. Even though we're implementing a loader for `.yaml`, the result must still be understandable by one of Bun's built-in loaders. It's loaders all the way down. -In this case we're using `"object"`—a special loader (intended for use by plugins) that converts a plain JavaScript object to an equivalent ES module. Any of Bun's built-in loaders are supported; these same loaders are used by Bun internally for handling files of various extensions. +In this case we're using `"object"`—a built-in loader (intended for use by plugins) that converts a plain JavaScript object to an equivalent ES module. Any of Bun's built-in loaders are supported; these same loaders are used by Bun internally for handling files of various kinds. The table below is a quick reference; refer to [Bundler > Loaders](/docs/bundler/loaders) for complete documentation. {% table %} @@ -175,13 +175,13 @@ In this case we're using `"object"`—a special loader (intended for use by plug --- - `js` -- `.js` `.mjs` `.cjs` +- `.mjs` `.cjs` - Transpile to JavaScript files --- - `jsx` -- `.jsx` +- `.js` `.jsx` - Transform JSX then transpile --- @@ -210,8 +210,20 @@ In this case we're using `"object"`—a special loader (intended for use by plug --- +- `napi` +- `.node` +- Import a native Node.js addon + +--- + +- `wasm` +- `.wasm` +- Import a native Node.js addon + +--- + - `object` -- — +- _none_ - A special loader intended for plugins that converts a plain JavaScript object to an equivalent ES module. Each key in the object corresponds to a named export. {% /callout %} diff --git a/docs/cli/build.md b/docs/cli/build.md index 3ce34df1d..f205969d5 100644 --- a/docs/cli/build.md +++ b/docs/cli/build.md @@ -4,7 +4,7 @@ Bun's fast native bundler is now in beta. It can be used via the `bun build` CLI command or the `Bun.build()` JavaScript API. -{% codetabs %} +{% codetabs group="a" %} ```ts#JavaScript await Bun.build({ @@ -55,7 +55,7 @@ Here, `index.tsx` is the "entrypoint" to our application. Commonly, this will be To create our bundle: -{% codetabs %} +{% codetabs group="a" %} ```ts#JavaScript await Bun.build({ @@ -80,7 +80,7 @@ For each file specified in `entrypoints`, Bun will generate a new bundle. This b └── index.js ``` -The contents of the `out/index.js` file looks something like this: +The contents of `out/index.js` will look something like this: ```js#out/index.js // ... @@ -176,6 +176,11 @@ Like the Bun runtime, the bundler supports an array of file types out of the box console.log(contents); // => "Hello, world!" ``` +--- + +- `.node` `.wasm` +- These files are supported by the Bun runtime, but during bundling they are treated as [assets](#assets). + {% /table %} ### Assets @@ -184,19 +189,14 @@ If the bundler encounters an import with an unrecognized extension, it treats th {% codetabs %} -```ts#Build file -await Bun.build({ - entrypoints: ['./index.ts'], - outdir: './out' -}) -``` - ```ts#Input +// bundle entrypoint import logo from "./logo.svg"; console.log(logo); ``` ```ts#Output +// bundled output var logo = "./logo-ab237dfe.svg"; console.log(logo); ``` @@ -219,7 +219,7 @@ The behavior described in this table can be overridden with [plugins](/docs/bund **Required.** An array of paths corresponding to the entrypoints of our application. One bundle will be generated for each entrypoint. -{% codetabs %} +{% codetabs group="a" %} ```ts#JavaScript const result = await Bun.build({ @@ -242,7 +242,7 @@ $ bun build --entrypoints ./index.ts The directory where output files will be written. -{% codetabs %} +{% codetabs group="a" %} ```ts#JavaScript const result = await Bun.build({ @@ -283,7 +283,7 @@ When `outdir` is specified: The intended execution environment for the bundle. -{% codetabs %} +{% codetabs group="a" %} ```ts#JavaScript await Bun.build({ @@ -350,7 +350,7 @@ $ bun build ./index.tsx --outdir ./out --format esm Whether to enable bundling. -{% codetabs %} +{% codetabs group="a" %} ```ts#JavaScript await Bun.build({ @@ -369,7 +369,7 @@ $ bun build ./index.tsx --outdir ./out Set to `false` to disable bundling. Instead, files will be transpiled and individually written to `outdir`. -{% codetabs %} +{% codetabs group="a" %} ```ts#JavaScript await Bun.build({ @@ -389,7 +389,7 @@ $ bun build ./index.tsx --outdir ./out --no-bundling Whether to enable code splitting. -{% codetabs %} +{% codetabs group="a" %} ```ts#JavaScript await Bun.build({ @@ -425,7 +425,7 @@ export const shared = 'shared'; To bundle `entry-a.ts` and `entry-b.ts` with code-splitting enabled: -{% codetabs %} +{% codetabs group="a" %} ```ts#JavaScript await Bun.build({ @@ -461,7 +461,7 @@ The generated `chunk-2fce6291bf86559d.js` file contains the shared code. To avoi A list of plugins to use during bundling. -{% codetabs %} +{% codetabs group="a" %} ```ts#JavaScript await Bun.build({ @@ -544,18 +544,18 @@ By design, the manifest is a simple JSON object that can easily be serialized or Specifies the type of sourcemap to generate. -{% codetabs %} +{% codetabs group="a" %} ```ts#JavaScript await Bun.build({ entrypoints: ['./index.tsx'], outdir: './out', - sourcemap: "inline", // default "none" + sourcemap: "external", // default "none" }) ``` ```bash#CLI -$ bun build ./index.tsx --outdir ./out --sourcemap=inline +$ bun build ./index.tsx --outdir ./out --sourcemap=external ``` {% /codetabs %} @@ -570,7 +570,13 @@ $ bun build ./index.tsx --outdir ./out --sourcemap=inline --- - `"inline"` -- A sourcemap is generated and appended to the end of the generated bundle as a base64 payload inside a `//# sourceMappingURL=` comment. +- A sourcemap is generated and appended to the end of the generated bundle as a base64 payload. + + ```ts + // <bundled code here> + + //# sourceMappingURL=data:application/json;base64,<encoded sourcemap here> + ``` --- @@ -579,6 +585,20 @@ $ bun build ./index.tsx --outdir ./out --sourcemap=inline {% /table %} +{% callout %} + +Generated bundles contain a [debug id](https://sentry.engineering/blog/the-case-for-debug-ids) that can be used to associate a bundle with its corresponding sourcemap. This `debugId` is added as a comment at the bottom of the file. + +```ts +// <generated bundle code> + +//# debugId=<DEBUG ID> +``` + +The associated `*.js.map` sourcemap will be a JSON file containing an equivalent `debugId` property. + +{% /callout %} + ### `minify` Whether to enable minification. Default `false`. @@ -589,7 +609,7 @@ When targeting `bun`, identifiers will be minified by default. To enable all minification options: -{% codetabs %} +{% codetabs group="a" %} ```ts#JavaScript await Bun.build({ @@ -607,7 +627,7 @@ $ bun build ./index.tsx --outdir ./out --minify To granularly enable certain minifications: -{% codetabs %} +{% codetabs group="a" %} ```ts#JavaScript await Bun.build({ @@ -635,7 +655,7 @@ boolean; --> A list of import paths to consider _external_. Defaults to `[]`. -{% codetabs %} +{% codetabs group="a" %} ```ts#JavaScript await Bun.build({ @@ -665,7 +685,7 @@ console.log(_.upperCase(value)); Normally, bundling `index.tsx` would generate a bundle containing the entire source code of the `"zod"` package. If instead, we want to leave the `import` statement as-is, we can mark it as external: -{% codetabs %} +{% codetabs group="a" %} ```ts#JavaScript await Bun.build({ @@ -698,7 +718,7 @@ console.log(_.upperCase(value)); Customizes the generated file names. Defaults to `./[dir]/[name].[ext]`. -{% codetabs %} +{% codetabs group="a" %} ```ts#JavaScript await Bun.build({ @@ -773,7 +793,7 @@ For example: We can combine these tokens to create a template string. For instance, to include the hash in the generated bundle names: -{% codetabs %} +{% codetabs group="a" %} ```ts#JavaScript await Bun.build({ @@ -801,7 +821,7 @@ This build would result in the following file structure: When a `string` is provided for the `naming` field, it is used only for bundles _that correspond to entrypoints_. The names of [chunks](#splitting) and copied assets are not affected. Using the JavaScript API, separate template strings can be specified for each type of generated file. -{% codetabs %} +{% codetabs group="a" %} ```ts#JavaScript await Bun.build({ @@ -826,7 +846,7 @@ $ bun build ./index.tsx --outdir ./out --entry-naming "[dir]/[name].[ext]" --chu The root directory of the project. -{% codetabs %} +{% codetabs group="a" %} ```ts#JavaScript await Bun.build({ @@ -853,7 +873,7 @@ If unspecified, it is computed to be the first common ancestor of all entrypoint We can build both entrypoints in the `pages` directory: -{% codetabs %} +{% codetabs group="a" %} ```ts#JavaScript await Bun.build({ @@ -884,7 +904,7 @@ Since the `pages` directory is the first common ancestor of the entrypoint files This behavior can be overridden by specifying the `root` option: -{% codetabs %} +{% codetabs group="a" %} ```ts#JavaScript await Bun.build({ @@ -945,7 +965,7 @@ console.log(logo); Setting `publicPath` will prefix all file paths with the specified value. -{% codetabs %} +{% codetabs group="a" %} ```ts#JavaScript await Bun.build({ @@ -971,32 +991,66 @@ The output file would now look something like this. ## Reference ```ts -await Bun.build({ - entrypoints: string[]; // list of file path - outdir?: string; // default to in-memory build - target?: "browser" | "bun" | "node"; // default: "browser" - splitting?: boolean; // default true - plugins?: BunPlugin[]; - manifest?: boolean; // default false - external?: string[]; - naming?: string | { - entry?: string; // default '[dir]/[name].[ext]' - chunk?: string; // default '[name]-[hash].[ext]' - asset?: string; // default '[name]-[hash].[ext]' - }; +interface Bun { + build(options: BuildOptions): Promise<{ + outputs: Array<{ path: string; result: Blob | BunFile }>; + manifest?: BuildManifest; + }>; +} + +interface BuildOptions { + entrypoints: string[]; // required + outdir?: string; // default: no write (in-memory only) + target?: "browser" | "bun" | "node"; // "browser" + splitting?: boolean; // true + plugins?: BunPlugin[]; // [] + loader?: { [k in string]: Loader }; + manifest?: boolean; // false + external?: string[]; // [] + sourcemap?: "none" | "inline" | "external"; // "none" + root?: string; // computed from entrypoints + naming?: + | string + | { + entry?: string; // '[dir]/[name].[ext]' + chunk?: string; // '[name]-[hash].[ext]' + asset?: string; // '[name]-[hash].[ext]' + }; publicPath?: string; // e.g. http://mydomain.com/ - minify?: boolean | { // default false - identifiers?: boolean; - whitespace?: boolean; - syntax?: boolean; + minify?: + | boolean // false + | { + identifiers?: boolean; + whitespace?: boolean; + syntax?: boolean; + }; +} + +interface BuildManifest { + inputs: { + [path: string]: { + output: { + path: string; + }; + imports: { + path: string; + kind: ImportKind; + external?: boolean; + asset?: boolean; // whether the import defaulted to "file" loader + }[]; + }; }; -}); + outputs: { + [path: string]: { + type: "chunk" | "entrypoint" | "asset"; + inputs: { path: string }[]; + imports: { + path: string; + kind: ImportKind; + external?: boolean; + }[]; + exports: string[]; + }; + }; +} ``` - -<!-- -root?: string; // project root -format?: "esm"; // later: "cjs", "iife" -loader?: { [k in string]: Loader }; -sourcemap?: "none" | "inline" | "external"; // default: "none" -treeshaking?: boolean; ---> diff --git a/docs/nav.ts b/docs/nav.ts index fcafdf25f..b0f0932e3 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/migration", "Migration", { + description: `Guides for migrating from other bundlers to Bun.`, + }), divider("Test runner"), page("cli/test", "`bun test`", { @@ -202,7 +205,7 @@ export default { page("ecosystem/stric", "Stric", { description: `Stric is a minimalist, fast web framework for Bun.`, }), - + page("ecosystem/awesome", "Awesome", { href: "https://github.com/apvarun/awesome-bun", description: ``, diff --git a/docs/runtime/index.md b/docs/runtime/index.md index b835ba464..b97deb122 100644 --- a/docs/runtime/index.md +++ b/docs/runtime/index.md @@ -303,4 +303,4 @@ Bun exposes a set of Bun-specific APIs on the `Bun` global object and through a ## Plugins -Support for additional file types can be implemented with plugins. Refer to [Runtime > Plugins](/docs/runtime/plugins) for full documentation. +Support for additional file types can be implemented with plugins. Refer to [Runtime > Plugins](/docs/bundler/plugins) for full documentation. diff --git a/docs/runtime/loaders.md b/docs/runtime/loaders.md index b73350e56..a483efbec 100644 --- a/docs/runtime/loaders.md +++ b/docs/runtime/loaders.md @@ -82,7 +82,7 @@ $ bun run ./my-wasm-app.whatever ## Custom loaders -Support for additional file types can be implemented with plugins. Refer to [Runtime > Plugins](/docs/runtime/plugins) for full documentation. +Support for additional file types can be implemented with plugins. Refer to [Runtime > Plugins](/docs/bundler/plugins) for full documentation. <!-- diff --git a/packages/bun-types/bun.d.ts b/packages/bun-types/bun.d.ts index e14118680..03c17001c 100644 --- a/packages/bun-types/bun.d.ts +++ b/packages/bun-types/bun.d.ts @@ -953,7 +953,7 @@ declare module "bun" { entrypoints: string[]; // list of file path outdir?: string; // output directory target?: Target; // default: "browser" - // format?: ModuleFormat; // later: "cjs", "iife" + format?: ModuleFormat; // later: "cjs", "iife" naming?: | string |