ChristophP/elm-esm

Modularize makeESModule

hmsk opened this issue · 10 comments

hmsk commented

Thanks for sharing such a useful implementation ✨

One thing I'd like to request is that the distributed elm-esm npm provides importable makeESModule.

I'm imagining an interface like:

import { toESM } from 'elm-esm'

toESM(compiledElmProject)

I could build my own function by copying your code actually. However, I'm wondering if elm-esm becomes a single source of truth for this purpose in the community, and we can contribute when Elm core changes outcome in the future.

Hi @hmsk ,

thanks for opening this issue. :-)

Just to be clear I correctly understand what you want this function to do:

  1. The function would take a string and return a string. The input is the regular output of the Elm compiler as a string. The output the same compiled Elm code but converted to an ES module. Is that correct?

  2. Also can you tell me a bit more about your use case and what you are trying to do? Is working string-to-string better for you than a function that reads from an input file and writes to an output file? Why?

hmsk commented

Thanks for replying!

Correct! I'm intending to pass the output string from node-elm-compiler and expect it's ESM-ized.

The exact case is a plugin for vite. To bundle compiled .elm file into a built JS.
I found another project snowpack-elm-plugin which is for another JS bundler Snowpack and copying your code actually. I could do the same, but I prefer to import elm-esm as a module/source-of-truth as I mentioned.

Ah cool, I was suspecting it had to be for some kind of plugin.

I've knows snowpack but I haven;t heard about Vite before you mentioned it. Good to know. :-)

I think the function that you want already exists, it just isn't exposed yet. Should be easy do if you need it as a NodeJS export.

If you need it as an ES6 export I think I may have to do some extra work.

Ah from your first comment it looks like you want the function as a ES Module and not CommonJS. I am not 100% sure how that works. I am thinking about providing both the CommonJS and ES Module export as separate module and declare them in the package.json like this:

{
  "main": "./common-js-export.js",
  "module":  "./es-module-export.js"
}

Do you think that would work?

Or maybe it would be best to add something like rollup which generates the correct outputs.

Tried to read a bit about how to use ES6 Modules with Node. The docs are a mess and the support is still experimental https://nodejs.org/api/packages.html#packages_dual_commonjs_es_module_packages

hmsk commented

Ah, my sample code was intending on TypeScript, that means CJS vs ESM doesn't matter for me and I just expected it's a named export then. At least I'm not going to use the function in ES env actually. So not pure ESM is required.

To make changes on your repo minimum, how's about separating the function into another file and export through CJS style module.exports? Then the main script can import with require, and npm user like me can also import/require with const { toESM } = require('elm-esm/to-esm')

Ah great, if CJS is good enough for you then this is an easy thing to do. Will start implementing now. 👍

Allright it's published. https://github.com/ChristophP/elm-esm#nodejs-usage

Let me know if this works for you.

hmsk commented

That's perfect, my small wrapping for IIFE is completely naturalized by esm-elm 🎉 🎉
hmsk/vite-plugin-elm@ad53d3b#diff-a2a171449d862fe29692ce031981047d7ab755ae7f84c707aef80701b3ea0c80L11

Thanks for your generous and immediate implementation!

Awesome glad this is already put to use. 👍
I like your truck with calling the IIFE und getting the output that way. Maybe this is a more reliable way than the regexes I am using.