A template repository for an NPM package that supports TypeScript, ESM, CJS, as well as exporting CLI commands.
ESLint and Jest are also integrated into the project out-of-the-box.
Out-of-the-box, this template includes a basic greeting
CLI that also allows the greet
helper that
it calls to be exported from the package to be able to be imported within a consuming project
instead of integrating with the CLI command.
This is just to show an example of how to define things - you can delete it and replace with your own package and/or CLI implementation.
Because this template has been configured to support ESM, you will have to ensure your import paths include the exact path to the file. This unfortunately means that it won't correctly resolve without the extension or for index files just using the folder in the import path.
Also, for .ts
and .tsx
files, you will have to ensure you use .js
and .jsx
extensions in your
import paths.
Here's an example:
// These will not work
import { thing } from "../helpers";
import { thing } from "../helpers/thing";
// These will work
import { thing } from "../helpers/index.js";
import { thing } from "../helpers/thing.js";
If you want to test the CLI command locally you can run yarn start
in the project root after
compiling, or to test it as a global command you can run npm link
after installing the project,
which will allow you to run the package's exported CLI commands globally.
You should add unit test coverage for your package implementation to ensure everything works correctly. If you want to test it interactively in a consuming project to be 100% certain your package works as expected, you can use the link functionality provided by Yarn or NPM (depending on if you're using Yarn or NPM in the consuming project).
Everything is all integrated with the prepack
hook to automatically compile before the package's
tgz
file is created. This will allow you to just be able to run yarn publish
(or with npm
if you
choose to remove yarn.lock
and use that instead) to publish new versions of your package in one step.
If you just want to compile without packing or publishing, you can just run yarn compile
directly,
or use yarn compile:watch
if you want it to recompile when you make changes.
If you just want to pack the .tgz
file, just run yarn pack
.
TypeScript has been configured to output the compiled .js
and .d.ts
files as both ES Module (ESM) format,
as well as CommonJS (CJS) format. These are outputted to the cjs
and esm
folders respectively.
A package.json
file lives within /cjs
to flag the folder as being CommonJS, to override the
top-level type
value of module
.
This, in addition to the exports
configuration in package.json
, allows the package to support
both native ESM and CJS consumers simultaneously. Consumers will automatically use the appropriate
format depending on if they're using the import
or require
syntax in their codebase.