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.
Array<string>
packages
is an array of globs which specify which packages should be built with preconstruct.
Note: this is the default value, if it's what you want, you don't need to specify it.
{
"preconstruct": {
"packages": ["."]
}
}
{
"preconstruct": {
"packages": ["packages/*"]
}
}
{ [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.
Note: this is the default value, if it's what you want, you don't need to specify it.
{
"preconstruct": {
"globals": {}
}
}
{
"preconstruct": {
"globals": {
"react": "React",
"react-dom": "ReactDOM"
}
}
}
"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
Entrypoint | full |
unscoped-package-name |
---|---|---|
pkg |
dist/pkg.cjs.js |
dist/pkg.cjs.js |
pkg/entrypoint |
dist/pkg-entrypoint.cjs.js |
dist/pkg.cjs.js |
@scope/pkg |
dist/scope-pkg.cjs.js |
dist/pkg.cjs.js |
@scope/pkg/entrypoint |
dist/scope-pkg-entrypoint.cjs.js |
dist/pkg.cjs.js |
Note: this is the default value, if it's what you want, you don't need to specify it.
{
"preconstruct": {
"distFilenameStrategy": "full"
}
}
{
"preconstruct": {
"distFilenameStrategy": "unscoped-package-name"
}
}
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.
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
.
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}"]
}
}
{
"preconstruct": {
"entrypoints": ["index.js", "other.js"]
}
}
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 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.
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.
The module
field specifies an ES Module build. This bundle is what bundlers like webpack will use.
Example:
{
"module": "dist/my-package.esm.js"
}
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"
}
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.
The worker
field specifies alias files exclusive to DOM-less javascript environments like CloudFlare Workers. This allows you to create different bundles from your source code based on typeof window
and typeof document
and typeof process
checks - thanks to that you can, for example, remove broser-only or Node.js-only code (just for those bundles).
Note: Those files are not meant to be consumed by workers "as is". They just assume worker-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.