Zero-Config JS/TS Bundler

bunchee

I was trying to build a convenient bundler for my colleagues who are working on a javascript library. They were asking me for suggestions of bundling practice. I was about to recommend them some bundler tools from community. For non-JS developers, understanding various standard of javascript module standards (umd/esm/cjs/amd/etc.) can be painful. Thus I thought why not just build one.

Those small crews are separated into different teams who are maintaining or building JS libs, with their own domain knowledge for specific purposes such as video bitrate tunning or stream downloading. Different practices were adopted before in the legacy projects, I want to align them to make developers and researchers concentrated on their own focus, implementing algorithms instead of figuring out the compiling/bundling things.

Pick Modern Syntax Set

Only few of the legacy projects are still using ES3 to implement modern features like classes, and non of the projects are trying any unstable syntaxes like decorators. So I decided to pick the stable ones as fundamental supported syntax set, mostly are after tc39 stage 4 and implemented by latest browsers. Still excludes the ones with controversy, Yes, like decorators.

After reading Lea's post I do believe confirmedly that zero-configuration is the right way to go.

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, and left rest of the assets processing to webpack on application level.

About Compiler: I was worrying the install size of babel tool chains, bublejs was my first choice in advantage of lightweight lib size. It's still built with acornjs, but the support is kind of narrow due to limited target on compiling ES6. After few weeks of experimentation, limited support on async/await and generators let me finally give up bublejs and choose to babel again.

The growth of typescript is insane, at last I decided to make it support typescript as well. This brings me convenience of building my own ts libraries.

Usage

On the usage of bundler, thanks to microbundle for leveraging the nice contract on package.json level, that let user use fields like "main" / "module" to specify the module types and generate output assets path. Love this idea so much 'cause it's easier than exports sugar for non-JS developers to learn.

The module field is now widely supported across module bundlers like (rollup, webpack, etc.).

{
  "main": "dist/pkg.cjs.js",
  "module": "dist/pkg.esm.js",
  "scripts": {
    "build": "bunchee ./src/index.js"
  }
}

bunchee doesn't support any other module fields besides "main" and "module", e.g. it doesn't support "browser" field. I do feel "browser" is a complicated one and most of cases CommonJS and ESModule are enough for a small library. Prefer to exports as esm only due to its advantage on optimizing static modules with treeshaking technology and it's the next generation of module definition.

When you use CLI to generate output, UMD format is also supported, giving user flexibility to created browser runnable assets. Usually UMD format is not an idea format to adopt if the lib can be consumed by other lib as an underlayer one.

You can also choose to minify it or not, generate sourcemap or not. The full introduction are defined here.

Comparison

There are also some zero-config bundlers in the community, like parcel for building apps, ncc for bundling single nodejs file, tsdx for building ts lib, microbundle for building regular js/ts library.

Microbundle has the most similar objective and I did learn a lot from it. The said thing is some concern cases are not supported on microbundle side: like apply esmodule interop to cjs assets. I understand the intention was good to make cjs assets pure and not mixed with esm standard, but it will cause few issues when cjs assets are consumed by esm usage import.

bunchee is kind of lightweight and simple, but fit for most of our cases.

Self Host

I found @vercel/ncc is compiled by itself which is super interesting. I spent sometime to divided bunchee into core lib and CLI two parts, finally accomplished the self-host functionality of bunchee.

That's it, welcome to use bunchee!

npm install -D bunchee