Fable support for Feliz/React applications
See original GitHub issueHi there,
For a while now, we have been trying to integrate the react-refresh plugin into a React application with the Fable. I tried of bunch of configuration and non have worked so far 😞 I am really hoping you could give us guidelines as to how to make the integration work. I realize that you most likely aren’t familiar with Fable and its tool chain, so let me briefly explain how it works and what the problem is.
Fable integrates into webpack pretty much the same way typescript does with a specialized loader called fable-loader
, this loader generated Babel AST and is then handed off to webpack for bundling and minification. To build React applications, we use a binding library called Feliz which offers an API and glue code that internally calls React APIs. Feliz code looks a lot like its React equivalent, for example:
import ReactDOM from 'react-dom'
import React, { useState } from 'react';
function Counter() {
// Declare a new state variable, which we'll call "count"
const [count, setCount] = useState(0);
return (
<div>
<h1>{count}</h1>
<button onClick={() => setCount(count + 1)}>
Increment
</button>
</div>
);
}
ReactDOM.render(<Counter />, document.getElementById("root"))
Translates to this F# code
module App
open Feliz
let counter = React.functionComponent(fun () ->
let (count, setCount) = React.useState(0)
Html.div [
Html.h1 count
Html.button [
prop.text "Increment"
prop.onClick (fun _ -> setCount(count + 1))
]
])
ReactDOM.render(counter, document.getElementById "root")
However, I am guessing that the code generated by Fable and especially by Feliz is something that this plugin cannot detect changes in for some reason. This is why I created a reproduction sample to demonstrate the issue
https://github.com/Zaid-Ajaj/react-fast-refresh-repro
UPDATE: the repository now includes the generated JS code (Babel AST before minification or bundling) within the directory called
compiled-js
which you can inspect without having to run or build anything
This repository includes a simplified React application built with Feliz and can be compiled with Fable. It uses webpack and it includes this plugin. To run application you simply execute npm install
and npm start
but unfortunately you need dotnet 3.1+ installed on your system
If it is not an option for you install dotnet to try out the sample, please let me know and I will figure something out
Now when we are running the application using npm start
and we make changes to the file in src/App.fs
where there is a simple counter function component, the changes are not detected and instead the whole page is refreshed. We are not sure why this is happening and we could use some advice about our generated code. It could also be something silly we overlooked in the configuration of the plugin.
I added a npm script called debug-compiled-js
which compiles the application into its intermediate state as the output of the Babel AST before it is handed off to webpack, you can run this script using npm run debug-compiled-js
and you will see the generated App.js
file in the compiled-js
directory.
I would really really appreciate it if you could take a look 🙏 see if we did the configuration the right way and whether we should change or simplify the way our generated JS looks like so that this plugin and future iterations of it can work with Fable.
Thanks a lot in advance ❤️
Zaid
Issue Analytics
- State:
- Created 3 years ago
- Comments:23 (1 by maintainers)
Top GitHub Comments
I believe (but I am not entirely sure) that the reasoning has to do with the fact that we are using a function that is written in F# as input for another function used in JS: functions written in F# are automatically curried so I think Fable uncurries the function at call site of external JS APIs to make them adhere to standard JS conventions while allowing F# devs to write functions the same way they are used to. At least that is how I remember it
In the case of
fun () ->
the currying/uncurrying might totally unnecessary but I am can’t say for sure in all casesDan - thanks for stepping in while I was away busy with other stuff!
I think I’ll add some FAQ to the README to clarify some of these underlying assumptions.
I’m not sure about this.
.fs
as you’ve shown to not allow any js files sneak in (explicitly)