npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@ncpa0cpl/nodepack

v2.3.3

Published

Simple packaging script for node libraries based on ESBuild

Downloads

201

Readme

nodepack

Features

  • Fast (uses ESBuild under the hood)
  • Build your project for CommonJS modules, ESModules and legacy environments all at once
  • Generate TypeScript declarations along with the compiled JavaScript
  • Generate TypeScript declarations for JSON files
  • Path aliases out of the box, along with import rewriting in .d.ts files

Table of contents

  1. Installation
  2. Usage
  3. Options
    1. target
    2. srcDir
    3. outDir
    4. formats
    5. bundle
    6. entrypoint
    7. external
    8. exclude
    9. replaceImports
    10. compileVendors
    11. preset
    12. declarations
    13. decoratorsMetadata
    14. extMapping
    15. isomorphicImports
    16. pathAliases
    17. tsConfig
    18. watch
    19. esbuildOptions

Installation

  1. Intall this package and esbuild using yarn or npm:

      npm i -D esbuild @ncpa0cpl/nodepack

    or

      yarn add -D esbuild @ncpa0cpl/nodepack
  2. (Optional) If you want to be able to generate TypeScript declarations also install typescript.

  3. (Optional) If you want to be able to generate TypeScript declarations for JSON files also install json-to-ts package.

Usage

Important

Make sure to explicitly set all type exports/imports as a type exports/imports in your project files. (use eslint rules to enforce this rule: for exports and for imports)

All exports and imports of TS types that are not marked as such will be left over in the compiled JS files, which will lead to runtime errors.

Execute this JavaScript script to build the files for the selected formats:

import { build } from "@ncpa0cpl/nodepack";
import process from "node:process";
import path from "path";

build({
  target: "es6",
  srcDir: path.resolve(process.cwd(), "src"),
  outDir: path.resolve(process.cwd(), "dist"),
  formats: ["cjs", "esm", "legacy"],
  declarations: true,
});

Then for node environments to correctly resolve the build files depending on the environment include the following in your package.json file:

{
  // main entrypoint for legacy environments that do not support the `exports` field
  "main": "./dist/legacy/index.js",
  // main type declarations entrypoint for legacy environments that do not support the `exports` field
  "types": "./dist/types/index.d.ts",
  "exports": {
    ".": {
      // main type declarations entrypoint
      "types": "./dist/types/index.d.ts",
      // main entrypoint for environments that use the ESModules
      "import": "./dist/esm/index.mjs",
      // main entrypoint for environments that use the CommonJS modules
      "require": "./dist/cjs/index.cjs"
    }
  }
}

Raw JSON

{
  "main": "./dist/legacy/index.js",
  "types": "./dist/types/index.d.ts",
  "exports": {
    ".": {
      "types": "./dist/types/index.d.ts",
      "import": "./dist/esm/index.mjs",
      "require": "./dist/cjs/index.cjs"
    }
  }
}

Options

target

(required)

Target environment for the generated JavaScript.

srcDir

(required)

Absolute path to the directory containing the source files.

outDir

(required)

Absolute path to the directory to which the compiled source should be outputted to.

formats

(required)

List of format types that should be outputted.

  • cjs format - CommonJS module format with a .cjs file extension.
  • esm format - ES module format with a .mjs file extension.
  • legacy format - CommonJS module format with a .js file extension.

bundle

(optional) Default: false

When enabled, the entire program will be bundled into a single file, with the exception of files and packages marked as external or as vendors.

entrypoint option must be provided when bundle is enabled.

entrypoint

(optional)

Filename of the entrypoint file, relative to the srcDir. This option is only used when bundle is enabled.

external

(optional) Default: []

List of packages that should be excluded from compilation. Imports of those packages will be left as is, unless replaceImports for that package is specified.

exclude

(optional) Default: []

Regex patterns used to exclude files from compilation.

replaceImports

(optional)

Allows to define import mappings, for example if given this replaceImports option: { eventemitter2: "eventemitter3" }, all imports of eventemitter2 in the source will be replaced with an import of eventemitter3 in the output.

compileVendors

(optional)

List of external packages that should be compiled along with the source files.

Each specified vendor package will be compiled into a single bundle file and placed inside a _vendors directory.

If set to all, all external packages will be compiled.

preset

(optional)

Can define which presets to use for the compilation. Available presets are: node, deno and gjs.

Each preset includes a set of package names that should be added to the external option for the given target environment.

declarations

(optional) Default: false

Indicates if typescript declarations are to be generated. If set to true, .d.ts files will be generated along the JavaScript files, if set to only no JavaScript will be emitted, only the declarations.

To be able to generate declarations, TypeScript package must be installed.

decoratorsMetadata

(optional) Default: false

Wether to generate metadata along with the typescript decorators, this requires to transpile files first with a TypeScript compiler before compiling with esbuild and will make the build process noticeably slower.

extMapping

(optional)

Allows to customize the file extension of the outputted files. This is useful for custom esbuild loaders, like a file loader.

If you want to map given extension to the used format (.cjs, .mjs or .js), you can use a %FORMAT% wildcard instead of a extension.

Example

To map all .png files to the javascript extension depending on which format it is generated for:

import { build } from "@ncpa0cpl/nodepack";

build({
  // ...
  formats: ["cjs", "esm", "legacy"],
  extMapping: {
    ".png": "%FORMAT%",
  },
  esbuildOptions: {
    loader: {
      ".png": "dataurl",
    },
  },
});

With the above options, a source with a ./src/icon.png file would get transformed to:

dist
|- cjs
|--|- icon.cjs
|- esm
|--|- icon.mjs
|- legacy
|--|- icon.js

To statically map .png file to other extension just replace the %FORMAT% with the desired extension.

isomorphicImports

(optional)

Files that should get their imports replaced to other path, depending on the extension for which it is compiled.

All path provided should be relative to the srcDir.

If no import is defined for a format, the import will be left as is.

Since some of the features in Node are only available for ESModules or CommonJS modules (for example __filename or import.meta), it might be helpful to have different file be imported depending on which module type the program is using.

To define a different index file for each of the compiled formats:

build({
  // ...
  isomorphicImports: {
    "./index.ts": {
      mjs: "./index.esm.ts",
      cjs: "./index.cjs.ts",
      js: "./index.legacy.ts",
    },
  },
});

pathAliases

(optional)

A map of path aliases.

Each path alias must end with a /*, and each alias value must be a path relative to the srcDir, start with a ./ and end with a /*.

Path aliases are used to replace imports in JavaScript files for all formats and TypeScript declaration files.

Example
import { build } from "@ncpa0cpl/nodepack";

build({
  // ...
  pathAliases: {
    "@Utils/*": "./Utils/*",
  },
});

tsConfig

(optional)

Absolute path to the TypeScript config file.

watch

(optional) Default: false

When watch mode is enabled, nodepack will listen for changes on the file system and rebuild whenever a file changes.

This option is currently experimental and you may encounter bugs if you use it.

esbuildOptions

(optional)

Options to pass to the esbuild compiler. (See available options here), most of the options are available but some can potentially break the compilation process.