fable-compiler / Fable

F# to JavaScript, TypeScript, Python, Rust and Dart Compiler
http://fable.io/
MIT License
2.89k stars 295 forks source link

Strange error with fable watch #2478

Closed isaacabraham closed 9 months ago

isaacabraham commented 3 years ago

Description

I've been experimenting with ViteJS as an alternative method of bundling and running the client portion of SAFE Stack apps, and even I have managed to get something up and running. However, I've gotten stuck on one issue:

If I run my Fable app using dotnet fable --run vite everything is good, but as soon as I try to turn on watch mode on fable i.e. dotnet fable watch --run vite, I get a problem: although the compiler works and vite hooks in, the app in the browser doesn't do anything. In the console, I get the following call stack:

Uncaught ReferenceError: global is not defined
    at ../../node_modules/socketcluster-client/lib/sctransport.js (sctransport.js:7)
    at __require2 (chunk-EB7XYW2R.js?v=538e0e19:12)
    at ../../node_modules/socketcluster-client/lib/scclientsocket.js (scclientsocket.js:6)
    at __require2 (chunk-EB7XYW2R.js?v=538e0e19:12)
    at ../../node_modules/socketcluster-client/index.js (index.js:1)
    at __require2 (chunk-EB7XYW2R.js?v=538e0e19:12)
    at ../../node_modules/remotedev/lib/devTools.js (devTools.js:13)
    at __require2 (chunk-EB7XYW2R.js?v=538e0e19:12)
    at ../../node_modules/remotedev/lib/index.js (index.js:3)
    at __require2 (chunk-EB7XYW2R.js?v=538e0e19:12)

I have no clue what this is, but as soon as I revert to dotnet fable --run everything just works.

Repro code

I've not got a publicly available repo available but can make one. But before doing that, I just wanted to see if they are differences between fable --run and fable watch --run that you think could possibly cause this.

Related information

MangelMaxime commented 3 years ago

The main difference I see, is that when using --watch Fable is adding DEBUG compiler directives so depending on the libraries it is possible that the build between dotnet fable and dotnet fable --watch is not exactly the same.

For example, this is the case if you are using Elmish.HMR which have a lot of #if DEBUG directives

https://github.com/elmish/hmr/blob/master/src/hmr.fs#L168-L224

isaacabraham commented 3 years ago

Ah, thanks for that :-) So it's likely that this is something that e.g. Elmish HMR is spitting out or similar. What's the best way to move forward on this - should I just create a basic Fable Elmish app that is configured for vite to repro the issue?

alfonsogarciacaro commented 3 years ago

As @MangelMaxime says it may be Elmish.HMR not being compatible with Vite so you can try commenting out the open Elmish.HMR line and see if that makes the error go away in watch mode. I also see remotedev in the logs, which is used by Elmish.Debugger. I've stopped using the Elmish.Debugger because remotedev doesn't seem to be maintained any more and gives issues with new tooling. So you can also try commenting out the |> Program.withDebugger line and see if that helps.

alfonsogarciacaro commented 3 years ago

BTW, I've also been playing recently with Snowpack. Not sure what's the difference with ViteJS but if I'm not mistaken they follow the same idea of avoiding bundling in development to make hot reloading faster. I'm not sure if Elmish.HMR works but at least React state with the fast refresh plugin works (I assume also Feliz useElmish) if you use the [<Feliz.ReactComponent>] and follow their arbitrary rules as @MangelMaxime puts it ;)

isaacabraham commented 3 years ago

@alfonsogarciacaro I think that standard development mode in Vite doesn't bundle, but yes, let me try removing the debugging and explicit HMR and other stuff piece by piece to see what's changed.

alfonsogarciacaro commented 2 years ago

@isaacabraham Is this still an issue. Can you please try with latest Fable and Elmish.HMR and disabling Elmish.Debugger?

lukaszkrzywizna commented 9 months ago

@isaacabraham is this not related to the fact that vite doesn't define a global field?

MangelMaxime commented 9 months ago

@lukaszkrzywizna

Indeed, it is fixed when adding these lines to the index.html

<!-- Polyfill for remotedev -->
<script type="text/javascript">
    var global = global || window;
</script>

I am closing as there is nothing to do on Fable side.