Skip to content

Commit

Permalink
Merge branch 'main' of github.com:oven-sh/bun into don/build/zig-test
Browse files Browse the repository at this point in the history
  • Loading branch information
DonIsaac committed Dec 30, 2024
2 parents d98c847 + 18ac7f9 commit ac7ff8c
Show file tree
Hide file tree
Showing 241 changed files with 16,501 additions and 6,698 deletions.
7 changes: 7 additions & 0 deletions .cursorignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Add directories or file patterns to ignore during indexing (e.g. foo/ or *.csv)
bench
vendor
*-fixture.{js,ts}
zig-cache
packages/bun-uws/fuzzing
build
2 changes: 1 addition & 1 deletion LATEST
Original file line number Diff line number Diff line change
@@ -1 +1 @@
1.1.40
1.1.41
62 changes: 62 additions & 0 deletions bench/snippets/zlib.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import { bench, run } from "../runner.mjs";
import zlib from "node:zlib";
import { promisify } from "node:util";

const deflate = promisify(zlib.deflate);
const inflate = promisify(zlib.inflate);

const short = "Hello World!";
const long = "Hello World!".repeat(1024);
const veryLong = "Hello World!".repeat(10240);

// Pre-compress some data for decompression tests
const shortBuf = Buffer.from(short);
const longBuf = Buffer.from(long);
const veryLongBuf = Buffer.from(veryLong);

let [shortCompressed, longCompressed, veryLongCompressed] = await Promise.all([
deflate(shortBuf, { level: 6 }),
deflate(longBuf, { level: 6 }),
deflate(veryLongBuf, { level: 6 }),
]);

const format = new Intl.NumberFormat("en-US", { notation: "compact", unit: "byte" });
// Compression tests at different levels
bench(`deflate ${format.format(short.length)}B (level 1)`, async () => {
await deflate(shortBuf, { level: 1 });
});

bench(`deflate ${format.format(short.length)} (level 6)`, async () => {
await deflate(shortBuf, { level: 6 });
});

bench(`deflate ${format.format(long.length)} (level 1)`, async () => {
await deflate(longBuf, { level: 1 });
});

bench(`deflate ${format.format(long.length)} (level 6)`, async () => {
await deflate(longBuf, { level: 6 });
});

bench(`deflate ${format.format(veryLong.length)} (level 1)`, async () => {
await deflate(veryLongBuf, { level: 1 });
});

bench(`deflate ${format.format(veryLong.length)} (level 6)`, async () => {
await deflate(veryLongBuf, { level: 6 });
});

// Decompression tests
bench(`inflate ${format.format(short.length)}`, async () => {
await inflate(shortCompressed);
});

bench(`inflate ${format.format(long.length)}`, async () => {
await inflate(longCompressed);
});

bench(`inflate ${format.format(veryLong.length)}`, async () => {
await inflate(veryLongCompressed);
});

await run();
2 changes: 1 addition & 1 deletion cmake/targets/BuildBun.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -860,7 +860,7 @@ endif()

if(WIN32)
target_link_options(${bun} PUBLIC
/STACK:0x1200000,0x100000
/STACK:0x1200000,0x200000
/errorlimit:0
)
if(RELEASE)
Expand Down
2 changes: 1 addition & 1 deletion cmake/targets/BuildLibDeflate.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ register_repository(
REPOSITORY
ebiggers/libdeflate
COMMIT
9d624d1d8ba82c690d6d6be1d0a961fc5a983ea4
733848901289eca058804ca0737f8796875204c8
)

