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

Element type is invalid error due to @mui/icons-material with react integration when running astro build #6512

Closed
1 task done
vemonet opened this issue Mar 11, 2023 · 5 comments

Comments

@vemonet
Copy link

vemonet commented Mar 11, 2023

What version of astro are you using?

2.1.0

Are you using an SSR adapter? If so, which one?

None

What package manager are you using?

Yarn 3 usually, but here all of them out of dispair!

What operating system are you using?

Linux Fedora 37

What browser are you using?

Firefox and Chromium, but this is not relevant, error happens at build time

Describe the Bug

Hi, I am trying to build an app with Astro + ReactJS + mui (material UI for react).

I used the create astro command to create the repo and add the react integration. I am trying to build a generic static website (with no integration to any provider)

How to reproduce

Not sure how to use astro.new and stackblitz tools, but everyone knows well git, so I put the code to reproduce on git! You can find the complete code to reproduce the issue here: https://github.com/MaastrichtU-IDS/knowledge-collaboratory/tree/astro-experiment

I made it really simple and succinct to try to narrow down where the issue comes from: there is just a basic navbar, main page and footer, I also removed the mui theme setup

You can easily try it running those commands, dev should work and build should fail:

git clone -b astro-experiment https://github.com/MaastrichtU-IDS/knowledge-collaboratory
cd knowledge-collaboratory
yarn
yarn dev
yarn build

Setup versions

  • Fedora 37
  • Node v18.13.0 and v16.17.1
  • yarn 3.4.1 and 1.22.19
  • npm 8.19.3
  • pnpm 7.29.1
  • astro ^2.1.0
  • react ^18.0.0
  • mui ^5.11.12

With yarn 3 and node 18

It works well with yarn dev and does not show any error or warning in the terminal or console

But if I try to build with yarn build I am getting an error emStyled is not a function

Click here to see the full error output
09:47:46 AM [content] No content directory found. Skipping type generation.
09:47:46 AM [build] output target: static
09:47:46 AM [build] Collecting build info...
09:47:46 AM [build] Completed in 203ms.
09:47:46 AM [build] Building static entrypoints...
09:47:49 AM [build] Completed in 2.68s.

 building client 
Completed in 1.87s.


 generating static routes 
 error   emStyled is not a function
TypeError: emStyled is not a function
    at styled$3 (file:///home/vemonet/develop/sandbox/astro-toast/dist/chunks/pages/all.b256aa7e.mjs:705:25)
    at file:///home/vemonet/develop/sandbox/astro-toast/dist/chunks/pages/all.b256aa7e.mjs:2027:35
    at file:///home/vemonet/develop/sandbox/astro-toast/dist/chunks/pages/all.b256aa7e.mjs:2378:38
    at ModuleJob.run (node:internal/modules/esm/module_job:194:25)

I did some research and unfortunately could not find a lot of issues regarding emStyled is not a function. And none of those issues responses were explaining the actual problem (it is usually "just update lib X to version Y to fix it")

With npm or yarn 1

Running dev works, so I tried running the build script with npm run and yarn v1 (yarn 3 has changed a lot from yarn 1 and seems to do a lot of things differently which is confusing, e.g. the cryptic error message it gave above).

I also tried using node 16 and node 18 (cf. below for exact versions used). In this case we get a different error, a bit more explicit, which seems to be related to react-dom :

 generating static routes 
▶ src/pages/index.astro
 error   Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object.
  File:
    /home/vemonet/develop/translator/knowledge-collaboratory/node_modules/react-dom/cjs/react-dom-server.node.production.min.js:77:77
  Code:
    76 | b,d);return;case $b:c=c.type;d=Wc(c,d);Xc(a,b,c,d,f);return;case Vb:f=d.children;c=c._context;d=d.value;e=c._currentValue;c._currentValue=d;g=P;P=d={parent:g,depth:null===g?0:g.depth+1,context:c,parentValue:e,value:d};b.context=d;Z(a,b,f);a=P;if(null===a)throw Error("Tried to pop a Context at the root of the app. This is a bug in React.");d=a.parentValue;a.context._currentValue=d===ec?a.context._defaultValue:d;a=P=a.parent;b.context=a;return;case Wb:d=d.children;d=d(c._currentValue);Z(a,b,d);return;
    > 77 | case ac:f=c._init;c=f(c._payload);d=Wc(c,d);Xc(a,b,c,d,void 0);return}throw Error("Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: "+((null==c?c:typeof c)+"."));}}
         |                                                                             ^
      78 | function Z(a,b,c){b.node=c;if("object"===typeof c&&null!==c){switch(c.$$typeof){case Qb:Xc(a,b,c.type,c.props,c.ref);return;case Rb:throw Error("Portals are not currently supported by the server renderer. Render them conditionally so that they only appear on the client render.");case ac:var d=c._init;c=d(c._payload);Z(a,b,c);return}if(qa(c)){$c(a,b,c);return}null===c||"object"!==typeof c?d=null:(d=fc&&c[fc]||c["@@iterator"],d="function"===typeof d?d:null);if(d&&(d=d.call(c))){c=d.next();if(!c.done){var f=
      79 | [];do f.push(c.value),c=d.next();while(!c.done);$c(a,b,f)}return}a=Object.prototype.toString.call(c);throw Error("Objects are not valid as a React child (found: "+("[object Object]"===a?"object with keys {"+Object.keys(c).join(", ")+"}":a)+"). If you meant to render a collection of children, use an array instead.");}"string"===typeof c?(d=b.blockedSegment,d.lastPushedText=Aa(b.blockedSegment.chunks,c,a.responseState,d.lastPushedText)):"number"===typeof c&&(d=b.blockedSegment,d.lastPushedText=Aa(b.blockedSegment.chunks,
      80 | ""+c,a.responseState,d.lastPushedText))}function $c(a,b,c){for(var d=c.length,f=0;f<d;f++){var e=b.treeContext;b.treeContext=rc(e,d,f);try{Yc(a,b,c[f])}finally{b.treeContext=e}}}
  Stacktrace:
Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object.
    at Xc (/home/vemonet/develop/translator/knowledge-collaboratory/node_modules/react-dom/cjs/react-dom-server.node.production.min.js:77:77)
    at Z (/home/vemonet/develop/translator/knowledge-collaboratory/node_modules/react-dom/cjs/react-dom-server.node.production.min.js:78:89)

