🎁

preconstruct

GitHub

Configuration

Preconstruct accepts configuration at three different configuration points; projects, packages and entrypoints. These configuration points can be represented by one package.json or by 20 package.jsons, it depends on the requirements of a specific project. For example, in a single package repo with one entrypoint, it would be represented by a single package.json.

Projects map 1:1 with a version control repository. They specify global configuration that applies to all builds.

Projects

packages

Array<string>

packages is an array of globs which specify which packages should be built with preconstruct.

Default

Note: this is the default value, if it's what you want, you don't need to specify it.

{
"preconstruct": {
"packages": ["."]
}
}

Example

{
"preconstruct": {
"packages": ["packages/*"]
}
}

globals

{ [packageName: string]: (umdName: string) }

globals specifies the UMD names of peerDependencies since peerDependencies aren't bundled in UMD builds. You shouldn't specify this option manually, preconstruct will prompt you for the UMD name of a package when it's necessary.

Default

Note: this is the default value, if it's what you want, you don't need to specify it.

{
"preconstruct": {
"globals": {}
}
}

Example

{
"preconstruct": {
"globals": {
"react": "React",
"react-dom": "ReactDOM"
}
}
}

distFilenameStrategy

"full" | "unscoped-package-name"

distFilenameStrategy specifies, you should probably use full(which is the default) unless you need to have filenames (likely if you have UMD builds whose filename you don't want to change) in which case, you should use unscoped-package-name

Entrypointfullunscoped-package-name
pkgdist/pkg.cjs.jsdist/pkg.cjs.js
pkg/entrypointdist/pkg-entrypoint.cjs.jsdist/pkg.cjs.js
@scope/pkgdist/scope-pkg.cjs.jsdist/pkg.cjs.js
@scope/pkg/entrypointdist/scope-pkg-entrypoint.cjs.jsdist/pkg.cjs.js

Default

Note: this is the default value, if it's what you want, you don't need to specify it.

{
"preconstruct": {
"distFilenameStrategy": "full"
}
}

Example

{
"preconstruct": {
"distFilenameStrategy": "unscoped-package-name"
}
}

Packages

Packages map 1:1 with npm packages. Along with specifying the entrypoints option described below, packages are also responsible for specifying dependencies which is necessary for bundling UMD bundles and ensuring that packages will have all of their required dependencies when installed through npm.

entrypoints

Array<string>

entrypoints is an array of globs which specify the entrypoints which consumers of your package should be able to import. They are resolved relative to the src directory of the package. To get the entrypoint directory from a source file, the extension is removed from the path relative to the src directory and if the last part is index, the index part is removed. For example, an entrypoint of something.js would create an entrypoint at pkg-name/something and another/index.js would create an entrypoint at pkg-name/another.

Default

Note: this is the default value, if it's what you want, you don't need to specify it.

{
"preconstruct": {
"entrypoints": ["index.{js,jsx,ts,tsx}"]
}
}

Example

{
"preconstruct": {
"entrypoints": ["index.js", "other.js"]
}
}

Entrypoints

Entrypoints are the lowest level configuration point and describe a set of bundles for a particular entrypoint. They are configured by the package.json in the folder of the entrypoint. We also have a guide on adding a second entrypoint

Build types

Build types specify what types of bundles Preconstruct should build. They are specified via the package.json fields which Node and bundlers like webpack look at to find bundles. It's important to note that all of the entrypoints in a package must have the same build types, this is necessary to ensure that common dependencies between entrypoints aren't duplicated.

main

The main field specifies a CommonJS build. It is the only build type which is required. This bundle will work in Node and can work in bundlers like webpack but a ES Module build is recommended for bundlers like webpack.

Example:

{
"main": "dist/my-package.cjs.js"
}

Note: This file actually just reexports either a production or a development bundle (respectively dist/my-package.cjs.prod.js or dist/my-package.cjs.dev.js in this example) based on the process.env.NODE_ENV value. This allows you to use process.env.NODE_ENV checks in your code so 2 distinct bundles are created but at runtime only one of them gets loaded.

module

The module field specifies an ES Module build. This bundle is what bundlers like webpack will use.

Example:

{
"module": "dist/my-package.esm.js"
}

umd:main

The umd:main field specifies a UMD build. This bundle can be used directly in a browser with a <script> tag.

Example:

{
"umd:main": "dist/my-package.umd.min.js"
}

browser

The browser field specifies alias files exclusive to browsers. This allows you to create different bundles from your source code based on typeof window and typeof document checks - thanks to that you can, for example, remove server-only code (just for those bundles).

Note: Those files are not meant to be consumed by browsers "as is". They just assume browser-like environment, but they still can contain for example references to process.env.NODE_ENV as that is meant to be replaced by a consuming bundler.