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.

Tokens
10.3K
Snippets
61
Records
93
Agent score
63%

What's inside Packemon

  1. Overview of Packemon zero-config package management

    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.
  2. 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-env to 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.
  3. Configure TypeScript declarations for multiple formats

    Due to TypeScript v4.7's introduction of .cts and .mts extensions, Packemon now requires explicitly named configuration files for each output format to ensure correct declaration generation. The --declarationConfig option has been removed.

    If you are building formats such as lib and esm, you must provide:

    • tsconfig.lib.json
    • tsconfig.esm.json

    Additionally, declaration files are no longer generated into a separate dts folder; 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/**/*"]
    }
  4. Packemon v4.0 ESM-only migration

    Packemon has migrated to be an ESM-only package and now ships exclusively as .mjs files. This change is intended to be transparent to users while providing increased performance and reduced memory usage compared to CommonJS (CJS).
  5. Automatic package.json exports and the default condition

    Packemon now implements an algorithm to automatically flatten exports and add a default condition 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.
  6. Migrate per-package Babel configurations to Packemon config

    Support for .babelrc files within individual packages has been removed. Custom Babel plugins and presets should now be configured using the babelOutput function in the .packemon.js configuration file.
    // packages/foo/.packemon.js
    module.exports = {
      babelOutput(config) {
        config.plugins.push('babel-plugin-formatjs');
      },
    };
  7. Implement bundle analysis using rollup-plugin-visualizer

    The --analyze CLI option has been removed. To analyze bundles, you must now implement rollup-plugin-visualizer via 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',
          })),
        );
      },
    };
  8. Handle CommonJS and ECMAScript interoperability

    Packemon uses babel-plugin-cjs-esm-interop to transform code between CommonJS (.cjs, .js) and ECMAScript modules (.mjs, .js with 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;
  9. Monitor package changes with packemon watch

    The watch command monitors the local file system for changes and triggers a rebuild for a package. By default, the watcher only monitors files located within the src folder of the package and uses default build options for the rebuild process.
    {
      "scripts": {
        "watch": "packemon watch"
      }
    }
  10. Install Chokidar for packemon file watching

    The packemon watch command requires chokidar to be installed in the project to function correctly.
    yarn add --dev chokidar
  11. Customize 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:

    1. Pass the --loadConfigs flag on the command line to enable filesystem lookups for config files.
    2. 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;