This error seems to point that an import is not done properly in the react-dom module. But I never use react-dom in my code, all the explicit imports to react are import React from "react"; or importing @mui/material components

With pnpm

How convenient that we have so many npm package managers! With pnpm the error comes directly when running pnpm dev (nice consistency)

On node 16 pnpm embarassingly fails to do basic maths as it tells me that 16.17.1 is not superior or equal to 16.12.0

Node.js v16.17.1 is not supported by Astro!
Please upgrade Node.js to a supported version: ">=16.12.0"

Then on node 18 pnpm forces me to install an unused dependency of a dependency, and then fails to find it (for a dependency which does not cause issues with npm and yarn anyway).

Click here to see the full error output
> astro dev

Error: Your application tried to access vscode-textmate, but it isn't declared in your dependencies; this makes the require call ambiguous and unsound.

Required package: vscode-textmate
Required by: /home/vemonet/develop/translator/knowledge-collaboratory/node_modules/.pnpm/[email protected]/node_modules/shiki/dist/

Require stack:
- /home/vemonet/develop/translator/knowledge-collaboratory/node_modules/.pnpm/[email protected]/node_modules/shiki/dist/index.js
    at require$$0.Module._resolveFilename (/home/vemonet/develop/translator/knowledge-collaboratory/.pnp.cjs:15384:13)
    at require$$0.Module._load (/home/vemonet/develop/translator/knowledge-collaboratory/.pnp.cjs:15234:42)
    at Module.require (node:internal/modules/cjs/loader:1105:19)
    at require (node:internal/modules/cjs/helpers:103:18)
    at Object.<anonymous> (/home/vemonet/develop/translator/knowledge-collaboratory/node_modules/.pnpm/[email protected]/node_modules/shiki/dist/index.js:6:22)
    at Module._compile (node:internal/modules/cjs/loader:1218:14)
    at Module._extensions..js (node:internal/modules/cjs/loader:1272:10)
    at require$$0.Module._extensions..js (/home/vemonet/develop/translator/knowledge-collaboratory/.pnp.cjs:15428:33)
    at Module.load (node:internal/modules/cjs/loader:1081:32)
    at require$$0.Module._load (/home/vemonet/develop/translator/knowledge-collaboratory/.pnp.cjs:15247:22)
 ELIFECYCLE  Command failed with exit code 1.

Questions

Note that yarn build was working fine with the template generated by create astro . And from the npm run build output it seems like the issue comes react-dom-server

