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 @_maxpou