Skip to main content

Build

Packemon was primarily designed and engineered for building packages. But what is building you ask? Building is the process of parsing, transforming, and bundling a package's source code into distributable and consumable files for npm, using community favorite tools like Babel and Rollup.

With that being said, the build command can be used to build all packages in a project according to their configured build targets (platform, formats, etc).

package.json
{    "scripts": {        "build": "packemon build --addEngines"    }}

Options#

Build supports the following command line options.

  • --addEngines - Add Node.js and npm engine versions to each package.json when platform is node. Uses the support setting to determine the version range.
  • --addExports - Add exports fields to each package.json according to the respective inputs setting. This is an experimental Node.js feature and may not work correctly (more information).
  • --analyze - Analyze and visualize all generated builds. Will open a browser visualization for each bundle in one of the following formats.
    • sunburst - Displays an inner circle surrounded by rings of deeper hierarchy levels.
    • treemap - Displays hierarchy levels as top-level and nested rectangles of varying size.
    • network - Displays files as nodes with the relationship between files.
  • --concurrency - Number of builds to run in parallel. Defaults to operating system CPU count.
  • --declaration - Generate TypeScript declarations for each package. Accepts one of the following values.
    • standard - Generates multiple d.ts files with tsc.
    • api - Generates a single d.ts file for each input. Uses @microsoft/api-extractor to only generate the public API. (NOTE: this is quite slow)
  • --declarationConfig - Path to a custom tsconfig for declaration building.
  • --filter - Filter packages to build based on their name in package.json.
  • --formats, -f - Only generate specific output formats.
  • --platforms, -p - Only target specific platforms.
  • --skipPrivate - Skip private packages from being built.
  • --timeout - Timeout in milliseconds before a build is cancelled. Defaults to no timeout.

All filtering options support standard patterns (foo-*), comma separated lists (foo,bar), or both.

How it works#

When the build process is ran, Packemon will find all viable packages within the current project and generate build artifacts. A build artifact is an output file that will be distributed with the npm package, but will not be committed to the project (ideally git ignored).

To demonstrate this, let's assume we have a package with the following folder structure and file contents (not exhaustive).

/โ”œโ”€โ”€ src/|   โ”œโ”€โ”€ index.ts|   โ””โ”€โ”€ *.tsโ”œโ”€โ”€ tests/โ”œโ”€โ”€ package.jsonโ”œโ”€โ”€ LICENSEโ””โ”€โ”€ README.md
package.json
{    "name": "package",    "packemon": {        "inputs": { "index": "src/index.ts" },        "platform": ["node", "browser"],        "formats": ["lib", "esm", "umd"],        "namespace": "Example"    }}

Based on the package configuration above, our build will target both Node.js and web browsers, while generating multiple index outputs across both platforms. The resulting folder structure will look like the following (when also using --declaration).

/โ”œโ”€โ”€ dts/|   โ””โ”€โ”€ index.d.tsโ”œโ”€โ”€ esm/|   โ””โ”€โ”€ index.jsโ”œโ”€โ”€ lib/|   โ””โ”€โ”€ browser/index.js|   โ””โ”€โ”€ node/index.jsโ”œโ”€โ”€ src/|   โ”œโ”€โ”€ index.ts|   โ””โ”€โ”€ *.tsโ”œโ”€โ”€ tests/โ”œโ”€โ”€ umd/|   โ””โ”€โ”€ index.jsโ”œโ”€โ”€ package.jsonโ”œโ”€โ”€ LICENSEโ””โ”€โ”€ README.md

Furthermore, the package.json will automatically be updated with our build artifact entry points and files list, as demonstrated below. This can further be expanded upon using the --addEngines and --addExports options.

package.json
{    "name": "package",    "main": "./lib/index.js",    "module": "./esm/index.js",    "browser": "./umd/index.js",    "types": "./dts/index.d.ts",    "files": ["dts/", "esm/", "lib/", "src/", "umd/"],    "packemon": {        "inputs": { "index": "src/index.ts" },        "platform": ["node", "browser"],        "formats": ["lib", "esm", "umd"],        "namespace": "Example"    }}

Amazing, we now have self-contained and tree-shaken build artifacts for consumption. However, to ensure only build artifacts are packaged and distributed to npm, we rely on the package.json files property. Based on the list above, the files published to npm would be the following (pretty much everything except tests).

/โ”œโ”€โ”€ dts/โ”œโ”€โ”€ esm/โ”œโ”€โ”€ lib/โ”œโ”€โ”€ src/โ”œโ”€โ”€ umd/โ”œโ”€โ”€ package.jsonโ”œโ”€โ”€ LICENSEโ””โ”€โ”€ README.md

Why are source files published? For source maps! Packemon will always generate source maps regardless of format, and the src directory is necessary for proper linking.