Compile TypeScript Libraries to Multiple Formats
It can be difficult to set up a typescript library to compile to ESM and CommonJS. As of Nx 16.8, you can use the@nx/rollup:rollup
executor to take care of it for you.
Use Rollup to Compile your TypeScript Project
Section titled “Use Rollup to Compile your TypeScript Project”If you do not use Rollup already, install the corresponding Nx plugin as follows:
nxadd@nx/rollup
Make sure the version of@nx/rollup
matches your other@nx/*
package versions.
You can then configure Rollup to compile your library by adding abuild
target to yourproject.json
orpackage.json
file. Here's an example:
{"name":"my-awesome-lib","nx": {"targets": {"build": {"executor":"@nx/rollup:rollup","options": {"main":"packages/my-awesome-lib/src/index.ts"}}}}}
{"name":"my-awesome-lib","targets": {"build": {"executor":"@nx/rollup:rollup","options": {"main":"packages/my-awesome-lib/src/index.ts"}}}}
If you happen to use the@nx/js:tsc
executor already, you can also use theRollup configuration generator from the Nx Rollup plugin to automatically configure your project's build target.
Configure Rollup to Create Multiple Formats
Section titled “Configure Rollup to Create Multiple Formats”You'll need to specifyformat
,additionalEntryPoints
andgenerateExportsField
in the executor options. Here's an example:
{"name":"my-awesome-lib","targets": {"build": {"executor":"@nx/rollup:rollup","options": {"main":"packages/my-awesome-lib/src/index.ts","format": ["esm","cjs"],"additionalEntryPoints": ["packages/my-awesome-lib/src/foo.ts"],"generateExportsField":true}}}}
After compiling our package usingnx build my-awesome-lib
we'll get the following output in ourdist
folder.
my-awesome-lib└─ .├─ README.md├─ foo.cjs.d.ts├─ foo.cjs.js├─ foo.esm.js├─ index.cjs.d.ts├─ index.cjs.js├─ index.esm.js├─ package.json└─ src├─ foo.d.ts├─ index.d.ts└─ lib└─ my-awesome-lib.d.ts
And ourpackage.json
will look like this:
{"name":"my-awesome-lib","version":"0.0.1",..."type":"commonjs","main":"./index.cjs.js","typings":"./src/index.d.ts","exports": {"./package.json":"./package.json",".": {"import":"./index.esm.js","default":"./index.cjs.js"},"./foo": {"import":"./foo.esm.js","default":"./foo.cjs.js"}},"module":"./index.esm.js"}
Now consumers of your package can access the appropriate format for their codebase and you don't have to worry about maintaining the infrastructure to compile to both formats.