Bunchee

zero config bundler for ECMAScript and TypeScript packages

README

bunchee


zero config bundler for JavaScript/TypeScript/JSX library


bunchee

Bunchee makes bundling your library into one file effortless, with zero configuration required. It is built on top of Rollup and SWC ⚡️, allowing you to focus on writing code and generating multiple module types (CommonJS, ESModules) simultaneously.

Quick Start


Installation


  1. ```sh
  2. npm install --save-dev bunchee
  3. ```

Configuration


Create your library entry file and package.json.
  1. ```sh
  2. cd ./my-lib && mkdir src
  3. touch ./src/index.ts
  4. touch package.json
  5. ```

Then use use the exports field in package.json to configure different conditions and leverage the same functionality as other bundlers, such as webpack. The exports field allows you to define multiple conditions.
  1. ```json
  2. {
  3.   "exports": {
  4.     "import": "dist/index.mjs",
  5.     "require": "dist/index.cjs"
  6.   },
  7.   "scripts": {
  8.     "build": "bunchee"
  9.   }
  10. }
  11. ```

If you want to use ESM package, change the type field in package.json to module, bunchee will change the output format to ESM.
  1. ```json
  2. {
  3.   "type": "module",
  4.   "exports": {
  5.     "import": "dist/index.mjs",
  6.     "require": "dist/index.cjs"
  7.   },
  8.   "scripts": {
  9.     "build": "bunchee"
  10.   }
  11. }
  12. ```

Now just run npm run build (or pnpm build / yarn build) if you're using these package managers, bunchee will find the entry files and build them.
The output format will based on the exports condition and also the file extension. Given an example:

- It's CommonJS for require and ESM for import based on the exports condition.
- It's CommonJS for .js and ESM for .mjs based on the extension regardless the exports condition. Then for export condition like "node" you could choose the format with your extension.

Usage


File Conventions


While exports field is becoming the standard of exporting in node.js, bunchee also supports to build multiple exports all in one command.

What you need to do is just add an entry file with the name ([name].[ext]) that matches the exported name from exports field in package.json. For instance:

- `/src/index.ts` will match `"."` export name or the if there's only one main export.- `/src/lite.ts` will match `"./lite"` export name.

The build script will be simplified to just bunchee in package.json without configure any input sources for each exports. Of course you can still specify other arguments as you need.

Assuming you have default export package as "." and subpath export "./lite" with different exports condition listed in package.json

  1. ```json
  2. {
  3.   "name": "example",
  4.   "scripts": {
  5.      "build": "bunchee"
  6.   },
  7.   "exports": {
  8.     "./lite": "./dist/lite.js"
  9.     ".": {
  10.       "import": "./dist/index.mjs",
  11.       "require": "./dist/index.cjs"
  12.    }
  13.   }
  14. }
  15. ```

Then you need to add two entry files index.ts and lite.ts in project root directory to match the export name "." and "./lite", bunchee will associate these entry files with export names then use them as input source and output paths information.

  1. ```
  2. - my-lib/
  3.   |- src/
  4.     |- lite.ts
  5.     |- index.ts
  6.   |- package.json
  7. ```

It will also look up for `index.` file under the directory having the name of the export path. For example, if you have `"./lite": "./dist/lite.js"` in exports field, then it will look up for `./lite/index.js` as the entry file as well.

Multiple Runtime


For exports condition like react-native, react-server and edge-light as they're special platforms, they could have different exports or different code conditions. In this case bunchee provides an override input source file convention if you want to build them as different code bundle.

For instance:

  1. ```json
  2. {
  3.   "exports": {
  4.     "react-server": "./dist/react-server.mjs",
  5.     "edge-light": "./dist/edge-light.mjs",
  6.     "import": "./dist/index.mjs"
  7.   }
  8. }
  9. ```

Executables


To build executable files with the bin field in package.json, bunchee requires you to create the bin directory under src directory. The source file matching will be same as the entry files convention.

For example:

  1. ```bash
  2. |- src/
  3.   |- bin/
  4.     |- index.ts
  5. ```

This will match the bin field in package.json as:

  1. ```json
  2. {
  3.   "bin": "./dist/bin.js"
  4. }
  5. ```

For multiple executable files, you can create multiple files under the bin directory.

  1. ```bash
  2. |- src/
  3.   |- bin/
  4.     |- foo.ts
  5.     |- bar.ts
  6. ```

This will match the bin field in package.json as:

  1. ```json
  2. {
  3.   "bin": {
  4.     "foo": "./dist/bin/a.js",
  5.     "bar": "./dist/bin/b.js"
  6.   }
  7. }
  8. ```

Note: For multiple bin files, the filename should match the key name in the bin field.



Server Components


bunchee supports to build server components and server actions with library directives like "use client" or "use server". It will generate the corresponding chunks for client and server that scope the client and server boundaries properly.
Then when the library is integrated to an app such as Next.js, app bundler can transform the client components and server actions correctly and maximum the benefits.

If you're using "use client" or "use server" in entry file, then it will be preserved on top and the dist file of that entry will become a client component.
If you're using "use client" or "use server" in a file that used as a dependency for an entry, then that file containing directives be split into a separate chunk and hoist the directives to the top of the chunk.

CLI


CLI Options


bunchee CLI provides few options to create different bundles or generating types.

- Output (`-o `): Specify output filename.- Format (`-f `): Set output format (default: `'esm'`).- External (`--external `): Specifying extra external dependencies, by default it is the list of `dependencies` and `peerDependencies` from `package.json`. Values are separate by comma.- Target (`--target `): Set ECMAScript target (default: `'es2015'`).- Runtime (`--runtime `): Set build runtime (default: `'browser'`).- Environment (`--env `): Define environment variables. (default: `NODE_ENV`, separate by comma)- Working Directory (`--cwd `): Set current working directory where containing `package.json`.
- Types (--dts): Generate TypeScript declaration files along with assets.
- Minify (-m): Compress output.
- Watch (-w): Watch for source file changes.

  1. ```sh
  2. cd <project-root-dir>

  3. # specifying input, output and format

  4. bunchee ./src/index.js -f cjs -o ./dist/bundle.js
  5. bunchee ./src/index.js -f esm -o ./dist/bundle.esm.js

  6. # build node.js library, or change target to es2019
  7. bunchee ./src/index.js --runtime node --target es2019
  8. ```

Specifying extra external dependencies


If you want to mark specific dependencies as external and not include them in the bundle, use the --external option followed by a comma-separated list of dependency names:

  1. ```sh
  2. bunchee --external=dependency1,dependency2,dependency3
  3. ```

Replace dependency1, dependency2, and dependency3 with the names of the dependencies you want to exclude from the bundle.

Bundling everything without external dependencies


To bundle your library without external dependencies, use the --no-external option:

  1. ```sh
  2. bunchee --no-external
  3. ```

This will include all dependencies within your output bundle.

Environment Variables


To pass environment variables to your bundled code, use the --env option followed by a comma-separated list of environment variable names:

  1. ```bash
  2. bunchee --env=ENV1,ENV2,ENV3
  3. ```

Replace ENV1, ENV2, and ENV3 with the names of the environment variables you want to include in your bundled code. These environment variables will be inlined during the bundling process.


You can use `index..` to override the input source file for specific export name. Or using `/index..` also works. Such as:

  1. ```
  2. |- src/
  3.   |- index/.ts
  4.   |- index.react-server.ts
  5.   |- index.edge-light.ts
  6. ```

This will match the export name "react-server" and "edge-light" then use the corresponding input source file to build the bundle.