Anyone has an idea why astro fails to build? Why does it shows errors related to the react-dom when I don't use it? How could this be solved? Do I need to add specific configuration to the astro.config.mjs? Maybe to fix the react-dom configuration

Thanks a lot for this beautifully crafted tool!

Link to Minimal Reproducible Example

https://github.com/MaastrichtU-IDS/knowledge-collaboratory/tree/astro-experiment

Participation

  • I am willing to submit a pull request for this issue.
@vemonet vemonet changed the title Error when running astro build for a basic app with react integration and material ui components Error seemingly related to react-dom when running astro build for a basic app with react integration and material ui components Mar 11, 2023
@vemonet
Copy link
Author

vemonet commented Mar 11, 2023

I tracked down the issue to be showing up as soon as an icon from @mui/icons-material is imported and used, e.g.:

import SearchIcon from '@mui/icons-material/Search';

<SearchIcon />

The error message is Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object.

Click here to see the full error output
 error   Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object.
  File:
    /home/vemonet/develop/sandbox/astro-react/node_modules/react-dom/cjs/react-dom-server.node.production.min.js:77:77
  Code:
    76 | b,d);return;case $b:c=c.type;d=Wc(c,d);Xc(a,b,c,d,f);return;case Vb:f=d.children;c=c._context;d=d.value;e=c._currentValue;c._currentValue=d;g=P;P=d={parent:g,depth:null===g?0:g.depth+1,context:c,parentValue:e,value:d};b.context=d;Z(a,b,f);a=P;if(null===a)throw Error("Tried to pop a Context at the root of the app. This is a bug in React.");d=a.parentValue;a.context._currentValue=d===ec?a.context._defaultValue:d;a=P=a.parent;b.context=a;return;case Wb:d=d.children;d=d(c._currentValue);Z(a,b,d);return;
    > 77 | case ac:f=c._init;c=f(c._payload);d=Wc(c,d);Xc(a,b,c,d,void 0);return}throw Error("Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: "+((null==c?c:typeof c)+"."));}}
         |                                                                             ^
      78 | function Z(a,b,c){b.node=c;if("object"===typeof c&&null!==c){switch(c.$$typeof){case Qb:Xc(a,b,c.type,c.props,c.ref);return;case Rb:throw Error("Portals are not currently supported by the server renderer. Render them conditionally so that they only appear on the client render.");case ac:var d=c._init;c=d(c._payload);Z(a,b,c);return}if(qa(c)){$c(a,b,c);return}null===c||"object"!==typeof c?d=null:(d=fc&&c[fc]||c["@@iterator"],d="function"===typeof d?d:null);if(d&&(d=d.call(c))){c=d.next();if(!c.done){var f=
      79 | [];do f.push(c.value),c=d.next();while(!c.done);$c(a,b,f)}return}a=Object.prototype.toString.call(c);throw Error("Objects are not valid as a React child (found: "+("[object Object]"===a?"object with keys {"+Object.keys(c).join(", ")+"}":a)+"). If you meant to render a collection of children, use an array instead.");}"string"===typeof c?(d=b.blockedSegment,d.lastPushedText=Aa(b.blockedSegment.chunks,c,a.responseState,d.lastPushedText)):"number"===typeof c&&(d=b.blockedSegment,d.lastPushedText=Aa(b.blockedSegment.chunks,
      80 | ""+c,a.responseState,d.lastPushedText))}function $c(a,b,c){for(var d=c.length,f=0;f<d;f++){var e=b.treeContext;b.treeContext=rc(e,d,f);try{Yc(a,b,c[f])}finally{b.treeContext=e}}}
  Stacktrace:
Error: Element type is invalid: expected a string (for built-in components) or a class/function (for composite components) but got: object.
    at Xc (/home/vemonet/develop/sandbox/astro-react/node_modules/react-dom/cjs/react-dom-server.node.production.min.js:77:77)
    at Z (/home/vemonet/develop/sandbox/astro-react/node_modules/react-dom/cjs/react-dom-server.node.production.min.js:78:89)
    at Yc (/home/vemonet/develop/sandbox/astro-react/node_modules/react-dom/cjs/react-dom-server.node.production.min.js:81:98)
    at $c (/home/vemonet/develop/sandbox/astro-react/node_modules/react-dom/cjs/react-dom-server.node.production.min.js:80:140)

Which seems to point at an issue with @mui/icons-material imports

So I tried to edit the vite build rollup config in astro.config.mjs to add the commonJS plugin, in case there was issues with @mui/icons-material importing CJS modules, but I still get the same error

import { defineConfig } from 'astro/config';
import react from "@astrojs/react";
import commonjs from '@rollup/plugin-commonjs';

export default defineConfig({
  integrations: [react()],
  vite: {
    build: {
      rollupOptions: {
        plugins: [
          commonjs(),
        ],
      },
    },
  }
});

Anyone has an idea how this issue with @mui/icons-material could be resolved?

@vemonet vemonet changed the title Error seemingly related to react-dom when running astro build for a basic app with react integration and material ui components Element type is invalid error due to @mui/icons-material with react integration when running astro build Mar 11, 2023
@vemonet
Copy link
Author

vemonet commented Mar 11, 2023

I finally found the root of my problem, it is related to issue #4432

There is a proposed workaround to use client:only='react' for the problematic components (the one using mui icons in my case), it is not ideal since it would be nice to have assets like icons preloaded, but let's give it a try!

Now the yarn build completes, but if we try to open the built website the components we defined with client:only are not showing, and we have the following error in the console.log:

Uncaught (in promise) TypeError: cr is not a function

Which can be fixed by completely removing the @mui/icons-material component and directly using svg icons (it will be better on the long run anyway)

So Astro seems to properly support most of @mui/material, apart from @mui/icons-material, which can easily be replaced by directly using CSS and SVG for the icons

I guess there are still some work to do to fully integrate existing popular UI libraries from external frameworks, but what we have already is really promising! Thanks a lot!

@vemonet vemonet closed this as completed Mar 11, 2023
@ericpedia
Copy link

ericpedia commented Apr 7, 2023

I'm having the same issue, using React components from a Vite/TS project containing Material UI icons used as described above (import SearchIcon from '@mui/icons-material/Search' ... <SearchIcon />).

astro build fails with the error above if the component is used as anything but client:only. However, I have components with this issue that I want to use this as a pre-rendered static or client:load components. It works fine if I remove all Material icons.

Is there any workaround for this that doesn't require using a client:only component?

  • Versions: astro 2.2.0, @astrojs/react: 2.1.1
  • Package manager: npm
  • React components are from project using:
    • Vite 4.1.0, TypeScript 4.9.3, React 18.2.0

@QingXia-Ela
Copy link
Contributor

I finally found the root of my problem, it is related to issue #4432

There is a proposed workaround to use client:only='react' for the problematic components (the one using mui icons in my case), it is not ideal since it would be nice to have assets like icons preloaded, but let's give it a try!

Now the yarn build completes, but if we try to open the built website the components we defined with client:only are not showing, and we have the following error in the console.log:

Uncaught (in promise) TypeError: cr is not a function

Which can be fixed by completely removing the @mui/icons-material component and directly using svg icons (it will be better on the long run anyway)

So Astro seems to properly support most of @mui/material, apart from @mui/icons-material, which can easily be replaced by directly using CSS and SVG for the icons

I guess there are still some work to do to fully integrate existing popular UI libraries from external frameworks, but what we have already is really promising! Thanks a lot!

@ericpedia Hey guys, you can try NoSsr component from mui like this example:

import ExpandMoreIcon from '@mui/icons-material/ExpandMore'
import NoSsr from '@mui/material/NoSsr'

const icon = (
  // prevent to use ssr render
  <NoSsr>
    <ExpandMoreIcon className="text-white" />
  </NoSsr>
)

It's work for me!

@Mayur290
Copy link

Mayur290 commented Oct 7, 2024

I finally found the root of my problem, it is related to issue #4432

There is a proposed workaround to use client:only='react' for the problematic components (the one using mui icons in my case), it is not ideal since it would be nice to have assets like icons preloaded, but let's give it a try!

Now the yarn build completes, but if we try to open the built website the components we defined with client:only are not showing, and we have the following error in the console.log:

Uncaught (in promise) TypeError: cr is not a function

Which can be fixed by completely removing the @mui/icons-material component and directly using svg icons (it will be better on the long run anyway)

So Astro seems to properly support most of @mui/material, apart from @mui/icons-material, which can easily be replaced by directly using CSS and SVG for the icons

I guess there are still some work to do to fully integrate existing popular UI libraries from external frameworks, but what we have already is really promising! Thanks a lot!

interop: 'auto', solved it for me.

check here: vitejs/vite#16201

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