Dual Publish
Publish JS project as dual ES modules and CommonJS package to npm.
- Tested on projects with 16M downloads per month.
- CI tests with it works with Node.js, browsers, React Native, bundlers (webpack, Parcel, Rollup, or esbuild) and CDNs (like jspm).
- Does not change line numbers in stacktrace and keep sources readable.
- No build step. No need for separated
src/
anddist/
dirs in repository. You will be able to test branch by installing version from GitHub likenpm i example@you/example#fix
. - Multiple files support. Your user will be able to import separated files
likeimport { nanoid } from 'nanoid/async'
. - Cleans npm package from development configs before publishing.
- Supports
process.env.NODE_ENV
for development checks, which you want to remove in production JS bundle.
You write CommonJS in your npm library sources:
// index.js
module.exports = { lib }
npx dual-publish
compiles your library during publishing to npm:
// index.js
export { lib }
// index.cjs
module.exports = { lib }
// package.json
{
…
"type": "module",
"module": "index.js",
"main": "index.cjs",
"exports": {
"require": "./index.cjs",
"import": "./index.js"
}
}
Now your library can be imported natively as ESM or CommonJS:
// CommonJS
let { lib } = require('lib')
// ESM in Node.js, webpack, Parcel, and Rollup
import { lib } from 'lib'
// ESM in browser
import { lib } from 'https://cdn.jsdelivr.net/npm/lib/index.js'
Limits
- We recommend to avoid default export because of bug in webpack.
- Every JS file should be in own dir.
lib/index.js
instead oflib.js
. We need it to putpackage.json
withmodule
.
Usage
-
Take a normal CommonJS project with
require()
andmodule.exports =
. -
Because of bug in webpack we recommend to use only named exports:
const NAME = 'a' function change { … } module.exports = { NAME, change }
-
Move all files into separated dirs. Rename
lib.js
tolib/index.js
. Oldrequire('./lib')
will work. -
Add
dual-publish
to the project:npm i --save-dev dual-publish
-
Test the result by calling
npx dual-publish --check
. It will create a folder in your project with converted files. Review them manually. -
Publish your project with
npx dual-publish
instead ofnpm publish
.npx dual-publish