mirror of
https://github.com/oven-sh/bun
synced 2026-02-02 15:08:46 +00:00
feat(bundler): add files option for in-memory bundling (#25852)
## Summary
Add support for in-memory entrypoints and files in `Bun.build` via the
`files` option:
```ts
await Bun.build({
entrypoints: ["/app/index.ts"],
files: {
"/app/index.ts": `
import { greet } from "./greet.ts";
console.log(greet("World"));
`,
"/app/greet.ts": `
export function greet(name: string) {
return "Hello, " + name + "!";
}
`,
},
});
```
### Features
- **Bundle entirely from memory**: No files on disk needed
- **Override files on disk**: In-memory files take priority over disk
files
- **Mix disk and virtual files**: Real files can import virtual files
and vice versa
- **Multiple content types**: Supports `string`, `Blob`, `TypedArray`,
and `ArrayBuffer`
### Use Cases
- Code generation at build time
- Injecting build-time constants
- Testing with mock modules
- Bundling dynamically generated code
- Overriding configuration files for different environments
### Implementation Details
- Added `FileMap` struct in `JSBundler.zig` with `resolve`, `get`,
`contains`, `fromJS`, and `deinit` methods
- Uses `"memory"` namespace to avoid `pathWithPrettyInitialized`
allocation issues during linking phase
- FileMap checks added in:
- `runResolver` (entry point resolution)
- `runResolutionForParseTask` (import resolution)
- `enqueueEntryPoints` (entry point handling)
- `getCodeForParseTaskWithoutPlugins` (file content reading)
- Root directory defaults to cwd when all entrypoints are in the FileMap
- Added TypeScript types with JSDoc documentation
- Added bundler documentation with examples
## Test plan
- [x] Basic in-memory file bundling
- [x] In-memory files with absolute imports
- [x] In-memory files with relative imports (same dir, subdirs, parent
dirs)
- [x] Nested/chained imports between in-memory files
- [x] TypeScript and JSX support
- [x] Blob, Uint8Array, and ArrayBuffer content types
- [x] Re-exports and default exports
- [x] In-memory file overrides real file on disk
- [x] Real file on disk imports in-memory file via relative path
- [x] Mixed disk and memory files with complex import graphs
Run tests with: `bun bd test test/bundler/bundler_files.test.ts`
🤖 Generated with [Claude Code](https://claude.com/claude-code)
---------
Co-authored-by: Claude Bot <claude-bot@bun.sh>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
Co-authored-by: Jarred Sumner <jarred@jarredsumner.com>
Co-authored-by: Dylan Conway <dylan.conway567@gmail.com>
This commit is contained in:
59
packages/bun-types/bun.d.ts
vendored
59
packages/bun-types/bun.d.ts
vendored
@@ -1979,6 +1979,65 @@ declare module "bun" {
|
||||
*/
|
||||
reactFastRefresh?: boolean;
|
||||
|
||||
/**
|
||||
* A map of file paths to their contents for in-memory bundling.
|
||||
*
|
||||
* This allows you to bundle virtual files that don't exist on disk, or override
|
||||
* the contents of files that do exist on disk. The keys are file paths (which should
|
||||
* match how they're imported) and the values are the file contents.
|
||||
*
|
||||
* File contents can be provided as:
|
||||
* - `string` - The source code as a string
|
||||
* - `Blob` - A Blob containing the source code
|
||||
* - `NodeJS.TypedArray` - A typed array (e.g., `Uint8Array`) containing the source code
|
||||
* - `ArrayBufferLike` - An ArrayBuffer containing the source code
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* // Bundle entirely from memory (no files on disk needed)
|
||||
* await Bun.build({
|
||||
* entrypoints: ["/app/index.ts"],
|
||||
* files: {
|
||||
* "/app/index.ts": `
|
||||
* import { helper } from "./helper.ts";
|
||||
* console.log(helper());
|
||||
* `,
|
||||
* "/app/helper.ts": `
|
||||
* export function helper() {
|
||||
* return "Hello from memory!";
|
||||
* }
|
||||
* `,
|
||||
* },
|
||||
* });
|
||||
* ```
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* // Override a file on disk with in-memory contents
|
||||
* await Bun.build({
|
||||
* entrypoints: ["./src/index.ts"],
|
||||
* files: {
|
||||
* // This will be used instead of the actual ./src/config.ts file
|
||||
* "./src/config.ts": `export const API_URL = "https://production.api.com";`,
|
||||
* },
|
||||
* });
|
||||
* ```
|
||||
*
|
||||
* @example
|
||||
* ```ts
|
||||
* // Mix disk files with in-memory files
|
||||
* // Entry point is on disk, but imports a virtual file
|
||||
* await Bun.build({
|
||||
* entrypoints: ["./src/index.ts"], // Real file on disk
|
||||
* files: {
|
||||
* // Virtual file that ./src/index.ts can import via "./generated.ts"
|
||||
* "./src/generated.ts": `export const BUILD_TIME = ${Date.now()};`,
|
||||
* },
|
||||
* });
|
||||
* ```
|
||||
*/
|
||||
files?: Record<string, string | Blob | NodeJS.TypedArray | ArrayBufferLike>;
|
||||
|
||||
/**
|
||||
* Generate a JSON file containing metadata about the build.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user