effekt icon indicating copy to clipboard operation
effekt copied to clipboard

Emit CommonJS in JS backends

Open jiribenes opened this issue 1 year ago • 2 comments

Currently, the commonjs export produces the following export at the end:

module.exports = { main: () => main_1394().run() };

Unfortunately, browsers use a completely different module system so this produces a crash at runtime (as module doesn't exist).

Alternative 1

Let's hot-fix that by generating the following export (or a similar one) which works both in a browser and in Node.JS:

(typeof module != 'undefined' && module !== null ? module : {}).exports = $MODULE_NAME = {
  main: () => main_1435().run()
}

[where $MODULE_NAME is the name of our module]

🪄 Here's the `sed` call needed
sed -i'' -e 's/module.exports/(typeof module != "undefined" \&\& module !== null ? module : {}).exports = $MODULE_NAME/g' out/$MYFILE.js

Here's the code that would need to be changed: https://github.com/effekt-lang/effekt/blob/6f8973ae77e4962b67b3cb626142fab7430a6cd8/effekt/shared/src/main/scala/effekt/generator/js/Tree.scala#L46-L48

Alternative 2

Let's use ES modules instead! They have been stable for about 15 years by now and work both in a browser and in Node*.

This way, we could also get rid of the following hack: https://github.com/effekt-lang/effekt/blob/6f8973ae77e4962b67b3cb626142fab7430a6cd8/effekt/js/src/test/scala/effekt/WebTests.scala#L29-L34

*The only issue is that for Node.JS, all of our files would have to have the .mjs extension...

jiribenes avatar Mar 04 '24 13:03 jiribenes

For context: at some point we generated several different module formats (which is the reason why this is still called commonjs

https://github.com/effekt-lang/effekt/blob/6f8973ae77e4962b67b3cb626142fab7430a6cd8/effekt/shared/src/main/scala/effekt/generator/js/Tree.scala#L33

It shouldn't be too hard to first hotfix and then implement Alternative 2.

It might also be relevant that the standalone compilation mode now is whole program. That is, we do not generate separate files that need to be linked when compiling to JS. This is only enabled for the website.

b-studios avatar Mar 04 '24 14:03 b-studios

Let's please implement Alternative 2 with .mjs file extensions.

b-studios avatar Mar 12 '24 16:03 b-studios