trypurescript
trypurescript copied to clipboard
User-inputted module's `main` call called twice
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?
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
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.

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
Yup, that's probably it.
Still seeing this issue in Firefox (104.0b10 (64-bit))
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-shimsor 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 therenderissue in Firefox - Change
setInnerHTMLand thereforerenderto be idempotent and set the content (and not append to it). This would change the behavior, in case you intentionally have multiplerendercalls. But if possible, this would be the easiest and likely (for the user) the most robust change.
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.
Is the last suggested option viable?