aboutsummaryrefslogtreecommitdiff
path: root/docs/cli
diff options
context:
space:
mode:
authorGravatar Colin McDonnell <colinmcd94@gmail.com> 2023-04-28 08:35:20 -0700
committerGravatar GitHub <noreply@github.com> 2023-04-28 08:35:20 -0700
commit1483d73c3a9a4a045287df62c85b2173d80e8ceb (patch)
tree77aa6307d7b452b2759c3e7d53f3ebdc8761dd78 /docs/cli
parent52c50e37371ed0bf208de2b2e8dbf7c2cc1bd97c (diff)
downloadbun-1483d73c3a9a4a045287df62c85b2173d80e8ceb.tar.gz
bun-1483d73c3a9a4a045287df62c85b2173d80e8ceb.tar.zst
bun-1483d73c3a9a4a045287df62c85b2173d80e8ceb.zip
Bundler docs updates + support for `naming` string (#2767)
* Bundler docs updates * Remove comments * Updates * Fix bunx usages * Add info about metafile
Diffstat (limited to 'docs/cli')
-rw-r--r--docs/cli/build.md299
1 files changed, 166 insertions, 133 deletions
diff --git a/docs/cli/build.md b/docs/cli/build.md
index 2c7c78d4f..b4c7984dc 100644
--- a/docs/cli/build.md
+++ b/docs/cli/build.md
@@ -1,5 +1,5 @@
{% callout %}
-**Note** — Added in Bun v0.6.0
+**Note** — Available in the Bun v0.6.0 nightly. Run `bun upgrade --canary` to try it out.
{% /callout %}
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.
@@ -58,7 +58,7 @@ To create our bundle:
{% codetabs %}
```ts#JavaScript
-Bun.build({
+await Bun.build({
entrypoints: ['./index.tsx'],
outdir: './out',
})
@@ -70,12 +70,7 @@ $ bun build ./index.tsx --outdir ./out
{% /codetabs %}
-Let's break that down.
-
-- `entrypoints` — **Required.** An array of paths corresponding to the entrypoints of our application. In this case, we just have one.
-- `outdir` — **Required.** The directory where output files will be written.
-
-Running this build will generate a new file `./out/index.js`.
+For each file specified in `entrypoints`, Bun will generate a new bundle. This bundle will be written to disk in the `./out` directory (as resolved from the current working directory). After running the build, the file system looks like this:
```ts
.
@@ -85,18 +80,18 @@ Running this build will generate a new file `./out/index.js`.
└── index.js
```
-It looks something like this:
+The contents of the `out/index.js` file looks something like this:
```js#out/index.js
// ...
// ~20k lines of code
// including the contents of `react-dom/client` and all its dependencies
-// this is where the $jsx and $createRoot functions are defined
+// this is where the $jsxDEV and $createRoot functions are defined
// Component.tsx
function Component(props) {
- return $jsx("p", {
+ return $jsxDEV("p", {
children: props.message
}, undefined, false, undefined, this);
}
@@ -104,7 +99,7 @@ function Component(props) {
// index.tsx
var rootNode = document.getElementById("root");
var root = $createRoot(rootNode);
-root.render($jsx(Component, {
+root.render($jsxDEV(Component, {
message: "Sup!"
}, undefined, false, undefined, this));
```
@@ -181,58 +176,42 @@ Like the Bun runtime, the bundler supports an array of file types out of the box
console.log(contents); // => "Hello, world!"
```
----
-
-- `.*`
-- If the bundler encounters a file with an unsupported extension, it treats it as an _external file_. That means the import is converted into a path, and the referenced file is copied into the `outdir` as-is.
-
- {% codetabs %}
-
- ```ts#Build_file
- Bun.build({
- entrypoints: ['./index.ts'],
- outdir: './out',
- origin: 'https://example.com',
- })
- ```
+{% /table %}
- ```ts#Input
- import logo from "./logo.svg";
- console.log(logo);
- ```
+### Assets
- ```ts#Output
- var logo = "./logo-ab237dfe.svg";
- console.log(logo);
- ```
+If the bundler encounters an import with an unrecognized extension, it treats the imported file as an _external file_. The referenced file is copied as-is into `outdir`, and the import is resolved as a _path_ to the file.
- {% /codetabs %}
+{% codetabs %}
- By default, a hash is added to the file name to avoid collisions; this behavior can be overridden with the [`naming.asset`](#naming) option.
+```ts#Build_file
+await Bun.build({
+ entrypoints: ['./index.ts'],
+ outdir: './out'
+})
+```
- If a value is provided for `origin`, the bundler will construct an absolute URL instead of using a relative path.
+```ts#Input
+import logo from "./logo.svg";
+console.log(logo);
+```
- {% codetabs %}
+```ts#Output
+var logo = "./logo-ab237dfe.svg";
+console.log(logo);
+```
- ```ts-diff#Build_file
- Bun.build({
- entrypoints: ['./index.ts'],
- outdir: './out',
- + origin: 'https://example.com',
- })
- ```
+{% /codetabs %}
- ```ts-diff#Output
- - var logo = "./logo-ab237dfe.svg";
- + var logo = "https://example.com/logo-ab237dfe.svg";
- console.log(logo);
- ```
+{% callout %}
+The exact behavior of the file loader is also impacted by [`naming`](#naming) and [`publicPath`](#publicpath).
+{% /callout %}
- {% /codetabs %}
+Refer to the [Bundler > Loaders](/docs/bundler/loaders#file) page for more complete documentation on the file loader.
-{% /table %}
+### Plugins
-The behavior described in this table can be overridden with [plugins](/docs/bundler/plugins). Refer to the [Bundler > Loaders](/docs/bundler/loaders) page for complete documentation on Bun's built-in loaders.
+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.
## API
@@ -240,9 +219,65 @@ 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 %}
+
+```ts#JavaScript
+const result = await Bun.build({
+ entrypoints: ['./index.ts']
+}); // => Promise
+
+await result;
+// => { outputs: Array<{ path: string; result: Blob }> }
+```
+
+```bash#CLI
+$ bun build --entrypoints ./index.ts
+# the bundle will be printed to stdout
+# <bundled code>
+```
+
+{% /codetabs %}
+
### `outdir`
-**Required.** The directory where output files will be written.
+The directory where output files will be written.
+
+{% codetabs %}
+
+```ts#JavaScript
+const result = await Bun.build({
+ entrypoints: ['./index.ts'],
+ outdir: './out'
+});
+
+result;
+// => { outputs: Array<{ path: string; result: BunFile }> }
+```
+
+```bash#CLI
+$ bun build --entrypoints ./index.ts --outdir ./out
+# the bundle will be printed to stdout
+# ...
+```
+
+{% /codetabs %}
+
+When `outdir` is specified:
+
+- The JavaScript API will write the generated bundles to the appropriate location in `outdir`. The result of the `Bun.build()` call will contain `BunFile` instances corresponding to the new files.
+
+ ```ts
+ const result = await Bun.build({
+ /* ... */
+ });
+ // => { outputs: Array<{ path: string; result: BunFile }> }
+
+ for (const { path, result } of result.outputs) {
+ console.log(`Wrote file: ${path}`);
+ }
+ ```
+
+- The CLI will print a summary of the written files. The bundled code will not be written to `stdout`.
### `target`
@@ -251,7 +286,7 @@ The intended execution environment for the bundle.
{% codetabs %}
```ts#JavaScript
-Bun.build({
+await Bun.build({
entrypoints: ['./index.ts'],
outdir: './out',
target: 'browser', // default
@@ -259,7 +294,7 @@ Bun.build({
```
```bash#CLI
-$ bunx build --entrypoints ./index.ts --outdir ./out --target browser
+$ bun build --entrypoints ./index.ts --outdir ./out --target browser
```
{% /codetabs %}
@@ -298,27 +333,27 @@ Currently the bundler only supports one module format: `"esm"`. Support for `"cj
{% codetabs %}
```ts#Bun.build
-Bun.build({
+await Bun.build({
entrypoints: ['./index.tsx'],
outdir: './out',
- module: "esm",
+ format: "esm",
})
```
```bash#CLI
-$ bun build ./index.tsx --outdir ./out --module esm
+$ bun build ./index.tsx --outdir ./out --format esm
```
{% /codetabs %} -->
-### `bundling`
+<!-- ### `bundling`
Whether to enable bundling.
{% codetabs %}
```ts#JavaScript
-Bun.build({
+await Bun.build({
entrypoints: ['./index.tsx'],
outdir: './out',
bundling: true, // default
@@ -337,7 +372,7 @@ Set to `false` to disable bundling. Instead, files will be transpiled and indivi
{% codetabs %}
```ts#JavaScript
-Bun.build({
+await Bun.build({
entrypoints: ['./index.tsx'],
outdir: './out',
bundling: false,
@@ -348,7 +383,7 @@ Bun.build({
$ bun build ./index.tsx --outdir ./out --no-bundling
```
-{% /codetabs %}
+{% /codetabs %} -->
### `splitting`
@@ -357,7 +392,7 @@ Whether to enable code splitting.
{% codetabs %}
```ts#JavaScript
-Bun.build({
+await Bun.build({
entrypoints: ['./index.tsx'],
outdir: './out',
splitting: false, // default
@@ -393,7 +428,7 @@ To bundle `entry-a.ts` and `entry-b.ts` with code-splitting enabled:
{% codetabs %}
```ts#JavaScript
-Bun.build({
+await Bun.build({
entrypoints: ['./entry-a.ts', './entry-b.ts'],
outdir: './out',
splitting: true,
@@ -429,7 +464,7 @@ A list of plugins to use during bundling.
{% codetabs %}
```ts#JavaScript
-Bun.build({
+await Bun.build({
entrypoints: ['./index.tsx'],
outdir: './out',
plugins: [/* ... */],
@@ -458,6 +493,7 @@ const result = await Bun.build({
console.log(result.manifest);
```
+The manifest takes the following form:
{% details summary="Manifest structure" %}
The manifest has the following form:
@@ -503,6 +539,8 @@ export type ImportKind =
{% /details %}
+By design, the manifest is a simple JSON object that can easily be serialized or written to disk. It is also compatible with esbuild's [`metafile`](https://esbuild.github.io/api/#metafile) format.
+
### `sourcemap`
Specifies the type of sourcemap to generate.
@@ -510,7 +548,7 @@ Specifies the type of sourcemap to generate.
{% codetabs %}
```ts#JavaScript
-Bun.build({
+await Bun.build({
entrypoints: ['./index.tsx'],
outdir: './out',
sourcemap: "inline", // default "none"
@@ -544,12 +582,18 @@ $ bun build ./index.tsx --outdir ./out --sourcemap=inline
### `minify`
-Whether to enable minification. Default `false`. To enable minification:
+Whether to enable minification. Default `false`.
+
+{% callout %}
+When targeting `bun`, identifiers will be minified by default.
+{% /callout %}
+
+To enable all minification options:
{% codetabs %}
```ts#JavaScript
-Bun.build({
+await Bun.build({
entrypoints: ['./index.tsx'],
outdir: './out',
minify: true, // default false
@@ -562,12 +606,12 @@ $ bun build ./index.tsx --outdir ./out --minify
{% /codetabs %}
-This will enable all minification options. To granularly enable certain minifications:
+To granularly enable certain minifications:
{% codetabs %}
```ts#JavaScript
-Bun.build({
+await Bun.build({
entrypoints: ['./index.tsx'],
outdir: './out',
minify: {
@@ -595,7 +639,7 @@ A list of import paths to consider _external_. Defaults to `[]`.
{% codetabs %}
```ts#JavaScript
-Bun.build({
+await Bun.build({
entrypoints: ['./index.tsx'],
outdir: './out',
external: ["lodash", "react"], // default: []
@@ -618,7 +662,6 @@ import {z} from "zod";
const value = z.string().parse("Hello world!")
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:
@@ -626,7 +669,7 @@ Normally, bundling `index.tsx` would generate a bundle containing the entire sou
{% codetabs %}
```ts#JavaScript
-Bun.build({
+await Bun.build({
entrypoints: ['./index.tsx'],
outdir: './out',
external: ['zod'],
@@ -659,10 +702,10 @@ Customizes the generated file names. Defaults to `./[dir]/[name].[ext]`.
{% codetabs %}
```ts#JavaScript
-Bun.build({
+await Bun.build({
entrypoints: ['./index.tsx'],
outdir: './out',
- naming: "[dir]/[name].[ext]", // default
+ naming: "./[dir]/[name].[ext]", // default
})
```
@@ -694,12 +737,12 @@ With multiple entrypoints, the generated file hierarchy will reflect the directo
└── index.js
```
-The names of these files can be customized with the `naming` field. This field accepts a template string that is used to generate the filenames for all bundles corresponding to entrypoints. where the following tokens are replaced with their corresponding values:
+The names and locations of the generated files can be customized with the `naming` field. This field accepts a template string that is used to generate the filenames for all bundles corresponding to entrypoints. where the following tokens are replaced with their corresponding values:
-- `[name]` - The name of the entrypoint file, without the extension, e.g. `index`
-- `[ext]` - The extension of the generated bundle, e.g. `js`
-- `[hash]` - A hash of the bundle contents, e.g. `a1b2c3d4`
-- `[dir]` - The relative path from the build [`root`](#root) to the parent directory of the file, e.g. `nested`
+- `[name]` - The name of the entrypoint file, without the extension.
+- `[ext]` - The extension of the generated bundle.
+- `[hash]` - A hash of the bundle contents.
+- `[dir]` - The relative path from the build root to the parent directory of the file.
For example:
@@ -734,10 +777,10 @@ We can combine these tokens to create a template string. For instance, to includ
{% codetabs %}
```ts#JavaScript
-Bun.build({
+await Bun.build({
entrypoints: ['./index.tsx'],
outdir: './out',
- naming: '[dir]/[name]-[hash].[ext]',
+ naming: 'files/[dir]/[name]-[hash].[ext]',
})
```
@@ -753,7 +796,8 @@ This build would result in the following file structure:
.
├── index.tsx
└── out
- └── index-a1b2c3d4.js
+ └── files
+ └── index-a1b2c3d4.js
```
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.
@@ -761,7 +805,7 @@ When a `string` is provided for the `naming` field, it is used only for bundles
{% codetabs %}
```ts#JavaScript
-Bun.build({
+await Bun.build({
entrypoints: ['./index.tsx'],
outdir: './out',
naming: {
@@ -778,14 +822,14 @@ n/a
{% /codetabs %}
-### `root`
+<!-- ### `root`
The root directory of the project.
{% codetabs %}
```ts#JavaScript
-Bun.build({
+await Bun.build({
entrypoints: ['./pages/a.tsx', './pages/b.tsx'],
outdir: './out',
root: '.',
@@ -812,7 +856,7 @@ We can build both entrypoints in the `pages` directory:
{% codetabs %}
```ts#JavaScript
-Bun.build({
+await Bun.build({
entrypoints: ['./pages/index.tsx', './pages/settings.tsx'],
outdir: './out',
})
@@ -843,7 +887,7 @@ This behavior can be overridden by specifying the `root` option:
{% codetabs %}
```ts#JavaScript
-Bun.build({
+await Bun.build({
entrypoints: ['./pages/index.tsx', './pages/settings.tsx'],
outdir: './out',
root: '.',
@@ -867,92 +911,80 @@ By specifying `.` as `root`, the generated file structure will look like this:
└── pages
└── index.js
└── settings.js
-```
+``` -->
-### `origin`
+### `publicPath`
-Used to generate absolute asset URLs.
+A prefix to be appended to any import paths in bundled code.
-{% codetabs %}
-
-```ts#JavaScript
-Bun.build({
- entrypoints: ['./index.tsx'],
- outdir: './out',
- origin: 'https://cdn.example.com', // default is undefined
-})
-```
+<!-- $ bun build ./index.tsx --outdir ./out --publicPath https://cdn.example.com -->
-```bash#CLI
-$ bun build ./index.tsx --outdir ./out --origin https://cdn.example.com
-```
+In many cases, generated bundles will contain no `import` statements. After all, the goal of bundling is to combine all of the code into a single file. However there are a number of cases with the generated bundles will contain `import` statements.
-{% /codetabs %}
+- **Asset imports** — When importing an unrecognized file type like `*.svg`, the bundler defers to the [`file` loader](/docs/bundler/loaders#file), which copies the file into `outdir` as is. The import is converted into a variable
+- **External modules** — Files and modules can be marked as [`external`](#external), in which case they will not be included in the bundle. Instead, the `import` statement will be left in the final bundle.
+- **Chunking**. When [`splitting`](#splitting) is enabled, the bundler may generate separate "chunk" files that represent code that is shared among multiple entrypoints.
-When the bundler encounters an unknown file type, it defaults to using the `"file"` loader. This converts the import path to an absolute URL that can be referenced in the file. This is useful for referencing images, fonts, and other static assets.
+In any of these cases, the final bundles may contain paths to other files. By default these imports are _relative_. Here is an example of a simple asset import:
-```tsx#Input
-import logo from "./images/logo.svg";
+{% codetabs %}
-export function Logo(){
- return <img src={logo} />
-}
+```ts#Input
+import logo from './logo.svg';
+console.log(logo);
```
-In the absence of a plugin that overrides `*.svg` loading, the `logo` import will be converted to a relative path:
-
-```ts
-var logo = "./logo.svg";
-
+```ts#Output
+// logo.svg is copied into <outdir>
+// and hash is added to the filename to prevent collisions
+var logo = './logo-a7305bdef.svg';
console.log(logo);
```
-This is fine for local development, but in production, we may want these imports to correspond to absolute URLs. To do this, we can specify the `origin` option:
+{% /codetabs %}
+
+Setting `publicPath` will prefix all file paths with the specified value.
{% codetabs %}
```ts#JavaScript
-Bun.build({
+await Bun.build({
entrypoints: ['./index.tsx'],
outdir: './out',
- origin: 'https://cdn.mydomain.com',
+ publicPath: 'https://cdn.example.com/', // default is undefined
})
```
```bash#CLI
-$ bun build ./index.tsx --outdir ./out --origin https://cdn.mydomain.com
+n/a
```
{% /codetabs %}
-With `origin` set to this value, the generated bundle will now be something like this:
+The output file would now look something like this.
-```ts-diff
-- var logo = "./logo.svg";
-+ var logo = "https://cdn.mydomain.com/logo.svg";
-
-console.log(logo);
+```ts-diff#Output
+- var logo = './logo-a7305bdef.svg';
++ var logo = 'https://cdn.example.com/logo-a7305bdef.svg';
```
## Reference
```ts
-Bun.build({
+await Bun.build({
entrypoints: string[]; // list of file path
- outdir: string; // output directory
+ outdir?: string; // output directory
target?: "browser" | "bun" | "node"; // default: "browser"
- bundling?: boolean, // default: false, transform instead of bundling
splitting?: boolean, // default true, enable code splitting
plugins?: BunPlugin[];
manifest?: boolean; // whether to return manifest
- external?: Array<string | RegExp>;
+ external?: Array<string>;
naming?: string | {
entrypoint?: string;
chunk?: string;
asset?: string;
}, // default './[dir]/[name].[ext]'
- root?: string; // project root
- origin?: string; // e.g. http://mydomain.com
+ publicPath?: string; // e.g. http://mydomain.com/
minify?: boolean | {
identifiers?: boolean;
whitespace?: boolean;
@@ -962,7 +994,8 @@ Bun.build({
```
<!--
-module?: "esm"; // later: "cjs", "iife"
+root?: string; // project root
+format?: "esm"; // later: "cjs", "iife"
loader?: { [k in string]: Loader };
sourcemap?: "none" | "inline" | "external"; // default: "none"
treeshaking?: boolean;