huozhi.im

Zero-Config JS Bundler

bunchee

Reduce Burden

Once up a time, my coworkers who are non-JS developers were looking for a convenient bundler to build a simple JavaScript library. Too many bundlers such as webpack, parcel were confusing them a lot, feeling like finding a sword to cut beef. After being consulted with better choices, without need to understand the JS standards of module resolutions. I tried few ones but none of them are satisfying, so I decided to build my own one.

Especially after reading Lea's post I was strongly convinced that zero-configuration is the right way to go.

The CLI has to be simple enough and can output various types of bundles to support both CJS and ESM well. So I started to build this project, and named it bunchee. (Interestingly, I was trying to the name bun in 2018, but it was taken already and till 2023 it raised as a new amazing bundler in the community.)

Under the Hood of Bundler

Since most of the libraries will be installed on app layers again, for sure we don't have to bundle all the dependencies into final dist.

About bundler: I picked the rollup as the core of bundler, the output will be processed by application bundler.

About Compiler: We picked the blazing fast and stable swc as the compiler, it's a super fast compiler written in rust. It's also being adopted by rollup v4 for AST parsing.

Single Source of Truth

There're many module resolution for Node.js, plus the TypeScript types resolution, it's much more complex. For normal JavaScript project (could contain JSX and CSS), package.json will be enough. Once you configured main or module field, or exports field if you're using modern module resolution.

TypeScript Support

You can also use TypeScript to write your library, just add tsconfig.json to your project root, and bunchee will pick it up automatically. Most of the configuration you don't need to care about, mainly those ones which are effecting the compilation result such as compilation target.

Convention over Configuration

Group all the entry files into src/ folder, and bunchee will scan them and check if they're going to output as bundles. Simply you can just map from src/ to dist/.

At the end, just adding "build" "bunchee" into your package.json scripts, and you're good to go.

{
  "files": ["dist"],
  "main": "./dist/pkg.cjs.js",
  "exports": {
    ".": {
      "import": "./dist/pkg.esm.js",
      "require": "./dist/pkg.cjs.js"
    },
    "./package.json": "./package.json"
  },
  "scripts": {
    "build": "bunchee"
  }
}

React Server Components

People who playing with Next.js React Server Components are familiar with the new directives that introduced for Client Components and Server Actions, which are "use client" and "use server". The application bundler like webpack inside Next.js can analyze them and bundle them into different bundles. If we simply bundle everything into one file, the directives might be mixed and the boundaries will be messed up.

Rollup doesn't support them by default, it will warn as unknown directives while bundling. Preserving Code splitting strategy for the RSC boundaries are supported in bunchee as well, and you don't need to worry it at all. If there's any special code boundaries which are marked with "use client" or "use server", bunchee will bundle them into a separate chunk and preserve the top level directives. When they're bundled into Next.js app, they can be transformed correctly. No extra configuration needed.

Mission

This project is to simplify the bundling process for JavaScript libraries, since many times you need to think about configuring a lot of places to support CJS and ESM, also with TypeScript you might struggle with types resolution (.d.ts, .d.mts, .d.cts) that bunchee can still output them correctly.

We want to help developers focus on writing code, instead of thinking about how the code will be compiled and bundled, or the errors raised due to bad module resolution.

If you're not using bunchee yet, feel free to give it a try. Let me know if you're having any troubles or suggestions.