Logo

dev-resources.site

for different kinds of informations.

Mastering the Art of ESM and CJS Package Handling

Published at
10/15/2023
Categories
typescript
javascript
esm
node
Author
okikio
Categories
4 categories in total
typescript
open
javascript
open
esm
open
node
open
Author
6 person written this
okikio
open
Mastering the Art of ESM and CJS Package Handling

Greetings, fellow devs and bundlejs aficionados! πŸš€

I was closing out some long lived issues over on bundlejs, when issue #50 reminded me of the ongoing debate about how bundlejs should handle the ESM and CJS packages.

Lightbulbs flickered, coffee was consumed (I don't drink coffee, but you get the point), and I'm pretty sure I've cracked a solution. But there are a few slight behavior changes you need to be aware of. So buckle up. If anything looks off or confusing, please let me know in either the comments below, on GitHub Discussions or issue #50 directly.

The Issue at Hand 🧐

The root of the problem lies in how bundlejs was handling CommonJS files.

"CommonJS files only export their default, which created a conundrum. How can we tell if a module is CommonJS if we don't fetch it? And if we fetch it first, it's too late for esbuild to deal with it properly."

But never fear! I've worked out a solution that is impartial to whether the module is ESM or CommonJS.

The Solution 🧩

Let's walk through this step by step, using our handy deno.bundlejs.com API for demonstration.

  1. Single CJS File: Only export the default (no renaming involved). Check out this example using postcss-easings: https://deno.bundlejs.com/?file&q=postcss-easings&minify=false

  2. Multiple CJS Files: Export the default but use the file URL as the import name. Also, append ...Default to the end of it like so: reactDefault & reactDomDefault. Take a peek here: https://deno.bundlejs.com/?file&q=react,react-dom&minify=false

  3. Single ESM File: Export everything, including the default. No renaming here, folks! https://deno.bundlejs.com/?file&q=spring-easing&minify=false

  4. Multiple ESM Files: Export all methods and variables from all exports, but remember to use the naming rules for all default exports. For instance, after exporting the other module exports, rename the default export to springEasingDefault and codepointIteratorDefault: https://deno.bundlejs.com/?file&q=spring-easing,codepoint-iterator&minify=false

  5. Treeshaking: Here, we assume you want the driver's seat if you add the treeshake query param to the URL. So, all of the above rules are null and void, and you now have complete control over what is exported, including the default exports not being automatic. https://deno.bundlejs.com/?file&q=spring-easing,react&treeshake=[*],[*]&minify=false

🚨 Note: You might run into issues with CJS modules if you don't export default properly. Part of this is because tree-shaking is somewhat of a no-show for CJS packages, so tread lightly here!

There you have it! A quick and dirty rundown of the latest updates to the way bundlejs.com handles CJS and ESM packages.

So, go ahead and take the new system for a spin. Let me know what you think. Take it for a ride πŸš—

Photo by Marcin Jozwiak

Originally posted on blog.okikio.dev

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: