Logo

dev-resources.site

for different kinds of informations.

Creating a Node.js module for both CommonJS & ESM consumption

Published at
5/15/2022
Categories
javascript
node
esm
npm
Author
mathbraddock
Categories
4 categories in total
javascript
open
node
open
esm
open
npm
open
Author
12 person written this
mathbraddock
open
Creating a Node.js module for both CommonJS & ESM consumption

Last week I had an urge to create a simple stopwatch module for a future project. I recently got my feet wet with creating ECMAScript modules (ESM), and wanted to ensure that any module I created in the future would feel native to either CommonJS or ESM. Turns out it is very simple.

In the most skeleton form, my structure looked like this:

src/
└── index.cjs
index.js
index.mjs
package.json
Enter fullscreen mode Exit fullscreen mode

All of the work for the module lives in src/, with the two root index files just providing exports to be consumed by parent modules. Here is how the relevant portions of the files above look:

src/index.cjs:

module.exports = class SomeClass {
    // code here
}
Enter fullscreen mode Exit fullscreen mode

index.js:

const SomeClass = require('./src/index.cjs');

module.exports = SomeClass;
Enter fullscreen mode Exit fullscreen mode

index.mjs:

import SomeClass from './src/index.cjs';

export default SomeClass;
Enter fullscreen mode Exit fullscreen mode

package.json:

"main": "./index.js",
"exports": {
    "require": "./index.js",
    "import": "./index.mjs"
}
Enter fullscreen mode Exit fullscreen mode

And that's it! This can certainly be scaled up to more than a single export, and it can include named exports as well.

Bonus: here is the stopwatch module I created.

esm Article's
30 articles in total
Favicon
Bundling without a bundler with esm.sh
Favicon
Building NPM packages for CommonJS with ESM dependencies
Favicon
Web Development Without (Build) Tooling
Favicon
Dual Node TypeScript Packages - The Easy Way
Favicon
Oh CommonJS! Why are you mESMing with me?! Reasons to ditch CommonJS
Favicon
The Ongoing War Between CJS & ESM: A Tale of Two Module Systems
Favicon
How I optimized Carousel for EditorJS 2x in size.
Favicon
Transitioning from CommonJS to ESM
Favicon
Node.js, TypeScript and ESM: it doesn't have to be painful
Favicon
Set up Hot Reload for Typescript ESM projects
Favicon
Set up a Node.js project + TypeScript + Jest using ES Modules
Favicon
ESM & CJS: The subtle shift in bundlejs' behaviour
Favicon
Mastering the Art of ESM and CJS Package Handling
Favicon
Modules & Modules & Modules, Oh My!
Favicon
How to build TypeScript to ESM and CommonJS
Favicon
ES Modules & Import Maps: Back to the Future
Favicon
How to use ESM on the web and in Node.js
Favicon
Custom ESM loaders: Who, what, when, where, why, how
Favicon
Fix NX Node executor ERR_REQUIRE_ESM Error
Favicon
Creating a Node.js module for both CommonJS & ESM consumption
Favicon
STOP using require() in node backend
Favicon
JavaScript Module Ecosystem
Favicon
Declarative database modelling
Favicon
Expressjs: Javascript written in ECMAScript 2015 (ES6)
Favicon
How to use ES Modules with Node.js
Favicon
What does it take to support Node.js ESM?
Favicon
Build modular app with Alpine.js
Favicon
TS and ts-jest meet β€œtype”: β€œmodule”
Favicon
ESM doesn't need to break the ecosystem
Favicon
constructor() dynamic import()

Featured ones: