Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
theimowski opened this issue Mar 16, 2021 · 14 comments

Comments

@theimowski
Copy link

theimowski commented Mar 16, 2021

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

@Zaid-Ajaj
Copy link
Owner

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

@Zaid-Ajaj
Copy link
Owner

Looks like a Fable issue

@alfonsogarciacaro
Copy link
Contributor

Can you please try with 3.1.11? This is probably related to fable-compiler/Fable#2413

@Zaid-Ajaj
Copy link
Owner

I've confirmed that the issue is fixed as of v3.1.11 so @theimowski can you also give it a try?

@theimowski
Copy link
Author

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.

@Zaid-Ajaj
Copy link
Owner

@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?

@Zaid-Ajaj
Copy link
Owner

@theimowski I've crossposted the issue on react-refresh#330

@Zaid-Ajaj
Copy link
Owner

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

@theimowski
Copy link
Author

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.

@Zaid-Ajaj
Copy link
Owner

Zaid-Ajaj commented Mar 18, 2021

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?

@theimowski
Copy link
Author

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.

@Zaid-Ajaj
Copy link
Owner

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

@theimowski
Copy link
Author

I see - right, in that case it's fine.
The only issue then is what you described in pmmmwh/react-refresh-webpack-plugin#330

@MangelMaxime
Copy link
Contributor

I just happen to read this thread while searching for other stuff.

For information, since Fable 3.2.9 Fable will not emit JavaScript code if there is an F# compilation error.

However, if there is Fable compilation error (like missing replacements) it will still emit JavaScript code and so trigger Webpack or any tooling listening to the files.

fable-compiler/fable3-samples#10 (comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants