I faced a problem recently. I have a reference data package which is an npm package that can be consumed by two different projects:
- The frontend: a React application bundled with Vite.js, an ESM builder (with no CJS support).
- The backend: a Nestjs application that only supports CommonJS.
Also, this package contains some big files inside. Bundling everything in one file is a big no-no.
Folder structure
Letβs start with a classic file architecture:
Please note that everything under the src/
folder import/export dependencies with the ES7 import
/ export
keyword.
Libraryβs package.json
The solution I found is to have 2 folders under the dist
folder:
You can see that I use the exports
token. This allows the package owner to define multiple entry
points. A CommonJS system will use the index located in the ./dist/cjs/index.js
folder while an
ESM system will use the other index located in the esm folder.
By the way, you can do much more with the conditional exports!
tsconfig.json files
I donβt have one file but two.
If your IDE or other tools need one named tsconfig.json
, you can create a master one. Then the
specific tsconfig files can extend from it.
Then you can npm publish
and call it a day π₯³
Usage
Your package will be available in both ESM and CommonJS environments. Your users can use it without knowing thereβs a separation.
About the author
Hey, I'm Maxence Poutord, a passionate software engineer. In my day-to-day job, I'm working as a senior front-end engineer at Orderfox. When I'm not working, you can find me travelling the world or cooking.
Follow me on BlueskyRecommended posts
Understanding the Git Folder Structure and how git works under the hood.
Thomas Roberts is a fraudulent YouTuber who uses fake crypto tutorials to spread malware. He artificially inflates his channel's popularity and promotes a malicious script that downloads harmful files and steals crypto. This scam, powered by AI-generated content, highlights the growing sophistication of online threats.