Our great sponsors
-
nodejs-module-config-examples
A collection of Node.js module configurations for interoperability between CJS and ESM
-
SurveyJS
Open-Source JSON Form Builder to Create Dynamic Forms Right in Your App. With SurveyJS form UI libraries, you can build and style forms in a fully-integrated drag & drop form builder, render them in your JS app, and store form submission data in any backend, inc. PHP, ASP.NET Core, and Node.js.
-
webpack
A bundler for javascript and friends. Packs many modules into a few bundled assets. Code Splitting allows for loading parts of the application on demand. Through "loaders", modules can be CommonJs, AMD, ES6 modules, CSS, Images, JSON, Coffeescript, LESS, ... and your custom stuff.
I have confirmed all the provided package.json configurations (not specifically marked “does not work”) work in Node.js 12.22.x (v12 latest, the oldest supported line) and 17.2.0 (current latest at the time)1, and for grins, with webpack 5.53.0 and 5.63.0 respectively. I’ve prepared a repository with them so you can check them out yourself: JakobJingleheimer/nodejs-module-config-examples (the repo’s root README explains how to use it).
This also means that whatever build tooling must produce the distribution file with a .cjs file extension. This might necessitate chaining multiple build tools or adding a subsequent step to move/rename the file to have the .cjs file extension (ex mv ./dist/index.js ./dist/index.cjs)3. This can be worked around by adding a subsequent step to move/rename those outputted files (ex Rollup or a simple shell script).
Note that ESM is not “backwards” compatible with CJS: a CJS module cannot require() an ES Module; it is possible to use a dynamic import (await import()), but this is likely not what consumers expect (and, unlike ESM, CJS does not support Top-Level Await).
Note that generating CJS output with named exports from ESM is not currently possible with Webpack (support is pending Webpack PR#14998); it's not possible with esbuild (which, like Webpack, produces a non-static exports). However, Rollup DOES produce compatible output; the working example below uses Rollup instead of Webpack.
Note that generating CJS output with named exports from ESM is not currently possible with Webpack (support is pending Webpack PR#14998); it's not possible with esbuild (which, like Webpack, produces a non-static exports). However, Rollup DOES produce compatible output; the working example below uses Rollup instead of Webpack.
There was a bug in Node.js v13.0–13.6 where packageJson.exports["."] had to be an array with verbose config options as the first item (as an object) and the “default” as the second item (as a string). See nodejs/modules#446.