An automatic library bundler powered by Rollup.js.
⚠️ Bundlib is under development, please file a new issue if you find any issue or bug, suggestions are welcome as well.
- Install
- Build
- Configuration
- Options
- Selective Options
- Using the CLI tool
- Using Bundlib programmatically
- Plugin Notes
- Features
npm install bundlib --save-dev # or for short: npm i bundlib -D
Bundlib will try to find your entry point file in the src
folder. You can manually set your entry points using the input
option.
To build a CommonJS Module
simply add a "main"
field to your package.json
pointing to the output file, see the configuration section for extra options.
To build a ES Module
add a "module"
field to your package.json
pointing to the output file, see the configuration section for extra options.
For IIFE
, AMD
or UMD
builds, add a "browser"
field to your package.json
. The default format is "umd"
but it can be changed to "iife"
or "amd"
using the format
option, see the configuration section for more info and extra options.
Bundlib will configure Rollup according to you package.json
data, see Advanced Configuration for more information.
The "main"
field will be used as your CommonJS module output, if not present, CommonJS Module build will be skipped. You can skip the build manually using the skip
option.
The "module"
field will be used as your ES Module output, if not present, ES Module build will be skipped. You can skip the build manually using the skip
option. "jsnext:main"
field will also be honored if "module"
field is not present, but it is recommended to use the "module"
field.
The "browser"
field will be used as your Browser build output, if not present, Browser build will be skipped. You can skip the build manually using the skip
option. Bundlib only supports string
type "browser"
field, it will throw otherwise.
The "bin"
field will be used as your Binary build output, if not present, Binary build will be skipped. You can skip the build manually using the skip
option. Bundlib only supports string
type "bin"
field, it will throw otherwise.
The "types"
field will be used as your Types output if you are using typescript
. You can skip types generation using the skip
option. "typings"
field will also be honored if "types"
field is not present.
The "dependencies"
field will be used to detect installed packages, it will also be used to set external dependencies for your CommonJS module, ES module, and Binary builds, for Browser build dependencies will be bundled into the output file unless otherwise specified using the globals
option.
The "devDependencies"
field will be used to detect installed packages.
The "peerDependencies"
field will be used as external dependencies for your CommonJS module,, ES module, and Binary builds.
The "bundlib"
field can be used for advanced configuration, see Advanced Configuration for more information.
Advanced configuration can be done using the "bundlib"
field in your package.json
or by using one of the supported configuration files.
Set "bundlib"
field in your package.json
to an object
with your configuration. See options for more information.
example
// package.json
{
"name": "my-lib",
"version": "1.0.0",
"browser" : "dist/my-lib.amd.js",
"bundlib": {
"format": "amd"
}
...
}
You can also set "bundlib"
field in package.json
to a string
as a path, relative to the project root, pointing to a .json
, .yaml
, .yml
, .js
, .cjs
, .mjs
or .ts
, or json
or yaml
format file without extension containing the configuration.
example
// package.json
{
"name": "my-lib",
"version": "1.0.0",
"browser" : "dist/my-lib.amd.js",
"bundlib": "options.yml"
// ...
}
then...
# options.yaml
format: amd
If "bundlib"
field not present in your package.json
, Bundlib will try to find your configuration file using the following order...
- .bundlibrc (json or yaml format)
- .bundlibrc.json
- .bundlibrc.yaml
- .bundlibrc.yml
- .bundlibrc.js
- bundlib.config.js
- bundlib.config.cjs
- bundlib.config.mjs
- bundlib.config.ts
See the list of options below.
The option object may contain any of the following properties. Any invalid or unknown option will cause Bundlib to throw at build time. Any option or sub-option set to null
will be ignored.
The path to the files to be used as entry points for each of your builds. This option supports value based selective format
.
input: SelectiveStringOption;
Whether or not to generate source maps. Valid values are boolean
, "inline"
and "hidden"
. The default value is true
if you don't provide this option. See Rollup documentation for more information.
This option supports value based and boolean based selective format.
sourcemap: SelectiveSourcemapOption;
default true;
Whether or not to add a __esModule: true
property to your module. Valid values are boolean
and "if-default-prop"
. The default value is false
if you don't provide this option.
This option supports value based and boolean based selective format.
esModule: SelectiveEsModuleOption;
default false;
Whether or not to add an interop block. Valid values are boolean
, "default"
, "esModule"
, "compat"
, "auto"
and "defaultOnly"
. Rollup doesn't support interop
option as a boolean
anymore, we still support it by turning true
into "compat"
and false
into "default"
before we pass it to Rollup. The default value is "default"
if you don't provide this option.
This option supports value based and boolean based selective format.
interop: SelectiveInteropOption;
default "default";
A map of chunks to be built as CommonJS
modules. The object key
represents the input file and the value
represents the output file, relative to the project root. Files created using this option won't be bundled into the CommonJS
and Binary
builds and will be imported (required) instead.
chunks: Record<string, string>;
Defines the format to be used for the Browser
build.
format: 'iife' | 'amd' | 'umd';
default 'umd';
The name to be used to expose your library to the global scope in a IIFE
or UMD
browser build. If not provided it will default to the camelcased, unscoped "name"
field in package.json
or the camelcased directory name. If none of those can be obtained, it will throw at build time.
name: string;
id: string;
Optional amd id for AMD
or UMD
build.
If not present, AMD
define
method will use no id.
Whether or not to extend the globally exposed name on a IIFE
or UMD
build.
extend: boolean;
default false;
Object
or array
to map names to globals in Browser
build.
globals: { [name: string]: string } | string[];
default {};
Defines which files should be used to build an additional minified version, if true
will affect all modules. The minified file will be renamed from *.ext
to *.min.ext
. This option will override the default behavior of the --dev
, -d
cli option , which means only the minified version will be actually minified, the normal version will NOT be minified even if you don't set the --dev
, -d
cli option. This option supports boolean based selective format.
min: SelectiveMinOption;
default false;
See SelectiveMinOption
.
Transforms type export for CommonJS module using export = ...
instead of export default ...
.
⚠️ Note that this option should only be used when your library has adefault
export and nonamed
exports, otherwise it may cause the type declarations to become invalid.
equals: boolean;
default false;
Defines the directory to be used for cache, relative to the project root.
cache: string;
default "node_modules/.cache/bundlib";
Defines the location of typescript tsconfig.json
file, relative to the project root. This option supports value based selective format.
project: SelectiveStringOption;
default "tsconfig.json"
Defined which build Bundlib should skip. This option supports boolean based selective format.
min: SelectiveSkipOption;
default false;
See SelectiveSkipOption
.
Some options support a selective
format to allow for a more flexible configuration.
See Selective Types section for more information.
Note that some options support different selective formats. Boolean
type options support boolean
based format which is an extension of value
based format, while others support only value
based format.
See input
option, sourcemap
option, esModule
option, interop
option, min
option and project
option.
The value
based selective format allows you to enter a value
or an object
to set independent values.
const value: SelectiveValueBasedOption<BuildType, string> = 'some-string';
const value: SelectiveValueBasedOption<BuildType, string> = 'some-other-string';
const value: SelectiveValueBasedOption<BuildType, string> = null;
const value: SelectiveValueBasedOption<BuildType, string> = undefined;
const value: SelectiveValueBasedOption<BuildType, string> = () => 'some-string';
const value: SelectiveValueBasedOption<BuildType, string> = (key) => {
return key === 'module' ? 'module-value' : 'other-value';
};
const value: SelectiveValueBasedOption<BuildType, string> = { main: 'main-value' };
const value: SelectiveValueBasedOption<BuildType, string> = { module: 'module-value' };
You can override the default value as well using the default
object key.
const value: SelectiveValueBasedOption<BuildType, string> = {
default: 'default',
main: 'string',
};
const value: SelectiveValueBasedOption<BuildType, string> = {
default: 'default',
module: 'module',
};
The api
object key represents main
, module
and browser
.
const value: SelectiveValueBasedOption<BuildType, string> = {
api: 'string',
};
The boolean
based selective format is an extension of the a value
based selective format, except boolean
can be used as a value as well, and it allows keys
in the positive
or negative
format in addition to what value
based selective format normally accepts.
You can set it to a boolean
value.
const value: SelectiveBoolBasedOption<BuildType, never> = true;
const value: SelectiveBoolBasedOption<BuildType, never> = false;
You can set it to any of the valid keys, in the positive
format (ex: main
or +main
) or negative
format (ex: !main
or -main
). Valid keys are usually: main
, module
, browser
and bin
except for SelectiveSkipOption
which also accepts types
as key. It will also accepts the special api
key.
const value: SelectiveBoolBasedOption<BuildType, never> = 'main';
const value: SelectiveBoolBasedOption<BuildType, never> = 'api';
const value: SelectiveBoolBasedOption<BuildType, never> = '!api';
Any key that can be used as as single key
, can be as well used in an array. The first key sets the default state for the result, and the additional keys extend that initial state.
const value: SelectiveBoolBasedOption<BuildType, never> = ['main', 'module'];
const value: SelectiveBoolBasedOption<BuildType, never> = ['!browser', '!main'];
The api
special keys sets (or removes) main
, module
and browser
at the same time.
const value: SelectiveBoolBasedOption<BuildType, never> = 'api';
const value: SelectiveBoolBasedOption<BuildType, never> = ['api', '!browser'];
The boolean
based selective format is an extension of the value
based one. It accepts values as boolean
and objects containing boolean
values, in addition to what a value
based selective format normally accepts.
const value: SelectiveBoolBasedOption<BuildType, 'text'> = true;
const value: SelectiveBoolBasedOption<BuildType, 'text'> = { default: false, main: 'text' };
bundlib [options] [command]
Combine options according to your needs. Run bundlib --help
or bundlib -h
for a detailed help.
Create development, not minified builds. Builds affected by the min
option will ignore this option.
Prevent messages from showing in the console.
Show Bundlib version.
Show detailed help about the CLI tool.
Build your library for production
Runs Bundlib in watch mode
Bundlib exposes some function
and types
you can import
example
// rollup.config.js
import { configsFromPkg } from 'bundlib';
const dev = !process.env.production;
export default configsFromPkg(
process.cwd(),
{ dev },
);
An All-in-one function combining readPkg
, analyzePkg
and pkgToConfigs
. Just pass the directory where package.json
is located, and it will return an array of Rollup configuration objects.
- Syntax
async function bundlib(
cwd: string,
options?: BundlibAPIOptions | null | undefined,
): Promise<Array<rollup.RollupOptions>>;
arguments
cwd
: A string representing the path wherepackage.json
is located.options
: Some options to be passed topkgToConfigs
function.
return
: An array of Rollup configs.
Reads the content of package.json
and returns it. It will throw a TypeError
if package.json
content is not an object
.
- Syntax
async function readPkg(cwd: string): Promise<PkgJson>;
arguments
cwd
: A string representing the path wherepackage.json
is located.
return
: APromise
which resolves topackage.json
content.
Analyzes package.json
content, resolve bundlib configuration
and it turns it into more useful information about the build.
- Syntax
async function analyzePkg(
cwd: string,
pkg: PkgJson,
): Promise<PkgAnalyzed>;
arguments
cwd
: A string representing the path where configuration file should be located.pkg
: The content ofpackage.json
.
return
: APromise
which resolves to information and tools, useful to configure rollup.
If
pkg
not provided it will readpackage.json
from the current working directorycwd
. But this behavior will be removed in the future. So, to avoid problems in the future, please passpkg
See PkgAnalyzed
.
Takes a PkgAnalyzed
object an turns it into an array of config objects, ready to be used by Rollup.
- Syntax
function pkgToConfigs(
analyzed: PkgAnalyzed,
options?: BundlibAPIOptions | null | undefined,
): Array<rollup.RollupOptions>;
arguments
analyzed
: ThePkgAnalyzed
returned byanalyzePkg
function.options
: Some options which define some configurations.
return
: An array of Rollup configs.
See PkgAnalyzed
and BundlibAPIOptions
.
Creates an array of rollup config object, based on the content of package.json
and bundlib configuration file. It is a combination of readPkg
, analyzePkg
and pkgToConfigs
functions. It is exported as a way to "do it all in one step", but you can use the independent functions to have a bit mor control over the process.
async function configsFromPkg(
cwd: string,
options?: BundlibAPIOptions | null | undefined,
pkg: PkgJson = read(cwd + '/package.json'),
): Promise<Array<rollup.RollupOptions>>;
arguments
cwd
: A string representing the path wherepackage.json
and configuration file should be located.options
: An object with options to create the configs.pkg
: The content ofpackage.json
.
return
: APromise
which resolves to information and tools, useful to configure rollup.
If pkg
not provided it will be read from the current working directory cwd
.
A function that returns it's only argument. It helps to have code completion and type check when using javascript config file. See example.
function config(config: BundlibConfig): BundlibConfig;
- Example
First the "normal" way...
// bundlib.config.js
export default {
input: 'src/index.js',
interop: true,
// ... the rest of your config here
};
... You can improve your experience by using this helper function... when using vscode, for example, it will type check and autocomplete your config file while you type.
import { config } from 'bundlib';
export default config({
input: 'src/index.js',
interop: true,
// ... the rest of your config here
});
This are som of the types exported but bundlib.
interface BundlibConfig {
readonly input?: SelectiveStringOption;
readonly sourcemap?: SelectiveSourcemapOption;
readonly esModule?: SelectiveEsModuleOption;
readonly interop?: SelectiveInteropOption;
readonly cache?: string | null;
readonly chunks?: Record<string, string> | null;
readonly format?: 'amd' | 'iife' | 'umd' | null;
readonly name?: string | null;
readonly id?: string | null;
readonly extend?: boolean | null;
readonly globals?: Record<string, string> | string[] | null;
readonly equals?: boolean | null;
readonly min?: SelectiveMinOption;
readonly skip?: SelectiveSkipOption;
readonly project?: SelectiveStringOption;
}
See options input
, sourcemap
, esModule
, interop
, cache
, chunks
, format
, name
, id
, extend
, globals
, equals
, min
, skip
and project
, and types SelectiveStringOption
, SelectiveSourcemapOption
, SelectiveEsModuleOption
, SelectiveInteropOption
, SelectiveMinOption
and SelectiveSkipOption
.
interface PkgAnalyzed {
cwd: string;
pkg: PkgJson;
main: ModuleBuildOptions | null;
module: ModuleBuildOptions | null;
browser: BrowserBuildOptions | null;
bin: ModuleBuildOptions | null;
types: TypesBuildOptions | null;
chunks: Record<string, string> | null;
dependencies: {
runtime: PkgJsonDependencies | null;
dev: PkgJsonDependencies | null;
peer: PkgJsonDependencies | null;
};
cache: string | null;
isInstalled: (id: string) => string | undefined;
installed: {
babel: { id: '@babel/core'; version: string } | null;
eslint: { id: 'eslint'; version: string } | null;
chokidar: { id: 'chokidar'; version: string } | null;
typescript: { id: 'typescript'; version: string } | null;
};
}
See ModuleBuildOptions
, BrowserBuildOptions
and TypesBuildOptions
interface ModuleBuildOptions {
input: string | null;
output: string;
sourcemap: boolean | 'inline' | 'hidden';
esModule: boolean | 'if-default-prop';
interop: boolean | 'compat' | 'auto' | 'esModule' | 'default' | 'defaultOnly';
min: boolean;
project: string | null;
}
interface BrowserBuildOptions extends ModuleBuildOptions {
format: 'iife' | 'amd' | 'umd';
name: string | null;
id: string | null;
globals: Record<string, string> | null;
extend: boolean;
}
See ModuleBuildOptions
.
interface TypesBuildOptions {
output: string;
equals: boolean;
}
export interface BundlibAPIOptions {
dev?: boolean;
watch?: boolean;
onwarn?: rollup.WarningHandlerWithDefault;
}
type SelectiveValueBasedOption<K extends string, V> = ValueBasedSelectiveOption<K, 'api' | 'default', V>;
See ValueBasedSelectiveOption
on selective-option module.
type SelectiveBoolBasedOption<K extends string, V> = BoolBasedSelectiveOption<K, 'api', V, 'default'>;
See BoolBasedSelectiveOption
on selective-option module.
type BuildType = 'main' | 'module' | 'browser' | 'bin';
type SelectiveStringOption = SelectiveValueBasedOption<BuildType, string>;
See SelectiveValueBasedOption
and BuildType
.
type SelectiveSourcemapOption = SelectiveBoolBasedOption<BuildType, 'inline' | 'hidden'>;
See SelectiveBoolBasedOption
and BuildType
.
type SelectiveEsModuleOption = SelectiveBoolBasedOption<BuildType, 'if-default-prop'>;
See SelectiveBoolBasedOption
and BuildType
.
type SelectiveInteropOption = SelectiveBoolBasedOption<BuildType, 'default' | 'esModule' | 'compat' | 'auto' | 'defaultOnly'>;
See SelectiveBoolBasedOption
and BuildType
.
type SelectiveMinOption = SelectiveBoolBasedOption<BuildType, never>;
See SelectiveBoolBasedOption
and BuildType
type SelectiveSkipBuildType = BuildType | 'types';
type SelectiveSkipOption = SelectiveBoolBasedOption<SelectiveSkipBuildType, never>;
See SelectiveBoolBasedOption
and BuildType
Because @rollup/plugin-eslint
uses it's own version of eslint
(maybe not the same version you are using in your project), you may need to use the "overrides"
property of your package.json
to ensure @rollup/plugin-eslint
uses the same version you are using inside your project.
{
"devDependencies": {
"eslint": "^9.10.0"
},
"overrides": {
"eslint": "^9.10.0"
}
}
Some values from your tsconfig.json
file "compilerOptions"
will be ignored or overridden by Bundlib
.
"module"
option will be set to "ESNext"
.
"sourceMap"
option will be set according to your sourcemap
option or it's default value.
"declaration"
and "declarationDir"
will be set according to your settings, trying to ensure it follows your package.json
and configuration. "declarationMap"
will be set to true
if your declaration files are being emitted.
- Uses
"main"
field in yourpackage.json
to build aCommonJS Module
. - Uses
"module"
field in yourpackage.json
(or"jsnext:main"
field) to build anES Module
. - Uses
"browser"
field in yourpackage.json
to build aBrowser
module. It only supports"browser"
field asstring
,object
format not supported. - Uses
"bin"
field in yourpackage.json
to build aBinary
module. It only supports"bin"
field asstring
,object
format not supported. - Uses
"types"
field in yourpackage.json
(or"typings"
field) as path for types declarations. - Uses
"dependencies"
and"peerDependencies"
to set external modules forCommonJS Module
,ES Module
andBinary
builds. Dependencies will be bundled by default inBrowser
builds, unless otherwise specified using theglobal
option. - Skip any build based on options.
- Uses
rollup-plugin-typescript2
iftypescript
installed as runtime or dev dependency. - Uses
@rollup/plugin-babel
if@babel/core
installed as runtime or dev dependency, otherwise it uses@rollup/plugin-buble
. - Uses
rollup-plugin-strip-shebang
androllup-plugin-add-shebang
to ensure a shebang on binary build. - Uses
@rollup/plugin-json
to import JSON files. - Uses
@rollup/plugin-eslint
ifeslint
installed as runtime or dev dependency. - Uses
@rollup/plugin-terser
to minify production build. - Uses
chokidar
for file watch if installed.
- Honor
"type"
field inpackage.json
- Honor
"exports"
field inpackage.json
- Support
package.json
"bin"
field as an object for multiple cli commands
- Type declarations for chunks created using the
chunks
option may not work properly.
MIT © 2019-2024 Manuel Fernández