Faire / mjml-react

React component library to generate the HTML emails on the fly
https://www.npmjs.com/package/@faire/mjml-react
MIT License
375 stars 16 forks source link

publish package so both `esm` and `cjs` can co-exist with the same imports #72

Open IanEdington opened 1 year ago

IanEdington commented 1 year ago

currently the package publishes esm and cjs seperately. This results in import statements like the following:

cjs

import { render } from "@faire/mjml-react/renders";

esm

import { render } from "@faire/mjml-react/esm/renders";

Is there some way to have the folders merged with both an esm and cjs version available? ~Would it make sense to prioritize one and allow the other to use an alias? ie. cjs is in root and esm is a directory in root?~ done

import { render } from "@faire/mjml-react/renders";

split out from #64

eddeee888 commented 1 year ago

Hello 👋 Would using (package.json).exports work? e.g.

{
  "name": "@faire/mjml-react",
  ...
  "exports": {
    "renders": {
      "import": "./dist/esm/utils/render.js",
      "require": "./dist/src/utils/render.js",
      "types": "./dist/src/utils/render.d.ts"
    }
  }
}

The above config should allow importing from @faire/mjml-react/renders (I haven't tried this myself though)

Here's the resources I looked through for the config:

emmclaughlin commented 1 year ago

Thanks @eddeee888! Thank is on the right track, but unfortunately I think it is a bit tricky to implement a solution that works for everything. We have that exact setup for the main package.json (i.e. all the Mjml* components) but to get all of the utils/extension files also exported in that way I think we would need to 1) update the file structure (see https://github.com/Faire/mjml-react/pull/77) and then 2) create a package.json for each file we want to easily export esm and cjs version of and place it in the right folder. Ideally the finall solution is importing from @faire/mjml-react/utils/render will automatically resolve esm and cjs

IanEdington commented 1 year ago

Did some reading on this and it seems like the conditional exports would work well for us

https://nodejs.org/api/packages.html#conditional-exports

This is a very interesting writeup on some of the pitfalls of including both ESM and CJS modules in the same package: https://nodejs.org/api/packages.html#dual-commonjses-module-packages

Fortunately we don't manage state in this library so it should be fine to have both.