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.

You'll need to specify format, additionalEntryPoints and generateExportsField in the executor options. Here's an example:

packages/my-awesome-lib/project.json
1{ 2 "name": "my-awesome-lib", 3 "targets": { 4 "build": { 5 "executor": "@nx/rollup:rollup", 6 "options": { 7 "main": "packages/my-awesome-lib/src/index.ts", 8 "format": ["esm", "cjs"], 9 "additionalEntryPoints": ["packages/my-awesome-lib/src/foo.ts"], 10 "generateExportsField": true 11 } 12 } 13 } 14} 15
Nx 15 and lower use @nrwl/ instead of @nx/

After compiling our package using nx build my-awesome-lib we'll get the following output in our dist folder.

1my-awesome-lib 2└─ . 3 ├─ README.md 4 ├─ foo.cjs.d.ts 5 ├─ foo.cjs.js 6 ├─ foo.esm.js 7 ├─ index.cjs.d.ts 8 ├─ index.cjs.js 9 ├─ index.esm.js 10 ├─ package.json 11 └─ src 12 ├─ foo.d.ts 13 ├─ index.d.ts 14 └─ lib 15 └─ my-awesome-lib.d.ts 16

And our package.json will look like this:

dist/my-awesome-lib/package.json
1{ 2 "name": "my-awesome-lib", 3 "version": "0.0.1", 4 ... 5 "type": "commonjs", 6 "main": "./index.cjs.js", 7 "typings": "./src/index.d.ts", 8 "exports": { 9 "./package.json": "./package.json", 10 ".": { 11 "import": "./index.esm.js", 12 "default": "./index.cjs.js" 13 }, 14 "./foo": { 15 "import": "./foo.esm.js", 16 "default": "./foo.cjs.js" 17 } 18 }, 19 "module": "./index.esm.js" 20} 21 22

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.