Starting from scratch with Feliz template, I've made it run with npm start
and then renamed HelloWorld
React Component in App.fs
to HelloWorlds
.
In result Fable compiles fine without any warnings, but React complains in the runtime (nothing gets rendered):
Uncaught Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.
at createFiberFromTypeAndProps (react-dom.development.js?61bb:25058)
at createFiberFromElement (react-dom.development.js?61bb:25086)
at reconcileSingleElement (react-dom.development.js?61bb:14052)
at reconcileChildFibers (react-dom.development.js?61bb:14112)
at reconcileChildren (react-dom.development.js?61bb:16997)
at updateHostRoot (react-dom.development.js?61bb:17599)
at beginWork (react-dom.development.js?61bb:19077)
at HTMLUnknownElement.callCallback (react-dom.development.js?61bb:3945)
at Object.invokeGuardedCallbackDev (react-dom.development.js?61bb:3994)
at invokeGuardedCallback (react-dom.development.js?61bb:4056)
Seems it's some kind of caching issue - not sure if in fable itself or feliz plugin. After clearing .fable
directory it works fine
Hi @theimowski I've recently encountered this as well. I will need to look into it but maybe @alfonsogarciacaro knows more about it. Can you also try using latest Fable v3.1.10? the template is at 3.1.5
Looks like a Fable issue
Can you please try with 3.1.11? This is probably related to https://github.com/fable-compiler/Fable/issues/2413
I've confirmed that the issue is fixed as of v3.1.11 so @theimowski can you also give it a try?
It still doesn't fully work as expected in Fable 3.1.11.
Trying to investigate this a bit further:
HelloWorld
-> HelloWorlds
but only in App.fs
:Compiling src/App.fsproj...
F# compilation finished in 17ms
Fable compilation finished in 31ms
/Users/theimowski/sandbox/feliz/rename/src/Main.fs(9,1): (12,2) error FSHARP: A unique overload for method 'render' could not be determined based on type information prior to this program point. A type annotation may be needed.
Known types of arguments: 'a * Browser.Types.HTMLElement
Candidates:
- static member ReactDOM.render : element:(unit -> Fable.React.ReactElement) * container:Browser.Types.HTMLElement -> 'a0
- static member ReactDOM.render : element:Fable.React.ReactElement * container:Browser.Types.HTMLElement -> 'a (code 41)
/Users/theimowski/sandbox/feliz/rename/src/Main.fs(10,9): (10,19) error FSHARP: The value, constructor, namespace or type 'HelloWorld' is not defined. Maybe you want one of the following:
HelloWorlds (code 39)
Watching src
ℹ 「wdm」: Compiling...
⚠ 「wdm」: assets by status 3.64 MiB [cached] 1 asset
assets by path *.js 71.9 KiB
asset app.js 66.3 KiB [emitted] (name: app)
asset app.cf083007398aca78c7c4.hot-update.js 5.54 KiB [emitted] [immutable] [hmr] (name: app)
asset app.cf083007398aca78c7c4.hot-update.json 27 bytes [emitted] [immutable] [hmr]
Entrypoint app 3.71 MiB = vendors.js 3.64 MiB app.js 66.3 KiB app.cf083007398aca78c7c4.hot-update.js 5.54 KiB
cached modules 1.38 MiB [cached] 74 modules
runtime modules 29.3 KiB 13 modules
./src/App.fs.js 2.75 KiB [built] [code generated]
WARNING in ./src/Main.fs.js 8:35-45
export 'HelloWorld' (imported as 'HelloWorld') was not found in './App.fs.js' (possible exports: HelloWorlds)
webpack 5.14.0 compiled with 1 warning in 139 ms
ℹ 「wdm」: Compiled with warnings.
There's an FSHARP compilation error, but webpack compiles and treats the error as a warning, WDS refreshes the page and you can see the React error in subject rendered on screen
Change HelloWorld
-> HelloWorlds
in Main.fs
: compilation successful, but React fails and the error is logged to dev console
Refresh the page - works fine afterwards
This might be some kind of race condition issue, on Feliz template if you rename in both files at the same time, it will usually work fine, however on a slightly bigger project, when renaming the component I can see following behaviour in logs (note the warning in the middle):
Compiling src/Client/Client.fsproj...
F# compilation finished in 67ms
Compiled src/Client/App.fsℹ 「wdm」: Compiling...
⚠ 「wdm」: Hash: 615d2643d48416b2ff41
Version: webpack 4.43.0
Time: 456ms
Built at: 03/17/2021 9:30:04 PM
Asset Size Chunks Chunk Names
app.e781f5f7185376d5a0d3.hot-update.js 9.4 KiB app [emitted] [immutable] [hmr] app
app.js 4.69 MiB app [emitted] app
e781f5f7185376d5a0d3.hot-update.json 45 bytes [emitted] [immutable] [hmr]
index.html 670 bytes [emitted]
+ 1 hidden asset
Entrypoint app = vendors~app.js app.js app.e781f5f7185376d5a0d3.hot-update.js
[./src/Client/App.fs.js] 1.32 KiB {app} [built]
+ 382 hidden modules
WARNING in ./src/Client/App.fs.js 28:21-32
"export 'HelloWorlds' was not found in './Index.fs.js'
Child html-webpack-plugin for "index.html":
1 asset
Entrypoint undefined = index.html
4 modules
ℹ 「wdm」: Compiled with warnings.
Fable compilation finished in 1635ms
Compiled src/Client/Index.fsWatching src
ℹ 「wdm」: Compiling...
ℹ 「wdm」: Hash: 837f9683f0ac04dcc729
Version: webpack 4.43.0
Time: 820ms
Built at: 03/17/2021 9:30:06 PM
Asset Size Chunks Chunk Names
615d2643d48416b2ff41.hot-update.json 45 bytes [emitted] [immutable] [hmr]
app.615d2643d48416b2ff41.hot-update.js 141 KiB app [emitted] [immutable] [hmr] app
app.js 4.69 MiB app [emitted] app
index.html 670 bytes [emitted]
+ 1 hidden asset
Entrypoint app = vendors~app.js app.js app.615d2643d48416b2ff41.hot-update.js
[./src/Client/Index.fs.js] 29.5 KiB {app} [built]
+ 382 hidden modules
Child html-webpack-plugin for "index.html":
1 asset
Entrypoint undefined = index.html
4 modules
ℹ 「wdm」: Compiled successfully.
@theimowski I think this might actually be an edge case for the fast-refresh plugin where it should trigger a full page refresh upon changing the entry point file.
I need to confirm the theory sometime: the problem will not occur when the referenced component is not in the entry point file. So if you have App.fs -> Middle.fs -> Main.fs (entry point) and you only change App.fs or Middle.fs
Can you also try this out?
@theimowski I've crossposted the issue on react-refresh#330
The react-refresh occurs when using latest webpack so I rolled back to webpack v4 until the issue is resolved and published a working Feliz template (now with more example components) as of v3.6
Thanks - yes indeed using new feliz template the refresh issue is gone.
Don't you think it'd be better if F# compilation error failed the webpack refresh? Or is it something hard to achieve?
Back with Fable 2.* and webpack dev server, when there was an F# compile error, the refresh wouldn't be triggered.
Don't you think it'd be better if F# compilation error failed the webpack refresh? Or is it something hard to achieve?
It's not impossible: probably requires emitting JS code that _intentionally_ has some syntax errors to break what webpack is doing but I doubt anyone wants that (especially @alfonsogarciacaro) 😉
I think the current situation is fine because when webpack is emitting a warning, Fable is emitting an error which is a higher priority for the developer to fix. Once the Fable (compile) error is fixed, the webpack warning also disappears. Am I missing something?
My personal preference would be that a failing step results in not executing steps that follow - otherwise you might observe stuff refreshing in your browser and you might get fooled that everything is fine, while your F# code is actually not compiling.
But react-refresh will show you an error page in red with an error message on the browser even if the terminal shows a webpack warning
I see - right, in that case it's fine.
The only issue then is what you described in https://github.com/pmmmwh/react-refresh-webpack-plugin/issues/330