trypurescript icon indicating copy to clipboard operation
trypurescript copied to clipboard

User-inputted module's `main` call called twice

Open JordanMartinez opened this issue 3 years ago • 7 comments

Opening up https://try.purescript.org/, I see that the module's main function is called twice, again. I thought this was fixed by #279, but maybe the recent es-module-shims update to 1.5.9 broke something?

JordanMartinez avatar Jul 23 '22 16:07 JordanMartinez

In case the issue has its root cause in es-module-shims there are two commits in recent releases that mention "initialization". Maybe interesting.

https://github.com/guybedford/es-module-shims/compare/1.5.9...1.5.12

Update: I don't think this will fix the issue.

I could reproduce the issue in Firefox, but not in Chrome. Could be browser or version related (e.g. one needs shims and the other doesn't).

https://discord.com/channels/864614189094928394/869607074152206397/1007075896005492837

andys8 avatar Aug 10 '22 23:08 andys8

I think I found the issue:

The docs of es-module-shims have this paragraph:

This execution failure is a feature - it avoids the polyfill causing double execution. The first import being a bare specifier in the pattern above is important to ensure this.

This is not the case for try.purescript.org. Adding import react from 'react'; as the first import would indeed lead to a working example in both Chrome and Firefox.

image

An alternative described in the docs is to activate shimMode.

window.esmsInitOptions = { shimMode: true }

Shim mode is an alternative to polyfill mode and doesn't rely on native modules erroring - instead it is triggered by the existence of any

andys8 avatar Aug 11 '22 00:08 andys8

Yup, that's probably it.

JordanMartinez avatar Aug 12 '22 20:08 JordanMartinez

Still seeing this issue in Firefox (104.0b10 (64-bit))

image

pete-murphy avatar Aug 27 '22 17:08 pete-murphy

Cool, I see it both working (locally, 25a909548d9aca2879cae81dba0e6c3b7d7a633b) and not working (try.purescript.org) at the same time using Firefox 103. Either there is a difference (not same code state, but I don't think so because the new comment is part of the html), frames behave differently on the domain compared to localhost or its depending on (load) times or other external influence.

https://user-images.githubusercontent.com/13085980/187042238-a1a67193-c6c2-4066-b142-6e701803030b.mp4

That makes it harder to reproduce locally, but the main issue is still the combination of iframes, settings listeners once, and es-module-shims intentionally crashing and executing scripts again. This combined with the fact that render is using setInnerHTML which doesn't set - but append - is brittle.

Options

  • Mess with es-module-shims or a larger change regarding listeners (once: true) and iframes
  • Using a different solution for modules, adding npm dependencies differently (but probably not easy to find a better alternative)
  • Add an additional script, importing a module, hitting the intentional error earlier (<script type="module">import uuid from 'uuid';</script>). Without being able to reproduce locally, I don't know if this would fix the render issue in Firefox
  • Change setInnerHTML and therefore render to be idempotent and set the content (and not append to it). This would change the behavior, in case you intentionally have multiple render calls. But if possible, this would be the easiest and likely (for the user) the most robust change.

andys8 avatar Aug 27 '22 17:08 andys8

For what it's worth, every time I've tried fixing this locally, it appeared to be fixed locally only for it to not be fixed on the actual site. Hence, it's hard to know when this problem has actually been solved.

JordanMartinez avatar Aug 27 '22 19:08 JordanMartinez

Is the last suggested option viable?

andys8 avatar Aug 28 '22 21:08 andys8