NOTE This is a fork of microbundle into which I am merging Travis Fischer's microbundle-crl, to work out what has changed in his version, and to see if I can merge his changes nicely into the main microbundle repo.
(Travis Fischer): this is a custom fork of microbundle which focuses on React for create-react-library which adds a few nice-to-have features:
- Changes the default
jsx
option toReact.createElement
rollup-plugin-smart-asset
- smart bundling of imported image assets@babel/plugin-proposal-decorators
- add support for legacy decorators - very convenient for mobx@babel/plugin-proposal-optional-chaining
- adds?.
syntax support
The zero-configuration bundler for tiny modules, powered by Rollup.
Guide β Setup β― Formats β― Modern Mode β― Usage & Configuration β― All Options
- One dependency to bundle your library using only a
package.json
- Support for ESnext & async/await (via Babel & async-to-promises)
- Produces tiny, optimized code for all inputs
- Supports multiple entry modules (
cli.js
+index.js
, etc) - Creates multiple output formats for each entry (CJS, UMD & ESM)
- 0 configuration TypeScript support
- Built-in Terser compression & gzipped bundle size tracking
1οΈβ£ Install by running: npm i -D microbundle
npm i -D microbundle-crl
{
"name": "foo", // your package name
"source": "src/foo.js", // your source code
"main": "dist/foo.js", // where to generate the CommonJS/Node bundle
"module": "dist/foo.module.js", // where to generate the ESM bundle
"unpkg": "dist/foo.umd.js", // where to generate the UMD bundle (also aliased as "umd:main")
"scripts": {
"build": "microbundle", // compiles "source" to "main"/"module"/"unpkg"
"dev": "microbundle watch" // re-build when source files change
}
}
3οΈβ£ Try it out by running npm run build
.
Microbundle produces esm
, cjs
, umd
bundles with your code compiled to syntax that works pretty much everywhere. While it's possible to customize the browser or Node versions you wish to support using a browserslist configuration, the default setting is optimal and strongly recommended.
In addition to the above formats, Microbundle also outputs a modern
bundle specially designed to work in all modern browsers. This bundle preserves most modern JS features when compiling your code, but ensures the result runs in 90% of web browsers without needing to be transpiled. Specifically, it uses preset-modules to target the set of browsers that support <script type="module">
- that allows syntax like async/await, tagged templates, arrow functions, destructured and rest parameters, etc. The result is generally smaller and faster to execute than the esm
bundle:
// Our source, "src/make-dom.js":
export default async function makeDom(tag, props, children) {
let el = document.createElement(tag);
el.append(...(await children));
return Object.assign(el, props);
}
Compiling the above using Microbundle produces the following modern
and esm
bundles:
make-dom.modern.js (123b) |
make-dom.module.js (166b) |
---|---|
export default async function(e, t, a) {
let n = document.createElement(e);
n.append(...(await a));
return Object.assign(n, t);
} |
export default function(e, t, r) {
try {
var n = document.createElement(e);
return Promise.resolve(r).then(function(e) {
n.append.apply(n, e);
return Object.assign(n, t);
});
} catch (e) {
return Promise.reject(e);
}
} |
This is enabled by default - all you have to do is add the field to your package.json
.
πββοΈ How to point to modern code in a package.json is being discussed. You might use the "module" field.
{
"main": "dist/foo.umd.js", // legacy UMD bundle (for Node & CDN use)
"module": "dist/foo.modern.module.js", // modern ES2017 bundle
"scripts": {
"build": "microbundle src/foo.js -f modern,umd"
}
}
Microbundle includes two commands - build
(the default) and watch
. Neither require any options, but you can tailor things to suit your needs a bit if you like.
Unless overridden via the command line, microbundle uses the source
property in your package.json
to locate the input file, and the main
property for the output:
{
"source": "src/index.js", // input
"main": "dist/my-library.js", // output
"scripts": {
"build": "microbundle"
}
}
For UMD builds, microbundle will use a camelCase version of the name
field in your package.json
as export name. This can be customized using an "amdName"
key in your package.json
or the --name
command line argument.
Acts just like microbundle build
, but watches your source files and rebuilds on any change.
Just point the input to a .ts
file through either the cli or the source
key in your package.json
and youβre done.
Microbundle will generally respect your TypeScript config defined in a tsconfig.json
file with notable exceptions being the "target" and "module" settings. To ensure your TypeScript configuration matches the configuration that Microbundle uses internally it's strongly recommended that you set "module": "ESNext"
and "target": "ESNext"
in your tsconfig.json
.
By default any css file imported as .module.css
, will be treated as a css-module. If you wish to treat all .css
imports as a module, specify the cli flag --css-modules true
. If you wish to disable all css-module behaviours set the
flag to false
.
The default scope name when css-modules is turned on will be, in watch mode _[name]__[local]__[hash:base64:5]
and when
you build _[hash:base64:5]
. This can be overriden by specifying the flag, eg
--css-modules "_something_[hash:base64:7]"
. Note: by setting this, it will be treated as a true, and thus, all .css
imports will be scoped.
flag | import | is css module? |
---|---|---|
null | import './my-file.css'; | β |
null | import './my-file.module.css'; | β |
false | import './my-file.css'; | β |
false | import './my-file.module.css'; | β |
true | import './my-file.css'; | β |
true | import './my-file.module.css'; | β |
Microbundle uses the fields from your package.json
to figure out where it should place each generated bundle:
{
"main": "dist/foo.js", // CommonJS bundle
"umd:main": "dist/foo.umd.js", // UMD bundle
"module": "dist/foo.m.js", // ES Modules bundle
"esmodule": "dist/foo.modern.js", // Modern bundle
"types": "dist/foo.d.ts" // TypeScript typings directory
}
By default Microbundle outputs multiple bundles, one bundle per format. A single bundle with a fixed output name can be built like this:
microbundle -i lib/main.js -o dist/bundle.js --no-pkg-main -f umd
To achieve the smallest possible bundle size, libraries often wish to rename internal object properties or class members to smaller names - transforming this._internalIdValue
to this._i
. Microbundle doesn't do this by default, however it can be enabled by creating a mangle.json
file (or a "mangle"
property in your package.json). Within that file, you can specify a regular expression pattern to control which properties should be mangled. For example: to mangle all property names beginning an underscore:
{
"mangle": {
"regex": "^_"
}
}
It's also possible to configure repeatable short names for each mangled property, so that every build of your library has the same output. See the wiki for a complete guide to property mangling in Microbundle.
Usage
$ microbundle <command> [options]
Available Commands
build Build once and exit
watch Rebuilds on any change
For more info, run any command with the `--help` flag
$ microbundle build --help
$ microbundle watch --help
Options
-v, --version Displays current version
-i, --entry Entry module(s)
-o, --output Directory to place build files into
-f, --format Only build specified formats (any of modern,es,cjs,umd or iife) (default modern,es,cjs,umd)
-w, --watch Rebuilds on any change (default false)
--pkg-main Outputs files analog to package.json main entries (default true)
--target Specify your target environment (node or web) (default web)
--external Specify external dependencies, or 'none' (default peerDependencies and dependencies in package.json)
--globals Specify globals dependencies, or 'none'
--define Replace constants with hard-coded values
--alias Map imports to different modules
--compress Compress output using Terser
--no-compress Disable output compressing
--strict Enforce undefined global context and add "use strict"
--name Specify name exposed in UMD and IIFE builds
--cwd Use an alternative working directory (default .)
--sourcemap Generate source map (default true)
--raw Show raw byte size (default false)
--jsx A custom JSX pragma like React.createElement (default: h)
--jsxImportSource Specify the automatic import source for JSX like preact
--tsconfig Specify the path to a custom tsconfig.json
--css-modules Configures .css to be treated as modules (default: null)
-h, --help Displays this message
Examples
$ microbundle build --globals react=React,jquery=$
$ microbundle build --define API_KEY=1234
$ microbundle build --alias react=preact/compat
$ microbundle watch --no-sourcemap # don't generate sourcemaps
$ microbundle build --tsconfig tsconfig.build.json
Here's what's coming up for Microbundle:
- Preact Fast 3kB React alternative with the same modern API. Components & Virtual DOM.
- Stockroom Offload your store management to a worker easily.
- Microenvi Bundle, serve, and hot reload with one command.
- Theme UI Build consistent, themeable React apps based on constraint-based design principles.
- react-recomponent Reason-style reducer components for React using ES6 classes.
- brazilian-utils Utils library for specific Brazilian businesses.
- react-hooks-lib A set of reusable react hooks.
- mdx-deck-live-code A library for mdx-deck to do live React and JS coding directly in slides.
- react-router-ext An Extended react-router-dom with simple usage.
- routex.js A dynamic routing library for Next.js.
- hooked-form A lightweight form-management library for React.
- goober Less than 1KB css-in-js alternative with a familiar API.
- react-model The next generation state management library for React