Jarred Sumner 92229ac0f6 Fix unbundled imports
Former-commit-id: f221da115c1afcd136648c9683d8e9907005a128
2021-08-26 21:43:42 -07:00
2021-08-25 19:08:11 -07:00
2021-08-17 01:44:30 -07:00
WIP
2021-07-28 10:56:36 -07:00
2021-08-25 19:08:11 -07:00
2021-08-10 18:26:16 -07:00
2021-08-15 22:17:20 -07:00
2021-08-26 21:43:42 -07:00
2021-08-15 22:17:20 -07:00
2021-08-25 19:08:11 -07:00
2021-08-24 00:49:39 -07:00
2021-08-25 17:56:06 -07:00
all
2021-05-28 23:26:13 -07:00
all
2021-05-28 23:26:13 -07:00
all
2021-05-28 23:26:13 -07:00
all
2021-05-28 23:26:13 -07:00
2021-06-09 13:26:30 -07:00
2021-08-25 17:56:06 -07:00
2021-06-09 13:26:30 -07:00
2021-05-08 14:23:52 -07:00
2021-07-19 17:15:57 -07:00
2021-08-25 17:56:06 -07:00
2021-08-15 22:17:20 -07:00
go
2021-08-11 13:56:03 -07:00

Bun: a fast bundler & transpiler for developing web software

Bun is a new:

  • JavaScript/TypeScript/JSX transpiler (bun ./file.tsx)
  • JavaScript bundler (run bun bun ./file1.ts ./file2.jsx and it will flatten node_module imports into one .bun)
  • Development server with 60fps Hot Module Reloading (& WIP support for React Fast Refresh) (run bun dev)
  • CSS bundler bun ./file.css (it flattens @import into one file)
  • JavaScript Runtime Environment (powered by JavaScriptCore, what WebKit/Safari uses)

All in one simple tool.

Most of Bun is written in Zig, a fast low-level programming language with manual memory management.

Install:

# Global install is recommended so bun appears in your $PATH
npm install -g bun-cli

Getting started

Using Bun with Next.js

In your project folder root (where package.json is):

npm install bun-framework-next path buffer
bun bun --use next
open http://localhost:3000; bun dev --origin "http://localhost:3000"

Here are some features of Next.js that aren't supported yet:

  • getStaticProps,getServerSideProps, getInitialProps, getStaticPaths. These functions will not be called.
  • locales, zones, assetPrefix (workaround: change --origin \"http://localhsot:3000/assetPrefixInhere\")
  • next/image - <Image /> component

Currently, any time you import new dependencies from node_modules, you will need to re-run bun bun --use next. This will eventually be automatic.

Using Bun without a framework or with Create React App

In your project folder root (where package.json is):

bun bun ./entry-point-1.js ./entry-point-2.jsx
bun dev ./entry-point-1.js ./entry-point-2.jsx --origin https://localhost:3000

By default, bun dev will look for any HTML files in the public directory and serve that. For browsers navigating to the page, the .html file extension is optional in the URL, and index.html will automatically rewrite for the directory.

Here are examples of routing from public/ and how they're matched:

File Path Dev Server URL
public/dir/index.html /dir
public/index.html /
public/hi.html /hi
public/file.html /file
public/font/Inter.woff2 /font/Inter.woff2

For Create React App users, note that Bun does not transpile HTML yet, so %PUBLIC_URL% will need to be replaced with '/'`.

From there, Bun relies on the filesystem for mapping dev server paths to source files. All URL paths are relative to the project root (where package.json is).

Here are examples of routing source code file paths:

File Path Dev Server URL
src/components/Button.tsx /src/components/Button.tsx
src/index.tsx /src/index.tsx
pages/index.js /pages/index.js

Using Bun without bun dev

bun dev is the recommended way to use Bun. Today, Bun is primarily intended to speed up your frontend development iteration cycle. bun does not implement a JavaScript minifier yet, and does not implement all the optimizations other tools do for shrinking bundle size. That means you probably should look to other tools for bundling in production. To make this split smoother, Bun strives for ecosystem compatibility (e.g. by integrating with Next.js)

bun bun ./entry-point-1.js ./entry-point-2.jsx
bun build ./entry-point-1.js ./entry-point-2.jsx --origin https://localhost:3000 --outdir=./out

You can also pass Bun a folder, and it will assume all JavaScript-like files are entry-points. This lets you use Bun's native filesystem router without a framework.

For a routes directory with these files:

  • routes/index.js
  • routes/hello/bar.js
  • routes/hello/baz.jsx
  • routes/wut/wat.jsx

This would be the corresponding command:

bun bun ./routes
bun build ./routes --outdir=./out

The Bun Bundling Format

bun bun generates a node_modules.bun and (optionally) a node_modules.server.bun. This is a new binary file format that makes it very efficient to serialize/deserialize node_modules. With a 2.4 GHz 8-Core Intel Core i9, metadata for

Unlike many other bundlers, Bun only bundles node_modules. This is great for development, where most people add/update packages much less frequently than app code (which is also great for caching in browsers). To make that distinction clear, the filename defaults to node_modules.bun. We recommend storing node_modules.bun in your git repository. Since it's a binary file, it shouldn't clutter your git history and it will make your entire frontend development team move faster if they don't have to re-bundle dependencies.

Building from source

Estimated: 30-60 minutes :(

You'll want to start downloading two things at once:

git clone https://github.com/jarred-sumner/zig && git checkout jarred/zig-sloppy-with-small-structs
git submodule update --init --recursive --progress --depth=1

Next, compile Zig.

On a Mac, that looks like this:

cmake . -DCMAKE_PREFIX_PATH=$(brew --prefix llvm) -DZIG_STATIC_LLVM=ON -DCMAKE_BUILD_TYPE=Release  && make -j 16

Note that brew install zig won't work. Bun uses a build of Zig with a couple patches.

You'll want to make sure zig is in $PATH. The zig binary wil be in the same folder as the newly-cloned zig repo. If you use fish, you can run fish_add_path (pwd).

Now go back to the folder with Bun's repository.

Run:

zig build headers
zig build

Credits

  • While written in Zig instead of Go, Bun's JS transpiler & CSS lexer source code is based off of @evanw's esbuild project. @evanw did a fantastic job with esbuild.

License

Bun itself is MIT-licensed.

However, JavaScriptCore (and WebKit) is LGPL-2 and Bun statically links it.

Per LGPL2:

(1) If you statically link against an LGPL'd library, you must also provide your application in an object (not necessarily source) format, so that a user has the opportunity to modify the library and relink the application.

You can find the patched version of WebKit used by Bun here: https://github.com/jarred-sumner/webkit. If you would like to relink Bun with changes:

  • git submodule update --init --recursive
  • make jsc
  • zig build

This compiles JavaScriptCore, compiles Bun's .cpp bindings for JavaScriptCore (which are the object files using JavaScriptCore) and outputs a new bun binary with your changes.

To successfully run zig build, you will need to install a fork of Zig you can find here: https://github.com/jarred-sumner/zig/tree/jarred/zig-sloppy.

Bun also statically links:

Description
Bun is a fast, incrementally adoptable all-in-one JavaScript, TypeScript & JSX toolkit. Use individual tools like bun test or bun install in Node.js projects, or adopt the complete stack with a fast JavaScript runtime, bundler, test runner, and package manager built in. Bun aims for 100% Node.js compatibility.
Readme 847 MiB
Languages
Zig 60.6%
C++ 24.9%
TypeScript 8.3%
C 3.3%
JavaScript 1.4%
Other 1.1%