register_cmake_command(
Expand Down
2 changes: 1 addition & 1 deletion cmake/tools/SetupWebKit.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ option(WEBKIT_VERSION "The version of WebKit to use")
option(WEBKIT_LOCAL "If a local version of WebKit should be used instead of downloading")

if(NOT WEBKIT_VERSION)
set(WEBKIT_VERSION 3845bf370ff4e9a5c0b96036255142c7904be963)
set(WEBKIT_VERSION 00e2b186fd25e79cea4cb4d63d9fd388192327f6)
endif()

if(WEBKIT_LOCAL)
Expand Down
110 changes: 110 additions & 0 deletions docs/bundler/html.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
As of Bun v1.1.43, Bun's bundler now has first-class support for HTML. Build static sites, landing pages, and web applications with zero configuration. Just point Bun at your HTML file and it handles everything else.

```html#index.html
<!doctype html>
<html>
<head>
<link rel="stylesheet" href="./styles.css" />
<script src="./app.ts" type="module"></script>
</head>
<body>
<img src="./logo.png" />
</body>
</html>
```

One command is all you need (won't be experimental after Bun v1.2):

{% codetabs %}

```bash#CLI
$ bun build --experimental-html --experimental-css ./index.html --outdir=dist
```

```ts#API
Bun.build({
entrypoints: ["./index.html"],
outdir: "./dist",
// On by default in Bun v1.2+
html: true,
experimentalCss: true,
});
```

{% /codetabs %}

Bun automatically:

- Bundles, tree-shakes, and optimizes your JavaScript, JSX and TypeScript
- Bundles and optimizes your CSS
- Copies & hashes images and other assets
- Updates all references to local files or packages in your HTML

## Zero Config, Maximum Performance

The HTML bundler is enabled by default after Bun v1.2+. Drop in your existing HTML files and Bun will handle:

- **TypeScript & JSX** - Write modern JavaScript for browsers without the setup
- **CSS** - Bundle CSS stylesheets directly from `<link rel="stylesheet">` or `@import`
- **Images & Assets** - Automatic copying & hashing & rewriting of assets in JavaScript, CSS, and HTML

## Watch mode

You can run `bun build --watch` to watch for changes and rebuild automatically.

You've never seen a watch mode this fast.

## Plugin API

Need more control? Configure the bundler through the JavaScript API and use Bun's builtin `HTMLRewriter` to preprocess HTML.

```ts
await Bun.build({
entrypoints: ["./index.html"],
outdir: "./dist",
html: true,
experimentalCss: true,
minify: true,

plugins: [
{
// A plugin that makes every HTML tag lowercase
name: "lowercase-html-plugin",
setup({ onLoad }) {
const rewriter = new HTMLRewriter().on("*", {
element(element) {
element.tagName = element.tagName.toLowerCase();
},
text(element) {
element.replace(element.text.toLowerCase());
},
});

onLoad({ filter: /\.html$/ }, async args => {
const html = await Bun.file(args.path).text();

return {
// Bun's bundler will scan the HTML for <script> tags, <link rel="stylesheet"> tags, and other assets
// and bundle them automatically
contents: rewriter.transform(html),
loader: "html",
};
});
},
},
],
});
```

## What Gets Processed?

Bun automatically handles all common web assets:

- Scripts (`<script src>`) are run through Bun's JavaScript/TypeScript/JSX bundler
- Stylesheets (`<link rel="stylesheet">`) are run through Bun's CSS parser & bundler
- Images (`<img>`, `<picture>`) are copied and hashed
- Media (`<video>`, `<audio>`, `<source>`) are copied and hashed
- Any `<link>` tag with an `href` attribute pointing to a local file is rewritten to the new path, and hashed

All paths are resolved relative to your HTML file, making it easy to organize your project however you want.
77 changes: 76 additions & 1 deletion docs/bundler/loaders.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
The Bun bundler implements a set of default loaders out of the box. As a rule of thumb, the bundler and the runtime both support the same set of file types out of the box.

`.js` `.cjs` `.mjs` `.mts` `.cts` `.ts` `.tsx` `.jsx` `.toml` `.json` `.txt` `.wasm` `.node`
`.js` `.cjs` `.mjs` `.mts` `.cts` `.ts` `.tsx` `.jsx` `.toml` `.json` `.txt` `.wasm` `.node` `.html`

Bun uses the file extension to determine which built-in _loader_ should be used to parse the file. Every loader has a name, such as `js`, `tsx`, or `json`. These names are used when building [plugins](https://bun.sh/docs/bundler/plugins) that extend Bun with custom loaders.

Expand Down Expand Up @@ -203,6 +203,81 @@ When using a [standalone executable](https://bun.sh/docs/bundler/executables), t

Otherwise, the database to embed is copied into the `outdir` with a hashed filename.

### `html`

**HTML loader**. Default for `.html` after Bun v1.2.0.

To enable the html loader:

- For `Bun.build`: set `html: true`
- For `bun build`: `--experimental-html` CLI flag

You most likely want to use the `html` loader in conjunction with `experimentalCss: true` or `--experimental-css`.

The html loader processes HTML files and bundles any referenced assets. It will:

- Bundle and hash referenced JavaScript files (`<script src="...">`)
- Bundle and hash referenced CSS files (`<link rel="stylesheet" href="...">`)
- Hash referenced images (`<img src="...">`)
- Preserve external URLs (by default, anything starting with `http://` or `https://`)

For example, given this HTML file:

{% codetabs %}

```html#src/index.html
<!DOCTYPE html>
<html>
<body>
<img src="./image.jpg" alt="Local image">
<img src="https://example.com/image.jpg" alt="External image">
<script type="module" src="./script.js"></script>
</body>
</html>
```

{% /codetabs %}

It will output a new HTML file with the bundled assets:

{% codetabs %}

```html#dist/output.html
<!DOCTYPE html>
<html>
<body>
<img src="./image-HASHED.jpg" alt="Local image">
<img src="https://example.com/image.jpg" alt="External image">
<script type="module" src="./output-ALSO-HASHED.js"></script>
</body>
</html>
```

{% /codetabs %}

Under the hood, it uses [`lol-html`](https://github.com/cloudflare/lol-html) to extract script and link tags as entrypoints, and other assets as external.

Currently, the list of selectors is:

- `audio[src]`
- `iframe[src]`
- `img[src]`
- `img[srcset]`
- `link:not([rel~='stylesheet']):not([rel~='modulepreload']):not([rel~='manifest']):not([rel~='icon']):not([rel~='apple-touch-icon'])[href]`
- `link[as='font'][href], link[type^='font/'][href]`
- `link[as='image'][href]`
- `link[as='style'][href]`
- `link[as='video'][href], link[as='audio'][href]`
- `link[as='worker'][href]`
- `link[rel='icon'][href], link[rel='apple-touch-icon'][href]`
- `link[rel='manifest'][href]`
- `link[rel='stylesheet'][href]`
- `script[src]`
- `source[src]`
- `source[srcset]`
- `video[poster]`
- `video[src]`

### `sh` loader

**Bun Shell loader**. Default for `.sh` files
Expand Down
7 changes: 4 additions & 3 deletions docs/nav.ts
Original file line number Diff line number Diff line change
Expand Up @@ -214,9 +214,9 @@ export default {
page("bundler", "`Bun.build`", {
description: "Bundle code for consumption in the browser with Bun's native bundler.",
}),
// page("bundler/intro", "How bundlers work", {
// description: "A visual introduction to bundling",
// }),
page("bundler/html", "HTML", {
description: `Bundle html files with Bun's native bundler.`,
}),
page("bundler/loaders", "Loaders", {
description: "Bun's built-in loaders for the bundler and runtime",
}),
Expand All @@ -226,6 +226,7 @@ export default {
page("bundler/macros", "Macros", {
description: `Run JavaScript functions at bundle-time and inline the results into your bundle`,
}),

page("bundler/vs-esbuild", "vs esbuild", {
description: `Guides for migrating from other bundlers to Bun.`,
}),
Expand Down
Loading

0 comments on commit ac7ff8c

Please sign in to comment.