Packemon
website·Indexed 32 days ago
https://packemon.dev/A zero-config tool for building and preparing TypeScript and JavaScript packages for distribution. It simplifies the build process by managing Babel, swc, and Rollup configurations, supporting monorepos, and providing commands for scaffolding, validating, and packing packages across multiple platforms.
What's inside Packemon
- Packemon provides a zero-config approach to package bundling, eliminating the need to manually configure tools like Babel, Rollup, or Webpack. It uses sane defaults to automatically configure packages, supporting both single-package (polyrepo) and multi-package (monorepo) project structures.
Overview of Packemon package building features
Packemon is a "batteries included" CLI designed for library maintainers to automate the process of preparing packages for distribution. It removes the need for manual Babel or Rollup configuration by providing sane defaults and automated tooling. Key capabilities include:
- Scaffolding TypeScript packages for both monorepo and polyrepo setups.
- Targeting multiple platforms including Node.js, Web browsers, React Native, and Electron.
- Supporting multiple output formats, including ECMAScript modules (default) and CommonJS.
- Using Rollup for tree-shaken, self-contained bundles to minimize file size.
- Supporting various entry point strategies: single index imports, multiple imports, or deep imports.
- Utilizing Babel's
preset-envto transform packages based on platform targets and necessary polyfills. - Generating and combining TypeScript declarations into a single public-only API representation.
- Creating compact source maps tailored to specific platforms and formats.
Configure TypeScript declarations for multiple formats
Due to TypeScript v4.7's introduction of
.ctsand.mtsextensions, Packemon now requires explicitly named configuration files for each output format to ensure correct declaration generation. The--declarationConfigoption has been removed.If you are building formats such as
libandesm, you must provide:tsconfig.lib.jsontsconfig.esm.json
Additionally, declaration files are no longer generated into a separate
dtsfolder; they are now generated directly into the format folders (e.g.,lib/,esm/).// Example tsconfig for a specific format (e.g., tsconfig.lib.json) { "extends": "../../tsconfig.options.json", "compilerOptions": { "outDir": "lib" }, "include": ["src/**/*"] }Packemon v4.0 ESM-only migration
Packemon has migrated to be an ESM-only package and now ships exclusively as.mjsfiles. This change is intended to be transparent to users while providing increased performance and reduced memory usage compared to CommonJS (CJS).Automatic package.json exports and the default condition
Packemon now implements an algorithm to automatically flatten exports and add adefaultcondition if one does not exist. This ensures that packages built for specific environments (like browsers) remain compatible with non-bundler environments such as Node.js and TypeScript, preventing 'missing exports or types' errors.Migrate per-package Babel configurations to Packemon config
Support for.babelrcfiles within individual packages has been removed. Custom Babel plugins and presets should now be configured using thebabelOutputfunction in the.packemon.jsconfiguration file.// packages/foo/.packemon.js module.exports = { babelOutput(config) { config.plugins.push('babel-plugin-formatjs'); }, };Implement bundle analysis using rollup-plugin-visualizer
The--analyzeCLI option has been removed. To analyze bundles, you must now implementrollup-plugin-visualizervia a custom Rollup configuration in your Packemon config file.const path = require('path'); const visualizer = require('rollup-plugin-visualizer'); module.exports = { rollupInput(config) { config.plugins.push( visualizer((outputOptions) => ({ filename: path.join(outputOptions.dir, 'stats.html'), gzipSize: true, open: true, sourcemap: true, template: 'treemap', })), ); }, };Handle CommonJS and ECMAScript interoperability
Packemon usesbabel-plugin-cjs-esm-interopto transform code between CommonJS (.cjs,.js) and ECMAScript modules (.mjs,.jswith module type) following official Node.js specifications. This ensures compatibility when mixing module systems.// Input: mjs const self = import.meta.url; // Output: cjs const self = __filename;Monitor package changes with packemon watch
Thewatchcommand monitors the local file system for changes and triggers a rebuild for a package. By default, the watcher only monitors files located within thesrcfolder of the package and uses default build options for the rebuild process.{ "scripts": { "watch": "packemon watch" } }System requirements for babel-plugin-env-constants
The plugin requires Node.js version 18.12 or higher and is compatible with Linux, OSX, and Windows operating systems.Install Chokidar for packemon file watching
Thepackemon watchcommand requireschokidarto be installed in the project to function correctly.yarn add --dev chokidarCustomize Babel, swc, and Rollup configurations
Packemon allows advanced customization of its internal build tool configurations via an opt-in mechanism. This is intended as an escape hatch for unsupported requirements (e.g., specific CSS processing).
To enable customization:
- Pass the
--loadConfigsflag on the command line to enable filesystem lookups for config files. - Create a
packemon.config.{ts,js}file at the root (applies to all packages) or an optional.packemon.{ts,js}file within a specific package.
Configuration fields accept functions that receive the finalized config as an argument (and the current build as a second argument for output fields), allowing for in-place mutation. It is recommended to only add new functionality rather than mutating existing Packemon-generated settings.
Available configuration fields:
babelInput: Parsing syntax into AST.babelOutput: Applying transformations.rollupInput: Defining inputs, outputs, and more.rollupOutput: Customizing each output.swc: Boolean to enable swc instead of Babel.swcInput: Parsing syntax into AST.swcOutput: Applying transformations.
import type { ConfigFile } from 'packemon'; import linaria from '@linaria/rollup'; const config: ConfigFile = { babelOutput(config, build) { config.presets.push('@linaria/babel-preset'); }, rollupInput(config) { config.plugins.unshift(linaria()); }, }; export default config;- Pass the