Feliz: Error after renaming React Component: Uncaught Error: Element type is invalid: expected a string

Created on 16 Mar 2021  ·  13Comments  ·  Source: Zaid-Ajaj/Feliz

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

All 13 comments

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:

  1. Change 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

  1. Change HelloWorld -> HelloWorlds in Main.fs: compilation successful, but React fails and the error is logged to dev console

  2. 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

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Zaid-Ajaj picture Zaid-Ajaj  ·  6Comments

nojaf picture nojaf  ·  4Comments

l3m picture l3m  ·  7Comments

Dzoukr picture Dzoukr  ·  9Comments

cmeeren picture cmeeren  ·  6Comments