Bundling is currently an important mechanism for building complex web apps. Modern apps typically consist of a large number of files and package dependencies. Despite the fact that modern browsers support [ES Module](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules) imports, it's still too slow to fetch each file via inidividual HTTP requests. _Bundling_ is the process of concatenating several source files into a single large file that can be loaded in a single request. {% callout %} **On bundling** — Despite recent advances like [`modulepreload`](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/rel/modulepreload) and [HTTP/3](https://en.wikipedia.org/wiki/HTTP/3), bundling is still the most performant approach. {% /callout %} ## Bundling your app Bun's approach to bundling is a little different from other bundlers. Start by passing your app's entrypoint to `bun bun`. ```bash $ bun bun ./app.js ``` Your entrypoint can be any `js|jsx|ts|tsx|html` file. With this file as a starting point, Bun will construct a graph of imported files and packages, transpile everything, and generate a file called `node_modules.bun`. ## What is `.bun`? {% callout %} **Note** — [This format may change soon](https://github.com/oven-sh/bun/issues/121) {% /callout %} A `.bun` file contains the pre-transpiled source code of your application, plus a bunch of binary-encoded metadata about your application's structure. as a contains: - all the bundled source code - all the bundled source code metadata - project metadata & configuration Here are some of the questions `.bun` files answer: - when I import `react/index.js`, where in the `.bun` is the code for that? (not resolving, just the code) - what modules of a package are used? - what framework is used? (e.g., Next.js) - where is the routes directory? - how big is each imported dependency? - what is the hash of the bundle’s contents? (for etags) - what is the name & version of every npm package exported in this bundle? - what modules from which packages are used in this project? ("project" is defined as all the entry points used to generate the .bun) All in one file. It’s a little like a build cache, but designed for reuse across builds. {% details summary="Position-independent code" %} From a design perspective, the most important part of the `.bun` format is how code is organized. Each module is exported by a hash like this: ```js // preact/dist/preact.module.js export var $eb6819b = $$m({ "preact/dist/preact.module.js": (module, exports) => { let n, l, u, i, t, o, r, f, e = {}, c = [], s = /acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|itera/i; // ... rest of code ``` This makes bundled modules [position-independent](https://en.wikipedia.org/wiki/Position-independent_code). In theory, one could import only the exact modules in-use without reparsing code and without generating a new bundle. One bundle can dynamically become many bundles comprising only the modules in use on the webpage. Thanks to the metadata with the byte offsets, a web server can send each module to browsers [zero-copy](https://en.wikipedia.org/wiki/Zero-copy) using [sendfile](https://man7.org/linux/man-pages/man2/sendfile.2.html). Bun itself is not quite this smart yet, but these optimizations would be useful in production and potentially very useful for React Server Components. To see the schema inside, have a look at [`JavascriptBundleContainer`](./src/api/schema.d.ts#:~:text=export%20interface-,JavascriptBundleContainer,-%7B). You can find JavaScript bindings to read the metadata in [src/api/schema.js](./src/api/schema.js). This is not really an API yet. It’s missing the part where it gets the binary data from the bottom of the file. Someday, I want this to be usable by other tools too. {% /details %} ## Where is the code? `.bun` files are marked as executable. To print out the code, run `./node_modules.bun` in your terminal or run `bun ./path-to-node_modules.bun`. Here is a copy-pastable example: ```bash $ ./node_modules.bun > node_modules.js ``` This works because every `.bun` file starts with this: ``` #!/usr/bin/env bun ``` To deploy to production with Bun, you’ll want to get the code from the `.bun` file and stick that somewhere your web server can find it (or if you’re using Vercel or a Rails app, in a `public` folder). Note that `.bun` is a binary file format, so just opening it in VSCode or vim might render strangely. ## Advanced By default, `bun bun` only bundles external dependencies that are `import`ed or `require`d in either app code or another external dependency. An "external dependency" is defined as, "A JavaScript-like file that has `/node_modules/` in the resolved file path and a corresponding `package.json`". To force Bun to bundle packages which are not located in a `node_modules` folder (i.e., the final, resolved path following all symlinks), add a `bun` section to the root project’s `package.json` with `alwaysBundle` set to an array of package names to always bundle. Here’s an example: ```json { "name": "my-package-name-in-here", "bun": { "alwaysBundle": ["@mybigcompany/my-workspace-package"] } } ``` Bundled dependencies are not eligible for Hot Module Reloading. The code is served to browsers & Bun.js verbatim. But, in the future, it may be sectioned off into only parts of the bundle being used. That’s possible in the current version of the `.bun` file (so long as you know which files are necessary), but it’s not implemented yet. Longer-term, it will include all `import` and `export` of each module inside. ## What is the module ID hash? The `$eb6819b` hash used here: ```js export var $eb6819b = $$m({ ``` Is generated like this: 1. Murmur3 32-bit hash of `package.name@package.version`. This is the hash uniquely identifying the npm package. 2. Wyhash 64 of the `package.hash` + `package_path`. `package_path` means "relative to the root of the npm package, where is the module imported?". For example, if you imported `react/jsx-dev-runtime.js`, the `package_path` is `jsx-dev-runtime.js`. `react-dom/cjs/react-dom.development.js` would be `cjs/react-dom.development.js` 3. Truncate the hash generated above to a `u32` The implementation details of this module ID hash will vary between versions of Bun. The important part is the metadata contains the module IDs, the package paths, and the package hashes, so it shouldn’t really matter in practice if other tooling wants to make use of any of this. c'>jarred/clipboard-objc Unnamed repository; edit this file 'description' to name the repository.
aboutsummaryrefslogtreecommitdiff
path: root/packages/bun-release/src (unfollow)
AgeCommit message (Expand)AuthorFilesLines
2023-08-08worker tests (#4058)Gravatar dave caruso 7-15/+83
2023-08-08feat(bun/test): Implement "toSatisfy" & "toIncludeRepeated" (fwup) (#3651)Gravatar Tiramify (A.K. Daniel) 6-2/+367
2023-08-08Set exports to {} in user-constructed CommonJSModuleRecords (#4076)Gravatar dave caruso 2-1/+8
2023-08-08Fix require("console") #3820 (#4073)Gravatar dave caruso 3-2/+9
2023-08-08Update Worker.cppGravatar Dylan Conway 1-1/+0
2023-08-081. Check if the argument is an empty string in `path.format`. (#4064)Gravatar Ai Hoshino 2-67/+213
2023-08-08import bun (#4055)Gravatar Jarred Sumner 8-18/+61
2023-08-08Enable `Headers.prototype.getSetCookie`Gravatar Jarred Sumner 2-25/+11
2023-08-08Remove printfGravatar Jarred Sumner 1-1/+0
2023-08-07Add `env` option for `node:worker_threads` (#4052)Gravatar dave caruso 23-185/+723
2023-08-07Fix `Bun.hash` functions (#4054)Gravatar jhmaster 4-37/+42
2023-08-07fix `worker.ref()`Gravatar Dylan Conway 1-1/+1
2023-08-07add bun update to help menuGravatar Jarred Sumner 1-0/+2
2023-08-07implement fetching data urls (#4000)Gravatar Dylan Conway 10-21/+244
2023-08-07implement `bun update` (#4046)Gravatar Alex Lam S.L 5-89/+389
2023-08-07fix iterating headers with `set-cookie` (#4048)Gravatar Dylan Conway 5-53/+51
2023-08-07WASM test analyzer (#4043)Gravatar Jarred Sumner 25-169/+965
2023-08-07Improve plugin docsGravatar Colin McDonnell 3-306/+283
2023-08-07Fix `path.normalize` edge case. (#4042)Gravatar Ai Hoshino 2-1/+2
2023-08-06Fixes #4001 (#4034)Gravatar Jarred Sumner 3-9/+108
2023-08-06Fixes #4029 and fixes #4022 (#4032)Gravatar Jarred Sumner 4-29/+34
2023-08-06Fixes #4010 (#4031)Gravatar Jarred Sumner 1-24/+17
2023-08-06Update build-idGravatar Jarred Sumner 1-1/+1
2023-08-06Bind require.resolve() (#4030)Gravatar Jarred Sumner 4-13/+47
2023-08-06Fixes #4020Gravatar Jarred Sumner 2-1/+6
2023-08-06Running missing scripts exits with non-0 (#4026)Gravatar Yash Sharma 2-1/+13
2023-08-06[install] handle `bun add` of existing `peerDependencies` correctly (#4028)Gravatar Alex Lam S.L 3-22/+98
2023-08-06fix nanbun-v0.7.3Gravatar Jarred Sumner 1-0/+3
2023-08-06Update coverage.mdGravatar Jarred Sumner 1-1/+1
2023-08-06Update lol-htmlGravatar Jarred Sumner 1-0/+0
2023-08-06Fixes #3129 (#4018)Gravatar Jarred Sumner 3-104/+58
2023-08-06Code coverage for `bun test` (#3975)Gravatar Jarred Sumner 32-61/+1211
2023-08-06feat: impl `dns.getServers` (#3982)Gravatar Ai Hoshino 5-3/+135
2023-08-06Implement --test-name-pattern (#3998)Gravatar dave caruso 8-7/+151
2023-08-05Fix(cli/init): support subpath entrypoint. (#4002)Gravatar Ai Hoshino 1-1/+8
2023-08-05Remove Bun.plugin transpiler hook, encourage usage of `--preload` instead (#3...Gravatar dave caruso 5-243/+1
2023-08-04Support --dev/-D and support more flags on bun install (#3989)Gravatar Colin McDonnell 5-9/+14
2023-08-04fix macro string escaping (#3967)Gravatar Dylan Conway 4-8/+97
2023-08-04Fixes #3991Gravatar Jarred Sumner 2-4/+40
2023-08-04[install] handle `workspace:*` correctly (#3994)Gravatar Alex Lam S.L 2-54/+158
2023-08-04Update import-meta.mdGravatar Jarred Sumner 1-2/+1
2023-08-04Fix incorrect docsGravatar Jarred Sumner 1-2/+3
2023-08-04[types] fix `blob.json()` (#3995)Gravatar Alex Lam S.L 1-4/+4
2023-08-04FFI typo (#3973)Gravatar dave caruso 3-5/+10
2023-08-04Buffer.copy should ignore out-of-range sourceEnd (#3971)Gravatar Yifei Wang 2-17/+34
2023-08-04[install] store resolved workspace path in lockfile (#3974)Gravatar Alex Lam S.L 5-82/+187
2023-08-04Fix types (#3963)Gravatar Colin McDonnell 14-274/+892
2023-08-04feat(hot-clear-screen): clear terminal on hot reload (#3976)Gravatar simylein 1-0/+7