mirror of
https://github.com/oven-sh/bun
synced 2026-02-02 15:08:46 +00:00
docs: re-apply many recent changes that somehow aren't present (#24719)
lots of recent changes aren't present, so this reapplies them
This commit is contained in:
@@ -201,7 +201,7 @@ Bun generally takes about 2.5 minutes to compile a debug build when there are Zi
|
|||||||
- Batch up your changes
|
- Batch up your changes
|
||||||
- Ensure zls is running with incremental watching for LSP errors (if you use VSCode and install Zig and run `bun run build` once to download Zig, this should just work)
|
- Ensure zls is running with incremental watching for LSP errors (if you use VSCode and install Zig and run `bun run build` once to download Zig, this should just work)
|
||||||
- Prefer using the debugger ("CodeLLDB" in VSCode) to step through the code.
|
- Prefer using the debugger ("CodeLLDB" in VSCode) to step through the code.
|
||||||
- Use debug logs. `BUN_DEBUG_<scope>=1` will enable debug logging for the corresponding `Output.scoped(.<scope>, .hidden)` logs. You can also set `BUN_DEBUG_QUIET_LOGS=1` to disable all debug logging that isn't explicitly enabled. To dump debug lgos into a file, `BUN_DEBUG=<path-to-file>.log`. Debug logs are aggressively removed in release builds.
|
- Use debug logs. `BUN_DEBUG_<scope>=1` will enable debug logging for the corresponding `Output.scoped(.<scope>, .hidden)` logs. You can also set `BUN_DEBUG_QUIET_LOGS=1` to disable all debug logging that isn't explicitly enabled. To dump debug logs into a file, `BUN_DEBUG=<path-to-file>.log`. Debug logs are aggressively removed in release builds.
|
||||||
- src/js/\*\*.ts changes are pretty much instant to rebuild. C++ changes are a bit slower, but still much faster than the Zig code (Zig is one compilation unit, C++ is many).
|
- src/js/\*\*.ts changes are pretty much instant to rebuild. C++ changes are a bit slower, but still much faster than the Zig code (Zig is one compilation unit, C++ is many).
|
||||||
|
|
||||||
## Code generation scripts
|
## Code generation scripts
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ The order of the `--target` flag does not matter, as long as they're delimited b
|
|||||||
| bun-linux-x64 | Linux | x64 | ✅ | ✅ | glibc |
|
| bun-linux-x64 | Linux | x64 | ✅ | ✅ | glibc |
|
||||||
| bun-linux-arm64 | Linux | arm64 | ✅ | N/A | glibc |
|
| bun-linux-arm64 | Linux | arm64 | ✅ | N/A | glibc |
|
||||||
| bun-windows-x64 | Windows | x64 | ✅ | ✅ | - |
|
| bun-windows-x64 | Windows | x64 | ✅ | ✅ | - |
|
||||||
| ~~bun-windows-arm64~~ | Windows | arm64 | ❌ | ❌ | - |
|
| ~~bun-windows-arm64~~ | ~~Windows~~ | ~~arm64~~ | ❌ | ❌ | - |
|
||||||
| bun-darwin-x64 | macOS | x64 | ✅ | ✅ | - |
|
| bun-darwin-x64 | macOS | x64 | ✅ | ✅ | - |
|
||||||
| bun-darwin-arm64 | macOS | arm64 | ✅ | N/A | - |
|
| bun-darwin-arm64 | macOS | arm64 | ✅ | N/A | - |
|
||||||
| bun-linux-x64-musl | Linux | x64 | ✅ | ✅ | musl |
|
| bun-linux-x64-musl | Linux | x64 | ✅ | ✅ | musl |
|
||||||
@@ -524,12 +524,46 @@ codesign -vvv --verify ./myapp
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
|
## Code splitting
|
||||||
|
|
||||||
|
Standalone executables support code splitting. Use `--compile` with `--splitting` to create an executable that loads code-split chunks at runtime.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
bun build --compile --splitting ./src/entry.ts --outdir ./build
|
||||||
|
```
|
||||||
|
|
||||||
|
<CodeGroup>
|
||||||
|
|
||||||
|
```ts src/entry.ts icon="/icons/typescript.svg"
|
||||||
|
console.log("Entrypoint loaded");
|
||||||
|
const lazy = await import("./lazy.ts");
|
||||||
|
lazy.hello();
|
||||||
|
```
|
||||||
|
|
||||||
|
```ts src/lazy.ts icon="/icons/typescript.svg"
|
||||||
|
export function hello() {
|
||||||
|
console.log("Lazy module loaded");
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
</CodeGroup>
|
||||||
|
|
||||||
|
```bash terminal icon="terminal"
|
||||||
|
./build/entry
|
||||||
|
```
|
||||||
|
|
||||||
|
```txt
|
||||||
|
Entrypoint loaded
|
||||||
|
Lazy module loaded
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
## Unsupported CLI arguments
|
## Unsupported CLI arguments
|
||||||
|
|
||||||
Currently, the `--compile` flag can only accept a single entrypoint at a time and does not support the following flags:
|
Currently, the `--compile` flag can only accept a single entrypoint at a time and does not support the following flags:
|
||||||
|
|
||||||
- `--outdir` — use `outfile` instead.
|
- `--outdir` — use `outfile` instead (except when using with `--splitting`).
|
||||||
- `--splitting`
|
|
||||||
- `--public-path`
|
- `--public-path`
|
||||||
- `--target=node` or `--target=browser`
|
- `--target=node` or `--target=browser`
|
||||||
- `--no-bundle` - we always bundle everything into the executable.
|
- `--no-bundle` - we always bundle everything into the executable.
|
||||||
|
|||||||
@@ -1376,7 +1376,7 @@ interface BuildConfig {
|
|||||||
publicPath?: string;
|
publicPath?: string;
|
||||||
define?: Record<string, string>;
|
define?: Record<string, string>;
|
||||||
loader?: { [k in string]: Loader };
|
loader?: { [k in string]: Loader };
|
||||||
sourcemap?: "none" | "linked" | "inline" | "external" | "linked" | boolean; // default: "none", true -> "inline"
|
sourcemap?: "none" | "linked" | "inline" | "external" | boolean; // default: "none", true -> "inline"
|
||||||
/**
|
/**
|
||||||
* package.json `exports` conditions used when resolving imports
|
* package.json `exports` conditions used when resolving imports
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -188,7 +188,7 @@
|
|||||||
{
|
{
|
||||||
"group": "Publishing & Analysis",
|
"group": "Publishing & Analysis",
|
||||||
"icon": "upload",
|
"icon": "upload",
|
||||||
"pages": ["/pm/cli/publish", "/pm/cli/outdated", "/pm/cli/why", "/pm/cli/audit"]
|
"pages": ["/pm/cli/publish", "/pm/cli/outdated", "/pm/cli/why", "/pm/cli/audit", "/pm/cli/info"]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"group": "Workspace Management",
|
"group": "Workspace Management",
|
||||||
@@ -456,6 +456,7 @@
|
|||||||
"pages": [
|
"pages": [
|
||||||
"/guides/test/run-tests",
|
"/guides/test/run-tests",
|
||||||
"/guides/test/watch-mode",
|
"/guides/test/watch-mode",
|
||||||
|
"/guides/test/concurrent-test-glob",
|
||||||
"/guides/test/migrate-from-jest",
|
"/guides/test/migrate-from-jest",
|
||||||
"/guides/test/mock-functions",
|
"/guides/test/mock-functions",
|
||||||
"/guides/test/spy-on",
|
"/guides/test/spy-on",
|
||||||
|
|||||||
@@ -37,6 +37,7 @@ await extractLinks("https://bun.com");
|
|||||||
|
|
||||||
When scraping websites, you often want to convert relative URLs (like `/docs`) to absolute URLs. Here's how to handle URL resolution:
|
When scraping websites, you often want to convert relative URLs (like `/docs`) to absolute URLs. Here's how to handle URL resolution:
|
||||||
|
|
||||||
|
{/* prettier-ignore */}
|
||||||
```ts extract-links.ts icon="/icons/typescript.svg"
|
```ts extract-links.ts icon="/icons/typescript.svg"
|
||||||
async function extractLinksFromURL(url: string) {
|
async function extractLinksFromURL(url: string) {
|
||||||
const response = await fetch(url);
|
const response = await fetch(url);
|
||||||
@@ -47,13 +48,11 @@ async function extractLinksFromURL(url: string) {
|
|||||||
const href = el.getAttribute("href");
|
const href = el.getAttribute("href");
|
||||||
if (href) {
|
if (href) {
|
||||||
// Convert relative URLs to absolute // [!code ++]
|
// Convert relative URLs to absolute // [!code ++]
|
||||||
try {
|
try { // [!code ++]
|
||||||
// [!code ++]
|
|
||||||
const absoluteURL = new URL(href, url).href; // [!code ++]
|
const absoluteURL = new URL(href, url).href; // [!code ++]
|
||||||
links.add(absoluteURL); // [!code ++]
|
links.add(absoluteURL);
|
||||||
} catch {
|
} catch { // [!code ++]
|
||||||
// [!code ++]
|
links.add(href); // [!code ++]
|
||||||
links.add(href);
|
|
||||||
} // [!code ++]
|
} // [!code ++]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -65,6 +65,7 @@ First we use the [`.formData()`](https://developer.mozilla.org/en-US/docs/Web/AP
|
|||||||
|
|
||||||
Finally, we write the `Blob` to disk using [`Bun.write()`](https://bun.com/docs/api/file-io#writing-files-bun-write).
|
Finally, we write the `Blob` to disk using [`Bun.write()`](https://bun.com/docs/api/file-io#writing-files-bun-write).
|
||||||
|
|
||||||
|
{/* prettier-ignore */}
|
||||||
```ts index.ts icon="/icons/typescript.svg"
|
```ts index.ts icon="/icons/typescript.svg"
|
||||||
const server = Bun.serve({
|
const server = Bun.serve({
|
||||||
port: 4000,
|
port: 4000,
|
||||||
@@ -80,8 +81,7 @@ const server = Bun.serve({
|
|||||||
});
|
});
|
||||||
|
|
||||||
// parse formdata at /action // [!code ++]
|
// parse formdata at /action // [!code ++]
|
||||||
if (url.pathname === "/action") {
|
if (url.pathname === "/action") { // [!code ++]
|
||||||
// [!code ++]
|
|
||||||
const formdata = await req.formData(); // [!code ++]
|
const formdata = await req.formData(); // [!code ++]
|
||||||
const name = formdata.get("name"); // [!code ++]
|
const name = formdata.get("name"); // [!code ++]
|
||||||
const profilePicture = formdata.get("profilePicture"); // [!code ++]
|
const profilePicture = formdata.get("profilePicture"); // [!code ++]
|
||||||
|
|||||||
@@ -26,14 +26,14 @@ This will add the package to `peerDependencies` in `package.json`.
|
|||||||
|
|
||||||
Running `bun install` will install peer dependencies by default, unless marked optional in `peerDependenciesMeta`.
|
Running `bun install` will install peer dependencies by default, unless marked optional in `peerDependenciesMeta`.
|
||||||
|
|
||||||
|
{/* prettier-ignore */}
|
||||||
```json package.json icon="file-json"
|
```json package.json icon="file-json"
|
||||||
{
|
{
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"@types/bun": "^1.3.2"
|
"@types/bun": "^1.3.2"
|
||||||
},
|
},
|
||||||
"peerDependenciesMeta": {
|
"peerDependenciesMeta": {
|
||||||
"@types/bun": {
|
"@types/bun": { // [!code ++]
|
||||||
// [!code ++]
|
|
||||||
"optional": true // [!code ++]
|
"optional": true // [!code ++]
|
||||||
} // [!code ++]
|
} // [!code ++]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,12 +15,12 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
# ...
|
# ...
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v4
|
||||||
- uses: oven-sh/setup-bun@v2 // [!code ++]
|
- uses: oven-sh/setup-bun@v2 # [!code ++]
|
||||||
|
|
||||||
# run any `bun` or `bunx` command
|
# run any `bun` or `bunx` command
|
||||||
- run: bun install // [!code ++]
|
- run: bun install # [!code ++]
|
||||||
- run: bun index.ts // [!code ++]
|
- run: bun index.ts # [!code ++]
|
||||||
- run: bun run build // [!code ++]
|
- run: bun run build # [!code ++]
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
@@ -36,8 +36,8 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
# ...
|
# ...
|
||||||
- uses: oven-sh/setup-bun@v2
|
- uses: oven-sh/setup-bun@v2
|
||||||
with: // [!code ++]
|
with: # [!code ++]
|
||||||
bun-version: 1.2.0 # or "latest", "canary", <sha> // [!code ++]
|
bun-version: 1.2.0 # or "latest", "canary", <sha> # [!code ++]
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|||||||
@@ -27,9 +27,9 @@ if (process.env.NODE_ENV === "production") {
|
|||||||
|
|
||||||
Before the code reaches the JavaScript engine, Bun replaces `process.env.NODE_ENV` with `"production"`.
|
Before the code reaches the JavaScript engine, Bun replaces `process.env.NODE_ENV` with `"production"`.
|
||||||
|
|
||||||
|
{/* prettier-ignore */}
|
||||||
```ts
|
```ts
|
||||||
if ("production" === "production") {
|
if ("production" === "production") { // [!code ++]
|
||||||
// [!code ++]
|
|
||||||
console.log("Production mode");
|
console.log("Production mode");
|
||||||
} else {
|
} else {
|
||||||
console.log("Development mode");
|
console.log("Development mode");
|
||||||
@@ -42,9 +42,9 @@ It doesn't stop there. Bun's optimizing transpiler is smart enough to do some ba
|
|||||||
|
|
||||||
Since `"production" === "production"` is always `true`, Bun replaces the entire expression with the `true` value.
|
Since `"production" === "production"` is always `true`, Bun replaces the entire expression with the `true` value.
|
||||||
|
|
||||||
|
{/* prettier-ignore */}
|
||||||
```ts
|
```ts
|
||||||
if (true) {
|
if (true) { // [!code ++]
|
||||||
// [!code ++]
|
|
||||||
console.log("Production mode");
|
console.log("Production mode");
|
||||||
} else {
|
} else {
|
||||||
console.log("Development mode");
|
console.log("Development mode");
|
||||||
|
|||||||
143
docs/guides/test/concurrent-test-glob.mdx
Normal file
143
docs/guides/test/concurrent-test-glob.mdx
Normal file
@@ -0,0 +1,143 @@
|
|||||||
|
---
|
||||||
|
title: Selectively run tests concurrently with glob patterns
|
||||||
|
sidebarTitle: Concurrent test glob
|
||||||
|
mode: center
|
||||||
|
---
|
||||||
|
|
||||||
|
This guide demonstrates how to use the `concurrentTestGlob` option to selectively run tests concurrently based on file naming patterns.
|
||||||
|
|
||||||
|
## Project Structure
|
||||||
|
|
||||||
|
```sh title="Project Structure" icon="folder-tree"
|
||||||
|
my-project/
|
||||||
|
├── bunfig.toml
|
||||||
|
├── tests/
|
||||||
|
│ ├── unit/
|
||||||
|
│ │ ├── math.test.ts # Sequential
|
||||||
|
│ │ └── utils.test.ts # Sequential
|
||||||
|
│ └── integration/
|
||||||
|
│ ├── concurrent-api.test.ts # Concurrent
|
||||||
|
│ └── concurrent-database.test.ts # Concurrent
|
||||||
|
```
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
Configure your `bunfig.toml` to run test files with "concurrent-" prefix concurrently:
|
||||||
|
|
||||||
|
```toml title="bunfig.toml" icon="settings"
|
||||||
|
[test]
|
||||||
|
# Run all test files with "concurrent-" prefix concurrently
|
||||||
|
concurrentTestGlob = "**/concurrent-*.test.ts"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Test Files
|
||||||
|
|
||||||
|
### Unit Test (Sequential)
|
||||||
|
|
||||||
|
Sequential tests are good for tests that share state or have specific ordering requirements:
|
||||||
|
|
||||||
|
```ts title="tests/unit/math.test.ts" icon="/icons/typescript.svg"
|
||||||
|
import { test, expect } from "bun:test";
|
||||||
|
|
||||||
|
// These tests run sequentially by default
|
||||||
|
let sharedState = 0;
|
||||||
|
|
||||||
|
test("addition", () => {
|
||||||
|
sharedState = 5 + 3;
|
||||||
|
expect(sharedState).toBe(8);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("uses previous state", () => {
|
||||||
|
// This test depends on the previous test's state
|
||||||
|
expect(sharedState).toBe(8);
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
### Integration Test (Concurrent)
|
||||||
|
|
||||||
|
Tests in files matching the glob pattern automatically run concurrently:
|
||||||
|
|
||||||
|
```ts title="tests/integration/concurrent-api.test.ts" icon="/icons/typescript.svg"
|
||||||
|
import { test, expect } from "bun:test";
|
||||||
|
|
||||||
|
// These tests automatically run concurrently due to filename matching the glob pattern.
|
||||||
|
// Using test() is equivalent to test.concurrent() when the file matches concurrentTestGlob.
|
||||||
|
// Each test is independent and can run in parallel.
|
||||||
|
|
||||||
|
test("fetch user data", async () => {
|
||||||
|
const response = await fetch("/api/user/1");
|
||||||
|
expect(response.ok).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("fetch posts", async () => {
|
||||||
|
const response = await fetch("/api/posts");
|
||||||
|
expect(response.ok).toBe(true);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("fetch comments", async () => {
|
||||||
|
const response = await fetch("/api/comments");
|
||||||
|
expect(response.ok).toBe(true);
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
## Running Tests
|
||||||
|
|
||||||
|
```bash terminal icon="terminal"
|
||||||
|
# Run all tests - concurrent-*.test.ts files will run concurrently
|
||||||
|
bun test
|
||||||
|
|
||||||
|
# Override: Force ALL tests to run concurrently
|
||||||
|
# Note: This overrides bunfig.toml and runs all tests concurrently, regardless of glob
|
||||||
|
bun test --concurrent
|
||||||
|
|
||||||
|
# Run only unit tests (sequential)
|
||||||
|
bun test tests/unit
|
||||||
|
|
||||||
|
# Run only integration tests (concurrent due to glob pattern)
|
||||||
|
bun test tests/integration
|
||||||
|
```
|
||||||
|
|
||||||
|
## Benefits
|
||||||
|
|
||||||
|
1. **Gradual Migration**: Migrate to concurrent tests file by file by renaming them
|
||||||
|
2. **Clear Organization**: File naming convention indicates execution mode
|
||||||
|
3. **Performance**: Integration tests run faster in parallel
|
||||||
|
4. **Safety**: Unit tests remain sequential where needed
|
||||||
|
5. **Flexibility**: Easy to change execution mode by renaming files
|
||||||
|
|
||||||
|
## Migration Strategy
|
||||||
|
|
||||||
|
To migrate existing tests to concurrent execution:
|
||||||
|
|
||||||
|
1. **Start with independent integration tests** - These typically don't share state
|
||||||
|
2. **Rename files to match the glob pattern**: `mv api.test.ts concurrent-api.test.ts`
|
||||||
|
3. **Verify tests still pass** - Run `bun test` to ensure no race conditions
|
||||||
|
4. **Monitor for shared state issues** - Watch for flaky tests or unexpected failures
|
||||||
|
5. **Continue migrating stable tests incrementally** - Don't rush the migration
|
||||||
|
|
||||||
|
## Tips
|
||||||
|
|
||||||
|
- **Use descriptive prefixes**: `concurrent-`, `parallel-`, `async-`
|
||||||
|
- **Keep related sequential tests together** in the same directory
|
||||||
|
- **Document why certain tests must remain sequential** with comments
|
||||||
|
- **Use `test.concurrent()` for fine-grained control** in sequential files
|
||||||
|
(Note: In files matched by `concurrentTestGlob`, plain `test()` already runs concurrently)
|
||||||
|
|
||||||
|
## Multiple Patterns
|
||||||
|
|
||||||
|
You can specify multiple patterns for different test categories:
|
||||||
|
|
||||||
|
```toml title="bunfig.toml" icon="settings"
|
||||||
|
[test]
|
||||||
|
concurrentTestGlob = [
|
||||||
|
"**/integration/*.test.ts",
|
||||||
|
"**/e2e/*.test.ts",
|
||||||
|
"**/concurrent-*.test.ts"
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
This configuration will run tests concurrently if they match any of these patterns:
|
||||||
|
|
||||||
|
- All tests in `integration/` directories
|
||||||
|
- All tests in `e2e/` directories
|
||||||
|
- All tests with `concurrent-` prefix anywhere in the project
|
||||||
@@ -23,6 +23,7 @@ const spy = spyOn(leo, "sayHi");
|
|||||||
|
|
||||||
Once the spy is created, it can be used to write `expect` assertions relating to method calls.
|
Once the spy is created, it can be used to write `expect` assertions relating to method calls.
|
||||||
|
|
||||||
|
{/* prettier-ignore */}
|
||||||
```ts
|
```ts
|
||||||
import { test, expect, spyOn } from "bun:test";
|
import { test, expect, spyOn } from "bun:test";
|
||||||
|
|
||||||
@@ -35,8 +36,7 @@ const leo = {
|
|||||||
|
|
||||||
const spy = spyOn(leo, "sayHi");
|
const spy = spyOn(leo, "sayHi");
|
||||||
|
|
||||||
test("turtles", () => {
|
test("turtles", () => { // [!code ++]
|
||||||
// [!code ++]
|
|
||||||
expect(spy).toHaveBeenCalledTimes(0); // [!code ++]
|
expect(spy).toHaveBeenCalledTimes(0); // [!code ++]
|
||||||
leo.sayHi("pizza"); // [!code ++]
|
leo.sayHi("pizza"); // [!code ++]
|
||||||
expect(spy).toHaveBeenCalledTimes(1); // [!code ++]
|
expect(spy).toHaveBeenCalledTimes(1); // [!code ++]
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ When building a WebSocket server, it's typically necessary to store some identif
|
|||||||
With [Bun.serve()](https://bun.com/docs/api/websockets contextual-data), this "contextual data" is set when the connection is initially upgraded by passing a `data` parameter in the `server.upgrade()` call.
|
With [Bun.serve()](https://bun.com/docs/api/websockets contextual-data), this "contextual data" is set when the connection is initially upgraded by passing a `data` parameter in the `server.upgrade()` call.
|
||||||
|
|
||||||
```ts server.ts icon="/icons/typescript.svg"
|
```ts server.ts icon="/icons/typescript.svg"
|
||||||
Bun.serve<{ socketId: number }>({
|
Bun.serve({
|
||||||
fetch(req, server) {
|
fetch(req, server) {
|
||||||
const success = server.upgrade(req, {
|
const success = server.upgrade(req, {
|
||||||
data: {
|
data: {
|
||||||
@@ -22,6 +22,9 @@ Bun.serve<{ socketId: number }>({
|
|||||||
// ...
|
// ...
|
||||||
},
|
},
|
||||||
websocket: {
|
websocket: {
|
||||||
|
// TypeScript: specify the type of ws.data like this
|
||||||
|
data: {} as { socketId: number },
|
||||||
|
|
||||||
// define websocket handlers
|
// define websocket handlers
|
||||||
async message(ws, message) {
|
async message(ws, message) {
|
||||||
// the contextual data is available as the `data` property
|
// the contextual data is available as the `data` property
|
||||||
@@ -43,8 +46,7 @@ type WebSocketData = {
|
|||||||
userId: string;
|
userId: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
// TypeScript: specify the type of `data`
|
Bun.serve({
|
||||||
Bun.serve<WebSocketData>({
|
|
||||||
async fetch(req, server) {
|
async fetch(req, server) {
|
||||||
// use a library to parse cookies
|
// use a library to parse cookies
|
||||||
const cookies = parseCookies(req.headers.get("Cookie"));
|
const cookies = parseCookies(req.headers.get("Cookie"));
|
||||||
@@ -62,6 +64,9 @@ Bun.serve<WebSocketData>({
|
|||||||
if (upgraded) return undefined;
|
if (upgraded) return undefined;
|
||||||
},
|
},
|
||||||
websocket: {
|
websocket: {
|
||||||
|
// TypeScript: specify the type of ws.data like this
|
||||||
|
data: {} as WebSocketData,
|
||||||
|
|
||||||
async message(ws, message) {
|
async message(ws, message) {
|
||||||
// save the message to a database
|
// save the message to a database
|
||||||
await saveMessageToDatabase({
|
await saveMessageToDatabase({
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ Bun's server-side `WebSocket` API provides a native pub-sub API. Sockets can be
|
|||||||
This code snippet implements a simple single-channel chat server.
|
This code snippet implements a simple single-channel chat server.
|
||||||
|
|
||||||
```ts server.ts icon="/icons/typescript.svg"
|
```ts server.ts icon="/icons/typescript.svg"
|
||||||
const server = Bun.serve<{ username: string }>({
|
const server = Bun.serve({
|
||||||
fetch(req, server) {
|
fetch(req, server) {
|
||||||
const cookies = req.headers.get("cookie");
|
const cookies = req.headers.get("cookie");
|
||||||
const username = getUsernameFromCookies(cookies);
|
const username = getUsernameFromCookies(cookies);
|
||||||
@@ -19,6 +19,9 @@ const server = Bun.serve<{ username: string }>({
|
|||||||
return new Response("Hello world");
|
return new Response("Hello world");
|
||||||
},
|
},
|
||||||
websocket: {
|
websocket: {
|
||||||
|
// TypeScript: specify the type of ws.data like this
|
||||||
|
data: {} as { username: string },
|
||||||
|
|
||||||
open(ws) {
|
open(ws) {
|
||||||
const msg = `${ws.data.username} has entered the chat`;
|
const msg = `${ws.data.username} has entered the chat`;
|
||||||
ws.subscribe("the-group-chat");
|
ws.subscribe("the-group-chat");
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ Start a simple WebSocket server using [`Bun.serve`](https://bun.com/docs/api/htt
|
|||||||
Inside `fetch`, we attempt to upgrade incoming `ws:` or `wss:` requests to WebSocket connections.
|
Inside `fetch`, we attempt to upgrade incoming `ws:` or `wss:` requests to WebSocket connections.
|
||||||
|
|
||||||
```ts server.ts icon="/icons/typescript.svg"
|
```ts server.ts icon="/icons/typescript.svg"
|
||||||
const server = Bun.serve<{ authToken: string }>({
|
const server = Bun.serve({
|
||||||
fetch(req, server) {
|
fetch(req, server) {
|
||||||
const success = server.upgrade(req);
|
const success = server.upgrade(req);
|
||||||
if (success) {
|
if (success) {
|
||||||
@@ -22,6 +22,9 @@ const server = Bun.serve<{ authToken: string }>({
|
|||||||
return new Response("Hello world!");
|
return new Response("Hello world!");
|
||||||
},
|
},
|
||||||
websocket: {
|
websocket: {
|
||||||
|
// TypeScript: specify the type of ws.data like this
|
||||||
|
data: {} as { authToken: string },
|
||||||
|
|
||||||
// this is called when a message is received
|
// this is called when a message is received
|
||||||
async message(ws, message) {
|
async message(ws, message) {
|
||||||
console.log(`Received ${message}`);
|
console.log(`Received ${message}`);
|
||||||
|
|||||||
70
docs/pm/cli/info.mdx
Normal file
70
docs/pm/cli/info.mdx
Normal file
@@ -0,0 +1,70 @@
|
|||||||
|
---
|
||||||
|
title: "bun info"
|
||||||
|
description: "Display package metadata from the npm registry"
|
||||||
|
---
|
||||||
|
|
||||||
|
`bun info` displays package metadata from the npm registry.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
```bash terminal icon="terminal"
|
||||||
|
bun info react
|
||||||
|
```
|
||||||
|
|
||||||
|
This will display information about the `react` package, including its latest version, description, homepage, dependencies, and more.
|
||||||
|
|
||||||
|
## Viewing specific versions
|
||||||
|
|
||||||
|
To view information about a specific version:
|
||||||
|
|
||||||
|
```bash terminal icon="terminal"
|
||||||
|
bun info react@18.0.0
|
||||||
|
```
|
||||||
|
|
||||||
|
## Viewing specific properties
|
||||||
|
|
||||||
|
You can also query specific properties from the package metadata:
|
||||||
|
|
||||||
|
```bash terminal icon="terminal"
|
||||||
|
bun info react version
|
||||||
|
bun info react dependencies
|
||||||
|
bun info react repository.url
|
||||||
|
```
|
||||||
|
|
||||||
|
## JSON output
|
||||||
|
|
||||||
|
To get the output in JSON format, use the `--json` flag:
|
||||||
|
|
||||||
|
```bash terminal icon="terminal"
|
||||||
|
bun info react --json
|
||||||
|
```
|
||||||
|
|
||||||
|
## Alias
|
||||||
|
|
||||||
|
`bun pm view` is an alias for `bun info`:
|
||||||
|
|
||||||
|
```bash terminal icon="terminal"
|
||||||
|
bun pm view react # equivalent to: bun info react
|
||||||
|
```
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
```bash terminal icon="terminal"
|
||||||
|
# View basic package information
|
||||||
|
bun info is-number
|
||||||
|
|
||||||
|
# View a specific version
|
||||||
|
bun info is-number@7.0.0
|
||||||
|
|
||||||
|
# View all available versions
|
||||||
|
bun info is-number versions
|
||||||
|
|
||||||
|
# View package dependencies
|
||||||
|
bun info express dependencies
|
||||||
|
|
||||||
|
# View package homepage
|
||||||
|
bun info lodash homepage
|
||||||
|
|
||||||
|
# Get JSON output
|
||||||
|
bun info react --json
|
||||||
|
```
|
||||||
@@ -134,14 +134,14 @@ For more information on filtering with `bun install`, refer to [Package Manager
|
|||||||
|
|
||||||
Bun supports npm's `"overrides"` and Yarn's `"resolutions"` in `package.json`. These are mechanisms for specifying a version range for _metadependencies_—the dependencies of your dependencies. Refer to [Package manager > Overrides and resolutions](/pm/overrides) for complete documentation.
|
Bun supports npm's `"overrides"` and Yarn's `"resolutions"` in `package.json`. These are mechanisms for specifying a version range for _metadependencies_—the dependencies of your dependencies. Refer to [Package manager > Overrides and resolutions](/pm/overrides) for complete documentation.
|
||||||
|
|
||||||
|
{/* prettier-ignore */}
|
||||||
```json package.json file="file-json"
|
```json package.json file="file-json"
|
||||||
{
|
{
|
||||||
"name": "my-app",
|
"name": "my-app",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"foo": "^2.0.0"
|
"foo": "^2.0.0"
|
||||||
},
|
},
|
||||||
"overrides": {
|
"overrides": { // [!code ++]
|
||||||
// [!code ++]
|
|
||||||
"bar": "~4.4.0" // [!code ++]
|
"bar": "~4.4.0" // [!code ++]
|
||||||
} // [!code ++]
|
} // [!code ++]
|
||||||
}
|
}
|
||||||
@@ -304,7 +304,16 @@ For more advanced security scanning, including integration with services & custo
|
|||||||
|
|
||||||
## Configuration
|
## Configuration
|
||||||
|
|
||||||
The default behavior of `bun install` can be configured in `bunfig.toml`. The default values are shown below.
|
### Configuring `bun install` with `bunfig.toml`
|
||||||
|
|
||||||
|
`bunfig.toml` is searched for in the following paths on `bun install`, `bun remove`, and `bun add`:
|
||||||
|
|
||||||
|
1. `$XDG_CONFIG_HOME/.bunfig.toml` or `$HOME/.bunfig.toml`
|
||||||
|
2. `./bunfig.toml`
|
||||||
|
|
||||||
|
If both are found, the results are merged together.
|
||||||
|
|
||||||
|
Configuring with `bunfig.toml` is optional. Bun tries to be zero configuration in general, but that's not always possible. The default behavior of `bun install` can be configured in `bunfig.toml`. The default values are shown below.
|
||||||
|
|
||||||
```toml bunfig.toml icon="settings"
|
```toml bunfig.toml icon="settings"
|
||||||
[install]
|
[install]
|
||||||
@@ -345,7 +354,29 @@ minimumReleaseAge = 259200 # seconds
|
|||||||
minimumReleaseAgeExcludes = ["@types/node", "typescript"]
|
minimumReleaseAgeExcludes = ["@types/node", "typescript"]
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
### Configuring with environment variables
|
||||||
|
|
||||||
|
Environment variables have a higher priority than `bunfig.toml`.
|
||||||
|
|
||||||
|
| Name | Description |
|
||||||
|
| ---------------------------------- | ------------------------------------------------------------- |
|
||||||
|
| `BUN_CONFIG_REGISTRY` | Set an npm registry (default: https://registry.npmjs.org) |
|
||||||
|
| `BUN_CONFIG_TOKEN` | Set an auth token (currently does nothing) |
|
||||||
|
| `BUN_CONFIG_YARN_LOCKFILE` | Save a Yarn v1-style yarn.lock |
|
||||||
|
| `BUN_CONFIG_LINK_NATIVE_BINS` | Point `bin` in package.json to a platform-specific dependency |
|
||||||
|
| `BUN_CONFIG_SKIP_SAVE_LOCKFILE` | Don’t save a lockfile |
|
||||||
|
| `BUN_CONFIG_SKIP_LOAD_LOCKFILE` | Don’t load a lockfile |
|
||||||
|
| `BUN_CONFIG_SKIP_INSTALL_PACKAGES` | Don’t install any packages |
|
||||||
|
|
||||||
|
Bun always tries to use the fastest available installation method for the target platform. On macOS, that’s `clonefile` and on Linux, that’s `hardlink`. You can change which installation method is used with the `--backend` flag. When unavailable or on error, `clonefile` and `hardlink` fallsback to a platform-specific implementation of copying files.
|
||||||
|
|
||||||
|
Bun stores installed packages from npm in `~/.bun/install/cache/${name}@${version}`. Note that if the semver version has a `build` or a `pre` tag, it is replaced with a hash of that value instead. This is to reduce the chances of errors from long file paths, but unfortunately complicates figuring out where a package was installed on disk.
|
||||||
|
|
||||||
|
When the `node_modules` folder exists, before installing, Bun checks if the `"name"` and `"version"` in `package/package.json` in the expected node_modules folder matches the expected `name` and `version`. This is how it determines whether it should install. It uses a custom JSON parser which stops parsing as soon as it finds `"name"` and `"version"`.
|
||||||
|
|
||||||
|
When a `bun.lock` doesn’t exist or `package.json` has changed dependencies, tarballs are downloaded & extracted eagerly while resolving.
|
||||||
|
|
||||||
|
When a `bun.lock` exists and `package.json` hasn’t changed, Bun downloads missing dependencies lazily. If the package with a matching `name` & `version` already exists in the expected location within `node_modules`, Bun won’t attempt to download the tarball.
|
||||||
|
|
||||||
## CI/CD
|
## CI/CD
|
||||||
|
|
||||||
@@ -395,6 +426,94 @@ jobs:
|
|||||||
run: bun run build
|
run: bun run build
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Platform-specific dependencies?
|
||||||
|
|
||||||
|
bun stores normalized `cpu` and `os` values from npm in the lockfile, along with the resolved packages. It skips downloading, extracting, and installing packages disabled for the current target at runtime. This means the lockfile won't change between platforms/architectures even if the packages ultimately installed do change.
|
||||||
|
|
||||||
|
### `--cpu` and `--os` flags
|
||||||
|
|
||||||
|
You can override the target platform for package selection:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
bun install --cpu=x64 --os=linux
|
||||||
|
```
|
||||||
|
|
||||||
|
This installs packages for the specified platform instead of the current system. Useful for cross-platform builds or when preparing deployments for different environments.
|
||||||
|
|
||||||
|
**Accepted values for `--cpu`**: `arm64`, `x64`, `ia32`, `ppc64`, `s390x`
|
||||||
|
|
||||||
|
**Accepted values for `--os`**: `linux`, `darwin`, `win32`, `freebsd`, `openbsd`, `sunos`, `aix`
|
||||||
|
|
||||||
|
## Peer dependencies?
|
||||||
|
|
||||||
|
Peer dependencies are handled similarly to yarn. `bun install` will automatically install peer dependencies. If the dependency is marked optional in `peerDependenciesMeta`, an existing dependency will be chosen if possible.
|
||||||
|
|
||||||
|
## Lockfile
|
||||||
|
|
||||||
|
`bun.lock` is Bun’s lockfile format. See [our blogpost about the text lockfile](https://bun.com/blog/bun-lock-text-lockfile).
|
||||||
|
|
||||||
|
Prior to Bun 1.2, the lockfile was binary and called `bun.lockb`. Old lockfiles can be upgraded to the new format by running `bun install --save-text-lockfile --frozen-lockfile --lockfile-only`, and then deleting `bun.lockb`.
|
||||||
|
|
||||||
|
## Cache
|
||||||
|
|
||||||
|
To delete the cache:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
bun pm cache rm
|
||||||
|
# or
|
||||||
|
rm -rf ~/.bun/install/cache
|
||||||
|
```
|
||||||
|
|
||||||
|
## Platform-specific backends
|
||||||
|
|
||||||
|
`bun install` uses different system calls to install dependencies depending on the platform. This is a performance optimization. You can force a specific backend with the `--backend` flag.
|
||||||
|
|
||||||
|
**`hardlink`** is the default backend on Linux. Benchmarking showed it to be the fastest on Linux.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
rm -rf node_modules
|
||||||
|
bun install --backend hardlink
|
||||||
|
```
|
||||||
|
|
||||||
|
**`clonefile`** is the default backend on macOS. Benchmarking showed it to be the fastest on macOS. It is only available on macOS.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
rm -rf node_modules
|
||||||
|
bun install --backend clonefile
|
||||||
|
```
|
||||||
|
|
||||||
|
**`clonefile_each_dir`** is similar to `clonefile`, except it clones each file individually per directory. It is only available on macOS and tends to perform slower than `clonefile`. Unlike `clonefile`, this does not recursively clone subdirectories in one system call.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
rm -rf node_modules
|
||||||
|
bun install --backend clonefile_each_dir
|
||||||
|
```
|
||||||
|
|
||||||
|
**`copyfile`** is the fallback used when any of the above fail, and is the slowest. on macOS, it uses `fcopyfile()` and on linux it uses `copy_file_range()`.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
rm -rf node_modules
|
||||||
|
bun install --backend copyfile
|
||||||
|
```
|
||||||
|
|
||||||
|
**`symlink`** is typically only used for `file:` dependencies (and eventually `link:`) internally. To prevent infinite loops, it skips symlinking the `node_modules` folder.
|
||||||
|
|
||||||
|
If you install with `--backend=symlink`, Node.js won't resolve node_modules of dependencies unless each dependency has its own node_modules folder or you pass `--preserve-symlinks` to `node` or `bun`. See [Node.js documentation on `--preserve-symlinks`](https://nodejs.org/api/cli.html#--preserve-symlinks).
|
||||||
|
|
||||||
|
```bash
|
||||||
|
rm -rf node_modules
|
||||||
|
bun install --backend symlink
|
||||||
|
bun --preserve-symlinks ./my-file.js
|
||||||
|
node --preserve-symlinks ./my-file.js # https://nodejs.org/api/cli.html#--preserve-symlinks
|
||||||
|
```
|
||||||
|
|
||||||
|
## npm registry metadata
|
||||||
|
|
||||||
|
Bun uses a binary format for caching NPM registry responses. This loads much faster than JSON and tends to be smaller on disk.
|
||||||
|
You will see these files in `~/.bun/install/cache/*.npm`. The filename pattern is `${hash(packageName)}.npm`. It’s a hash so that extra directories don’t need to be created for scoped packages.
|
||||||
|
|
||||||
|
Bun's usage of `Cache-Control` ignores `Age`. This improves performance, but means bun may be about 5 minutes out of date to receive the latest package version metadata from npm.
|
||||||
|
|
||||||
## pnpm migration
|
## pnpm migration
|
||||||
|
|
||||||
Bun automatically migrates projects from pnpm to bun. When a `pnpm-lock.yaml` file is detected and no `bun.lock` file exists, Bun will automatically migrate the lockfile to `bun.lock` during installation. The original `pnpm-lock.yaml` file remains unmodified.
|
Bun automatically migrates projects from pnpm to bun. When a `pnpm-lock.yaml` file is detected and no `bun.lock` file exists, Bun will automatically migrate the lockfile to `bun.lock` during installation. The original `pnpm-lock.yaml` file remains unmodified.
|
||||||
|
|||||||
@@ -43,6 +43,19 @@ In addition, the `--save` flag can be used to add `cool-pkg` to the `dependencie
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Unlinking
|
||||||
|
|
||||||
|
Use `bun unlink` in the root directory to unregister a local package.
|
||||||
|
|
||||||
|
```bash terminal icon="terminal"
|
||||||
|
cd /path/to/cool-pkg
|
||||||
|
bun unlink
|
||||||
|
```
|
||||||
|
|
||||||
|
```txt
|
||||||
|
bun unlink v1.x (7416672e)
|
||||||
|
```
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
<Link />
|
<Link />
|
||||||
|
|||||||
@@ -89,6 +89,14 @@ The `--dry-run` flag can be used to simulate the publish process without actuall
|
|||||||
bun publish --dry-run
|
bun publish --dry-run
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### `--tolerate-republish`
|
||||||
|
|
||||||
|
Exit with code 0 instead of 1 if the package version already exists. Useful in CI/CD where jobs may be re-run.
|
||||||
|
|
||||||
|
```sh terminal icon="terminal"
|
||||||
|
bun publish --tolerate-republish
|
||||||
|
```
|
||||||
|
|
||||||
### `--gzip-level`
|
### `--gzip-level`
|
||||||
|
|
||||||
Specify the level of gzip compression to use when packing the package. Only applies to `bun publish` without a tarball path argument. Values range from `0` to `9` (default is `9`).
|
Specify the level of gzip compression to use when packing the package. Only applies to `bun publish` without a tarball path argument. Values range from `0` to `9` (default is `9`).
|
||||||
|
|||||||
@@ -5,14 +5,14 @@ description: "Control metadependency versions with npm overrides and Yarn resolu
|
|||||||
|
|
||||||
Bun supports npm's `"overrides"` and Yarn's `"resolutions"` in `package.json`. These are mechanisms for specifying a version range for _metadependencies_—the dependencies of your dependencies.
|
Bun supports npm's `"overrides"` and Yarn's `"resolutions"` in `package.json`. These are mechanisms for specifying a version range for _metadependencies_—the dependencies of your dependencies.
|
||||||
|
|
||||||
|
{/* prettier-ignore */}
|
||||||
```json package.json icon="file-json"
|
```json package.json icon="file-json"
|
||||||
{
|
{
|
||||||
"name": "my-app",
|
"name": "my-app",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"foo": "^2.0.0"
|
"foo": "^2.0.0"
|
||||||
},
|
},
|
||||||
"overrides": {
|
"overrides": { // [!code ++]
|
||||||
// [!code ++]
|
|
||||||
"bar": "~4.4.0" // [!code ++]
|
"bar": "~4.4.0" // [!code ++]
|
||||||
} // [!code ++]
|
} // [!code ++]
|
||||||
}
|
}
|
||||||
@@ -50,14 +50,14 @@ Add `bar` to the `"overrides"` field in `package.json`. Bun will defer to the sp
|
|||||||
overrides](https://docs.npmjs.com/cli/v9/configuring-npm/package-json#overrides) are not supported.
|
overrides](https://docs.npmjs.com/cli/v9/configuring-npm/package-json#overrides) are not supported.
|
||||||
</Note>
|
</Note>
|
||||||
|
|
||||||
|
{/* prettier-ignore */}
|
||||||
```json package.json icon="file-json"
|
```json package.json icon="file-json"
|
||||||
{
|
{
|
||||||
"name": "my-app",
|
"name": "my-app",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"foo": "^2.0.0"
|
"foo": "^2.0.0"
|
||||||
},
|
},
|
||||||
"overrides": {
|
"overrides": { // [!code ++]
|
||||||
// [!code ++]
|
|
||||||
"bar": "~4.4.0" // [!code ++]
|
"bar": "~4.4.0" // [!code ++]
|
||||||
} // [!code ++]
|
} // [!code ++]
|
||||||
}
|
}
|
||||||
@@ -69,14 +69,14 @@ The syntax is similar for `"resolutions"`, which is Yarn's alternative to `"over
|
|||||||
|
|
||||||
As with `"overrides"`, _nested resolutions_ are not currently supported.
|
As with `"overrides"`, _nested resolutions_ are not currently supported.
|
||||||
|
|
||||||
|
{/* prettier-ignore */}
|
||||||
```json package.json icon="file-json"
|
```json package.json icon="file-json"
|
||||||
{
|
{
|
||||||
"name": "my-app",
|
"name": "my-app",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"foo": "^2.0.0"
|
"foo": "^2.0.0"
|
||||||
},
|
},
|
||||||
"resolutions": {
|
"resolutions": { // [!code ++]
|
||||||
// [!code ++]
|
|
||||||
"bar": "~4.4.0" // [!code ++]
|
"bar": "~4.4.0" // [!code ++]
|
||||||
} // [!code ++]
|
} // [!code ++]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ It's common for a monorepo to have the following structure:
|
|||||||
|
|
||||||
In the root `package.json`, the `"workspaces"` key is used to indicate which subdirectories should be considered packages/workspaces within the monorepo. It's conventional to place all the workspace in a directory called `packages`.
|
In the root `package.json`, the `"workspaces"` key is used to indicate which subdirectories should be considered packages/workspaces within the monorepo. It's conventional to place all the workspace in a directory called `packages`.
|
||||||
|
|
||||||
```json
|
```json package.json icon="file-json"
|
||||||
{
|
{
|
||||||
"name": "my-project",
|
"name": "my-project",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
@@ -42,14 +42,22 @@ In the root `package.json`, the `"workspaces"` key is used to indicate which sub
|
|||||||
```
|
```
|
||||||
|
|
||||||
<Note>
|
<Note>
|
||||||
**Glob support** — Bun supports full glob syntax in `"workspaces"` (see [here](/runtime/glob#supported-glob-patterns)
|
**Glob support** — Bun supports full glob syntax in `"workspaces"`, including negative patterns (e.g.
|
||||||
for a comprehensive list of supported syntax), _except_ for exclusions (e.g. `!**/excluded/**`), which are not
|
`!**/excluded/**`). See [here](https://bun.com/docs/api/glob#supported-glob-patterns) for a comprehensive list of
|
||||||
implemented yet.
|
supported syntax.
|
||||||
</Note>
|
</Note>
|
||||||
|
|
||||||
|
```json package.json icon="file-json"
|
||||||
|
{
|
||||||
|
"name": "my-project",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"workspaces": ["packages/**", "!packages/**/test/**", "!packages/**/template/**"]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
Each workspace has it's own `package.json`. When referencing other packages in the monorepo, semver or workspace protocols (e.g. `workspace:*`) can be used as the version field in your `package.json`.
|
Each workspace has it's own `package.json`. When referencing other packages in the monorepo, semver or workspace protocols (e.g. `workspace:*`) can be used as the version field in your `package.json`.
|
||||||
|
|
||||||
```json
|
```json packages/pkg-a/package.json icon="file-json"
|
||||||
{
|
{
|
||||||
"name": "pkg-a",
|
"name": "pkg-a",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
|
|||||||
@@ -7,26 +7,40 @@ Configuring a development environment for Bun can take 10-30 minutes depending o
|
|||||||
|
|
||||||
If you are using Windows, please refer to [this guide](/project/building-windows)
|
If you are using Windows, please refer to [this guide](/project/building-windows)
|
||||||
|
|
||||||
## Install Dependencies
|
## Using Nix (Alternative)
|
||||||
|
|
||||||
|
A Nix flake is provided as an alternative to manual dependency installation:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nix develop
|
||||||
|
# or explicitly use the pure shell
|
||||||
|
# nix develop .#pure
|
||||||
|
export CMAKE_SYSTEM_PROCESSOR=$(uname -m)
|
||||||
|
bun bd
|
||||||
|
```
|
||||||
|
|
||||||
|
This provides all dependencies in an isolated, reproducible environment without requiring sudo.
|
||||||
|
|
||||||
|
## Install Dependencies (Manual)
|
||||||
|
|
||||||
Using your system's package manager, install Bun's dependencies:
|
Using your system's package manager, install Bun's dependencies:
|
||||||
|
|
||||||
<CodeGroup>
|
<CodeGroup>
|
||||||
|
|
||||||
```bash macOS (Homebrew)
|
```bash macOS (Homebrew)
|
||||||
$ brew install automake ccache cmake coreutils gnu-sed go icu4c libiconv libtool ninja pkg-config rust ruby
|
$ brew install automake cmake coreutils gnu-sed go icu4c libiconv libtool ninja pkg-config rust ruby sccache
|
||||||
```
|
```
|
||||||
|
|
||||||
```bash Ubuntu/Debian
|
```bash Ubuntu/Debian
|
||||||
$ sudo apt install curl wget lsb-release software-properties-common cargo ccache cmake git golang libtool ninja-build pkg-config rustc ruby-full xz-utils
|
$ sudo apt install curl wget lsb-release software-properties-common cargo cmake git golang libtool ninja-build pkg-config rustc ruby-full xz-utils
|
||||||
```
|
```
|
||||||
|
|
||||||
```bash Arch
|
```bash Arch
|
||||||
$ sudo pacman -S base-devel ccache cmake git go libiconv libtool make ninja pkg-config python rust sed unzip ruby
|
$ sudo pacman -S base-devel cmake git go libiconv libtool make ninja pkg-config python rust sed unzip ruby
|
||||||
```
|
```
|
||||||
|
|
||||||
```bash Fedora
|
```bash Fedora
|
||||||
$ sudo dnf install cargo ccache cmake git golang libtool ninja-build pkg-config rustc ruby libatomic-static libstdc++-static sed unzip which libicu-devel 'perl(Math::BigInt)'
|
$ sudo dnf install cargo clang19 llvm19 lld19 cmake git golang libtool ninja-build pkg-config rustc ruby libatomic-static libstdc++-static sed unzip which libicu-devel 'perl(Math::BigInt)'
|
||||||
```
|
```
|
||||||
|
|
||||||
```bash openSUSE Tumbleweed
|
```bash openSUSE Tumbleweed
|
||||||
@@ -56,6 +70,46 @@ $ brew install bun
|
|||||||
|
|
||||||
</CodeGroup>
|
</CodeGroup>
|
||||||
|
|
||||||
|
### Optional: Install `sccache`
|
||||||
|
|
||||||
|
sccache is used to cache compilation artifacts, significantly speeding up builds. It must be installed with S3 support:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# For macOS
|
||||||
|
$ brew install sccache
|
||||||
|
|
||||||
|
# For Linux. Note that the version in your package manager may not have S3 support.
|
||||||
|
$ cargo install sccache --features=s3
|
||||||
|
```
|
||||||
|
|
||||||
|
This will install `sccache` with S3 support. Our build scripts will automatically detect and use `sccache` with our shared S3 cache. **Note**: Not all versions of `sccache` are compiled with S3 support, hence we recommend installing it via `cargo`.
|
||||||
|
|
||||||
|
#### Registering AWS Credentials for `sccache` (Core Developers Only)
|
||||||
|
|
||||||
|
Core developers have write access to the shared S3 cache. To enable write access, you must log in with AWS credentials. The easiest way to do this is to use the [`aws` CLI](https://aws.amazon.com/cli/) and invoke [`aws configure` to provide your AWS security info](https://docs.aws.amazon.com/cli/latest/reference/configure/).
|
||||||
|
|
||||||
|
The `cmake` scripts should automatically detect your AWS credentials from the environment or the `~/.aws/credentials` file.
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary>Logging in to the `aws` CLI</summary>
|
||||||
|
|
||||||
|
1. Install the AWS CLI by following [the official guide](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html).
|
||||||
|
2. Log in to your AWS account console. A team member should provide you with your credentials.
|
||||||
|
3. Click your name in the top right > Security credentials.
|
||||||
|
4. Scroll to "Access keys" and create a new access key.
|
||||||
|
5. Run `aws configure` in your terminal and provide the access key ID and secret access key when prompted.
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary>Common Issues You May Encounter</summary>
|
||||||
|
|
||||||
|
- To confirm that the cache is being used, you can use the `sccache --show-stats` command right after a build. This will expose very useful statistics, including cache hits/misses.
|
||||||
|
- If you have multiple AWS profiles configured, ensure that the correct profile is set in the `AWS_PROFILE` environment variable.
|
||||||
|
- `sccache` follows a server-client model. If you run into weird issues where `sccache` refuses to use S3, even though you have AWS credentials configured, try killing any running `sccache` servers with `sccache --stop-server` and then re-running the build.
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
## Install LLVM
|
## Install LLVM
|
||||||
|
|
||||||
Bun requires LLVM 19 (`clang` is part of LLVM). This version requirement is to match WebKit (precompiled), as mismatching versions will cause memory allocation failures at runtime. In most cases, you can install LLVM through your system package manager:
|
Bun requires LLVM 19 (`clang` is part of LLVM). This version requirement is to match WebKit (precompiled), as mismatching versions will cause memory allocation failures at runtime. In most cases, you can install LLVM through your system package manager:
|
||||||
@@ -156,7 +210,7 @@ Bun generally takes about 2.5 minutes to compile a debug build when there are Zi
|
|||||||
- Batch up your changes
|
- Batch up your changes
|
||||||
- Ensure zls is running with incremental watching for LSP errors (if you use VSCode and install Zig and run `bun run build` once to download Zig, this should just work)
|
- Ensure zls is running with incremental watching for LSP errors (if you use VSCode and install Zig and run `bun run build` once to download Zig, this should just work)
|
||||||
- Prefer using the debugger ("CodeLLDB" in VSCode) to step through the code.
|
- Prefer using the debugger ("CodeLLDB" in VSCode) to step through the code.
|
||||||
- Use debug logs. `BUN_DEBUG_<scope>=1` will enable debug logging for the corresponding `Output.scoped(.<scope>, false)` logs. You can also set `BUN_DEBUG_QUIET_LOGS=1` to disable all debug logging that isn't explicitly enabled. To dump debug lgos into a file, `BUN_DEBUG=<path-to-file>.log`. Debug logs are aggressively removed in release builds.
|
- Use debug logs. `BUN_DEBUG_<scope>=1` will enable debug logging for the corresponding `Output.scoped(.<scope>, .hidden)` logs. You can also set `BUN_DEBUG_QUIET_LOGS=1` to disable all debug logging that isn't explicitly enabled. To dump debug logs into a file, `BUN_DEBUG=<path-to-file>.log`. Debug logs are aggressively removed in release builds.
|
||||||
- src/js/\*\*.ts changes are pretty much instant to rebuild. C++ changes are a bit slower, but still much faster than the Zig code (Zig is one compilation unit, C++ is many).
|
- src/js/\*\*.ts changes are pretty much instant to rebuild. C++ changes are a bit slower, but still much faster than the Zig code (Zig is one compilation unit, C++ is many).
|
||||||
|
|
||||||
## Code generation scripts
|
## Code generation scripts
|
||||||
@@ -327,15 +381,6 @@ bun run build -DUSE_STATIC_LIBATOMIC=OFF
|
|||||||
|
|
||||||
The built version of Bun may not work on other systems if compiled this way.
|
The built version of Bun may not work on other systems if compiled this way.
|
||||||
|
|
||||||
### ccache conflicts with building TinyCC on macOS
|
|
||||||
|
|
||||||
If you run into issues with `ccache` when building TinyCC, try reinstalling ccache
|
|
||||||
|
|
||||||
```bash
|
|
||||||
brew uninstall ccache
|
|
||||||
brew install ccache
|
|
||||||
```
|
|
||||||
|
|
||||||
## Using bun-debug
|
## Using bun-debug
|
||||||
|
|
||||||
- Disable logging: `BUN_DEBUG_QUIET_LOGS=1 bun-debug ...` (to disable all debug logging)
|
- Disable logging: `BUN_DEBUG_QUIET_LOGS=1 bun-debug ...` (to disable all debug logging)
|
||||||
|
|||||||
@@ -219,16 +219,21 @@ Build a minimal HTTP server with `Bun.serve`, run it locally, then evolve it by
|
|||||||
|
|
||||||
Bun can also execute `"scripts"` from your `package.json`. Add the following script:
|
Bun can also execute `"scripts"` from your `package.json`. Add the following script:
|
||||||
|
|
||||||
|
{/* prettier-ignore */}
|
||||||
```json package.json icon="file-code"
|
```json package.json icon="file-code"
|
||||||
{
|
{
|
||||||
"name": "quickstart",
|
"name": "quickstart",
|
||||||
"module": "index.ts",
|
"module": "index.ts",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"private": true,
|
||||||
"start": "bun run index.ts"
|
"scripts": { // [!code ++]
|
||||||
},
|
"start": "bun run index.ts" // [!code ++]
|
||||||
|
}, // [!code ++]
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/bun": "latest"
|
"@types/bun": "latest"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"typescript": "^5"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -276,6 +276,58 @@ This is useful for catching flaky tests or non-deterministic behavior. Each test
|
|||||||
|
|
||||||
The `--rerun-each` CLI flag will override this setting when specified.
|
The `--rerun-each` CLI flag will override this setting when specified.
|
||||||
|
|
||||||
|
### `test.concurrentTestGlob`
|
||||||
|
|
||||||
|
Specify a glob pattern to automatically run matching test files with concurrent test execution enabled. Test files matching this pattern will behave as if the `--concurrent` flag was passed, running all tests within those files concurrently.
|
||||||
|
|
||||||
|
```toml title="bunfig.toml" icon="settings"
|
||||||
|
[test]
|
||||||
|
concurrentTestGlob = "**/concurrent-*.test.ts"
|
||||||
|
```
|
||||||
|
|
||||||
|
This is useful for:
|
||||||
|
|
||||||
|
- Gradually migrating test suites to concurrent execution
|
||||||
|
- Running integration tests concurrently while keeping unit tests sequential
|
||||||
|
- Separating fast concurrent tests from tests that require sequential execution
|
||||||
|
|
||||||
|
The `--concurrent` CLI flag will override this setting when specified.
|
||||||
|
|
||||||
|
### `test.onlyFailures`
|
||||||
|
|
||||||
|
When enabled, only failed tests are displayed in the output. This helps reduce noise in large test suites by hiding passing tests. Default `false`.
|
||||||
|
|
||||||
|
```toml title="bunfig.toml" icon="settings"
|
||||||
|
[test]
|
||||||
|
onlyFailures = true
|
||||||
|
```
|
||||||
|
|
||||||
|
This is equivalent to using the `--only-failures` flag when running `bun test`.
|
||||||
|
|
||||||
|
### `test.reporter`
|
||||||
|
|
||||||
|
Configure the test reporter settings.
|
||||||
|
|
||||||
|
#### `test.reporter.dots`
|
||||||
|
|
||||||
|
Enable the dots reporter, which displays a compact output showing a dot for each test. Default `false`.
|
||||||
|
|
||||||
|
```toml title="bunfig.toml" icon="settings"
|
||||||
|
[test.reporter]
|
||||||
|
dots = true
|
||||||
|
```
|
||||||
|
|
||||||
|
#### `test.reporter.junit`
|
||||||
|
|
||||||
|
Enable JUnit XML reporting and specify the output file path.
|
||||||
|
|
||||||
|
```toml title="bunfig.toml" icon="settings"
|
||||||
|
[test.reporter]
|
||||||
|
junit = "test-results.xml"
|
||||||
|
```
|
||||||
|
|
||||||
|
This generates a JUnit XML report that can be consumed by CI systems and other tools.
|
||||||
|
|
||||||
## Package manager
|
## Package manager
|
||||||
|
|
||||||
Package management is a complex issue; to support a range of use cases, the behavior of `bun install` can be configured under the `[install]` section.
|
Package management is a complex issue; to support a range of use cases, the behavior of `bun install` can be configured under the `[install]` section.
|
||||||
@@ -551,7 +603,7 @@ For more details see [Minimum release age](/pm/cli/install#minimum-release-age)
|
|||||||
|
|
||||||
The `bun run` command can be configured under the `[run]` section. These apply to the `bun run` command and the `bun` command when running a file or executable or script.
|
The `bun run` command can be configured under the `[run]` section. These apply to the `bun run` command and the `bun` command when running a file or executable or script.
|
||||||
|
|
||||||
Currently, `bunfig.toml` isn't always automatically loaded for `bun run` in a local project (it does check for a global `bunfig.toml`), so you might still need to pass `-c` or `-c=bunfig.toml` to use these settings.
|
Currently, `bunfig.toml` is only automatically loaded for `bun run` in a local project (it doesn't check for a global `.bunfig.toml`).
|
||||||
|
|
||||||
### `run.shell` - use the system shell or Bun's shell
|
### `run.shell` - use the system shell or Bun's shell
|
||||||
|
|
||||||
|
|||||||
@@ -46,29 +46,22 @@ console.log(result);
|
|||||||
|
|
||||||
This replaces all images with a thumbnail of Rick Astley and wraps each `<img>` in a link, producing a diff like this:
|
This replaces all images with a thumbnail of Rick Astley and wraps each `<img>` in a link, producing a diff like this:
|
||||||
|
|
||||||
|
{/* prettier-ignore */}
|
||||||
```html
|
```html
|
||||||
<html>
|
<html>
|
||||||
<body>
|
<body>
|
||||||
<img src="/cat.jpg" /> // [!code --] <img src="dog.png" /> // [!code --]
|
<img src="/cat.jpg" /> <!-- [!code --] -->
|
||||||
<img src="https://example.com/bird.webp" /> // [!code --]
|
<img src="dog.png" /> <!-- [!code --] -->
|
||||||
<a href="https://www.youtube.com/watch?v=dQw4w9WgXcQ" target="_blank">
|
<img src="https://example.com/bird.webp" /> <!-- [!code --] -->
|
||||||
// [!code ++]
|
<a href="https://www.youtube.com/watch?v=dQw4w9WgXcQ" target="_blank"> <!-- [!code ++] -->
|
||||||
<img src="https://img.youtube.com/vi/dQw4w9WgXcQ/maxresdefault.jpg" alt="Definitely not a rickroll" />
|
<img src="https://img.youtube.com/vi/dQw4w9WgXcQ/maxresdefault.jpg" alt="Definitely not a rickroll" /> <!-- [!code ++] -->
|
||||||
// [!code ++]
|
</a> <!-- [!code ++] -->
|
||||||
</a>
|
<a href="https://www.youtube.com/watch?v=dQw4w9WgXcQ" target="_blank"> <!-- [!code ++] -->
|
||||||
// [!code ++]
|
<img src="https://img.youtube.com/vi/dQw4w9WgXcQ/maxresdefault.jpg" alt="Definitely not a rickroll" /> <!-- [!code ++] -->
|
||||||
<a href="https://www.youtube.com/watch?v=dQw4w9WgXcQ" target="_blank">
|
</a> <!-- [!code ++] -->
|
||||||
// [!code ++]
|
<a href="https://www.youtube.com/watch?v=dQw4w9WgXcQ" target="_blank"> <!-- [!code ++] -->
|
||||||
<img src="https://img.youtube.com/vi/dQw4w9WgXcQ/maxresdefault.jpg" alt="Definitely not a rickroll" />
|
<img src="https://img.youtube.com/vi/dQw4w9WgXcQ/maxresdefault.jpg" alt="Definitely not a rickroll" /> <!-- [!code ++] -->
|
||||||
// [!code ++]
|
</a> <!-- [!code ++] -->
|
||||||
</a>
|
|
||||||
// [!code ++]
|
|
||||||
<a href="https://www.youtube.com/watch?v=dQw4w9WgXcQ" target="_blank">
|
|
||||||
// [!code ++]
|
|
||||||
<img src="https://img.youtube.com/vi/dQw4w9WgXcQ/maxresdefault.jpg" alt="Definitely not a rickroll" />
|
|
||||||
// [!code ++]
|
|
||||||
</a>
|
|
||||||
// [!code ++]
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -283,7 +283,7 @@ You can also access the `Server` object from the `fetch` handler. It's the secon
|
|||||||
const server = Bun.serve({
|
const server = Bun.serve({
|
||||||
fetch(req, server) {
|
fetch(req, server) {
|
||||||
const ip = server.requestIP(req);
|
const ip = server.requestIP(req);
|
||||||
return new Response(`Your IP is ${ip}`);
|
return new Response(`Your IP is ${ip.address}`);
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
```
|
```
|
||||||
|
|||||||
@@ -107,13 +107,13 @@ Bun.serve({
|
|||||||
|
|
||||||
Once the upgrade succeeds, Bun will send a `101 Switching Protocols` response per the [spec](https://developer.mozilla.org/en-US/docs/Web/HTTP/Protocol_upgrade_mechanism). Additional `headers` can be attached to this `Response` in the call to `server.upgrade()`.
|
Once the upgrade succeeds, Bun will send a `101 Switching Protocols` response per the [spec](https://developer.mozilla.org/en-US/docs/Web/HTTP/Protocol_upgrade_mechanism). Additional `headers` can be attached to this `Response` in the call to `server.upgrade()`.
|
||||||
|
|
||||||
|
{/* prettier-ignore */}
|
||||||
```ts server.ts icon="/icons/typescript.svg"
|
```ts server.ts icon="/icons/typescript.svg"
|
||||||
Bun.serve({
|
Bun.serve({
|
||||||
fetch(req, server) {
|
fetch(req, server) {
|
||||||
const sessionId = await generateSessionId();
|
const sessionId = await generateSessionId();
|
||||||
server.upgrade(req, {
|
server.upgrade(req, {
|
||||||
headers: {
|
headers: { // [!code ++]
|
||||||
// [!code ++]
|
|
||||||
"Set-Cookie": `SessionId=${sessionId}`, // [!code ++]
|
"Set-Cookie": `SessionId=${sessionId}`, // [!code ++]
|
||||||
}, // [!code ++]
|
}, // [!code ++]
|
||||||
});
|
});
|
||||||
@@ -126,6 +126,8 @@ Bun.serve({
|
|||||||
|
|
||||||
Contextual `data` can be attached to a new WebSocket in the `.upgrade()` call. This data is made available on the `ws.data` property inside the WebSocket handlers.
|
Contextual `data` can be attached to a new WebSocket in the `.upgrade()` call. This data is made available on the `ws.data` property inside the WebSocket handlers.
|
||||||
|
|
||||||
|
To strongly type `ws.data`, add a `data` property to the `websocket` handler object. This types `ws.data` across all lifecycle hooks.
|
||||||
|
|
||||||
```ts server.ts icon="/icons/typescript.svg"
|
```ts server.ts icon="/icons/typescript.svg"
|
||||||
type WebSocketData = {
|
type WebSocketData = {
|
||||||
createdAt: number;
|
createdAt: number;
|
||||||
@@ -166,6 +168,10 @@ Bun.serve({
|
|||||||
});
|
});
|
||||||
```
|
```
|
||||||
|
|
||||||
|
<Info>
|
||||||
|
**Note:** Previously, you could specify the type of `ws.data` using a type parameter on `Bun.serve`, like `Bun.serve<MyData>({...})`. This pattern was removed due to [a limitation in TypeScript](https://github.com/microsoft/TypeScript/issues/26242) in favor of the `data` property shown above.
|
||||||
|
</Info>
|
||||||
|
|
||||||
To connect to this server from the browser, create a new `WebSocket`.
|
To connect to this server from the browser, create a new `WebSocket`.
|
||||||
|
|
||||||
```ts browser.js icon="file-code"
|
```ts browser.js icon="file-code"
|
||||||
|
|||||||
@@ -183,6 +183,29 @@ import { stuff } from "foo";
|
|||||||
|
|
||||||
The full specification of this algorithm are officially documented in the [Node.js documentation](https://nodejs.org/api/modules.html); we won't rehash it here. Briefly: if you import `from "foo"`, Bun scans up the file system for a `node_modules` directory containing the package `foo`.
|
The full specification of this algorithm are officially documented in the [Node.js documentation](https://nodejs.org/api/modules.html); we won't rehash it here. Briefly: if you import `from "foo"`, Bun scans up the file system for a `node_modules` directory containing the package `foo`.
|
||||||
|
|
||||||
|
### NODE_PATH
|
||||||
|
|
||||||
|
Bun supports `NODE_PATH` for additional module resolution directories:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
NODE_PATH=./packages bun run src/index.js
|
||||||
|
```
|
||||||
|
|
||||||
|
```ts
|
||||||
|
// packages/foo/index.js
|
||||||
|
export const hello = "world";
|
||||||
|
|
||||||
|
// src/index.js
|
||||||
|
import { hello } from "foo";
|
||||||
|
```
|
||||||
|
|
||||||
|
Multiple paths use the platform's delimiter (`:` on Unix, `;` on Windows):
|
||||||
|
|
||||||
|
```bash
|
||||||
|
NODE_PATH=./packages:./lib bun run src/index.js # Unix/macOS
|
||||||
|
NODE_PATH=./packages;./lib bun run src/index.js # Windows
|
||||||
|
```
|
||||||
|
|
||||||
Once it finds the `foo` package, Bun reads the `package.json` to determine how the package should be imported. To determine the package's entrypoint, Bun first reads the `exports` field and checks for the following conditions.
|
Once it finds the `foo` package, Bun reads the `package.json` to determine how the package should be imported. To determine the package's entrypoint, Bun first reads the `exports` field and checks for the following conditions.
|
||||||
|
|
||||||
```json package.json icon="file-json"
|
```json package.json icon="file-json"
|
||||||
|
|||||||
@@ -51,6 +51,7 @@ await client.incr("counter");
|
|||||||
By default, the client reads connection information from the following environment variables (in order of precedence):
|
By default, the client reads connection information from the following environment variables (in order of precedence):
|
||||||
|
|
||||||
- `REDIS_URL`
|
- `REDIS_URL`
|
||||||
|
- `VALKEY_URL`
|
||||||
- If not set, defaults to `"redis://localhost:6379"`
|
- If not set, defaults to `"redis://localhost:6379"`
|
||||||
|
|
||||||
### Connection Lifecycle
|
### Connection Lifecycle
|
||||||
|
|||||||
@@ -234,8 +234,8 @@ Bun.openInEditor(currentFile);
|
|||||||
You can override this via the `debug.editor` setting in your [`bunfig.toml`](/runtime/bunfig).
|
You can override this via the `debug.editor` setting in your [`bunfig.toml`](/runtime/bunfig).
|
||||||
|
|
||||||
```toml bunfig.toml
|
```toml bunfig.toml
|
||||||
[debug] // [!code ++]
|
[debug] # [!code ++]
|
||||||
editor = "code" // [!code ++]
|
editor = "code" # [!code ++]
|
||||||
```
|
```
|
||||||
|
|
||||||
Or specify an editor with the `editor` param. You can also specify a line and column number.
|
Or specify an editor with the `editor` param. You can also specify a line and column number.
|
||||||
|
|||||||
@@ -184,6 +184,53 @@ This is useful for:
|
|||||||
- Large test suites that consume significant memory
|
- Large test suites that consume significant memory
|
||||||
- Development environments with memory constraints
|
- Development environments with memory constraints
|
||||||
|
|
||||||
|
## Test execution
|
||||||
|
|
||||||
|
### concurrentTestGlob
|
||||||
|
|
||||||
|
Automatically run test files matching a glob pattern with concurrent test execution enabled. This is useful for gradually migrating test suites to concurrent execution or for running specific test types concurrently.
|
||||||
|
|
||||||
|
```toml title="bunfig.toml" icon="settings"
|
||||||
|
[test]
|
||||||
|
concurrentTestGlob = "**/concurrent-*.test.ts" # Run files matching this pattern concurrently
|
||||||
|
```
|
||||||
|
|
||||||
|
Test files matching this pattern will behave as if the `--concurrent` flag was passed, running all tests within those files concurrently. This allows you to:
|
||||||
|
|
||||||
|
- Gradually migrate your test suite to concurrent execution
|
||||||
|
- Run integration tests concurrently while keeping unit tests sequential
|
||||||
|
- Separate fast concurrent tests from tests that require sequential execution
|
||||||
|
|
||||||
|
The `--concurrent` CLI flag will override this setting when specified, forcing all tests to run concurrently regardless of the glob pattern.
|
||||||
|
|
||||||
|
#### randomize
|
||||||
|
|
||||||
|
Run tests in random order to identify tests with hidden dependencies:
|
||||||
|
|
||||||
|
```toml title="bunfig.toml" icon="settings"
|
||||||
|
[test]
|
||||||
|
randomize = true
|
||||||
|
```
|
||||||
|
|
||||||
|
#### seed
|
||||||
|
|
||||||
|
Specify a seed for reproducible random test order. Requires `randomize = true`:
|
||||||
|
|
||||||
|
```toml title="bunfig.toml" icon="settings"
|
||||||
|
[test]
|
||||||
|
randomize = true
|
||||||
|
seed = 2444615283
|
||||||
|
```
|
||||||
|
|
||||||
|
#### rerunEach
|
||||||
|
|
||||||
|
Re-run each test file multiple times to identify flaky tests:
|
||||||
|
|
||||||
|
```toml title="bunfig.toml" icon="settings"
|
||||||
|
[test]
|
||||||
|
rerunEach = 3
|
||||||
|
```
|
||||||
|
|
||||||
## Coverage Options
|
## Coverage Options
|
||||||
|
|
||||||
### Basic Coverage Settings
|
### Basic Coverage Settings
|
||||||
|
|||||||
@@ -41,6 +41,15 @@ test/package-json-lint.test.ts:
|
|||||||
Ran 4 tests across 1 files. [0.66ms]
|
Ran 4 tests across 1 files. [0.66ms]
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### Dots Reporter
|
||||||
|
|
||||||
|
The dots reporter shows `.` for passing tests and `F` for failures—useful for large test suites.
|
||||||
|
|
||||||
|
```sh terminal icon="terminal"
|
||||||
|
bun test --dots
|
||||||
|
bun test --reporter=dots
|
||||||
|
```
|
||||||
|
|
||||||
### JUnit XML Reporter
|
### JUnit XML Reporter
|
||||||
|
|
||||||
For CI/CD environments, Bun supports generating JUnit XML reports. JUnit XML is a widely-adopted format for test results that can be parsed by many CI/CD systems, including GitLab, Jenkins, and others.
|
For CI/CD environments, Bun supports generating JUnit XML reports. JUnit XML is a widely-adopted format for test results that can be parsed by many CI/CD systems, including GitLab, Jenkins, and others.
|
||||||
|
|||||||
2
packages/bun-types/bun.d.ts
vendored
2
packages/bun-types/bun.d.ts
vendored
@@ -1788,7 +1788,7 @@ declare module "bun" {
|
|||||||
* @see {@link outdir} required for `"linked"` maps
|
* @see {@link outdir} required for `"linked"` maps
|
||||||
* @see {@link publicPath} to customize the base url of linked source maps
|
* @see {@link publicPath} to customize the base url of linked source maps
|
||||||
*/
|
*/
|
||||||
sourcemap?: "none" | "linked" | "inline" | "external" | "linked" | boolean;
|
sourcemap?: "none" | "linked" | "inline" | "external" | boolean;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* package.json `exports` conditions used when resolving imports
|
* package.json `exports` conditions used when resolving imports
|
||||||
|
|||||||
@@ -215,7 +215,7 @@ export interface BundlerTestInput {
|
|||||||
unsupportedJSFeatures?: string[];
|
unsupportedJSFeatures?: string[];
|
||||||
/** if set to true or false, create or edit tsconfig.json to set compilerOptions.useDefineForClassFields */
|
/** if set to true or false, create or edit tsconfig.json to set compilerOptions.useDefineForClassFields */
|
||||||
useDefineForClassFields?: boolean;
|
useDefineForClassFields?: boolean;
|
||||||
sourceMap?: "inline" | "external" | "linked" | "none" | "linked";
|
sourceMap?: "inline" | "external" | "linked" | "none";
|
||||||
plugins?: BunPlugin[] | ((builder: PluginBuilder) => void | Promise<void>);
|
plugins?: BunPlugin[] | ((builder: PluginBuilder) => void | Promise<void>);
|
||||||
install?: string[];
|
install?: string[];
|
||||||
production?: boolean;
|
production?: boolean;
|
||||||
|
|||||||
Reference in New Issue
Block a user