styled-components / xstyled

A utility-first CSS-in-JS framework built for React. πŸ’…πŸ‘©β€πŸŽ€βš‘οΈ
https://xstyled.dev
MIT License
2.27k stars 107 forks source link

Next js error "Error: Element type is invalid: expected a string" #338

Closed joseDaKing closed 2 years ago

joseDaKing commented 2 years ago

πŸ› Bug Report

I get this error in next js 12, and I have followed the Next js instruction on the website. The problem might be that next js 12 uses swc as compiler and not babel

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.

To Reproduce

Create next js app and try to use xstyled

Expected behavior

It should work without any problem

Run npx envinfo --system --binaries --npmPackages @xstyled/system,@xstyled/styled-components,styled-components --markdown --clipboard

Paste the results here:

# System:
 - OS: Windows 10 10.0.19043
 - CPU: (8) x64 Intel(R) Core(TM) i5-8250U CPU @ 1.60GHz
 - Memory: 1.20 GB / 7.88 GB
## Binaries:
 - Node: 16.13.1 - C:\Program Files\nodejs\node.EXE     
 - npm: 7.17.0 - C:\Program Files\nodejs\npm.CMD        
## npmPackages:
 - @xstyled/styled-components: ^3.3.0 => 3.3.0
 - styled-components: ^5.3.3 => 5.3.3
jguddas commented 2 years ago

Can reproduce, createCss(system).x.div is undefined on the server and defined on the client.

I did get it to work using a not so clean workaround https://stackblitz.com/edit/nextjs-9rrzrs?file=pages/index.js

jguddas commented 2 years ago

Everywhere in node_modules/@xstyled/styled-components/dist/index.esm.js other than for createX we use scStyledInterop instead of scStyled, I tried changing this by hand, and it worked :man_shrugging:

    const baseStyled = scStyledInterop(component);
    return getCreateStyle(config ? baseStyled.withConfig(config) : baseStyled, css, generator);
  };
};
const createStyled = (generator) => {
  const css = createCssFunction(generator);
  const styled = createBaseStyled(css);
  const xstyled = createBaseStyled(css, generator);
  styled.box = xstyled("div");
  Object.keys(scStyledInterop).forEach((key) => {
    styled[key] = styled(key);
    styled[`${key}Box`] = xstyled(key);
  });
  return styled;
};

const createX = (generator) => {
  const xstyled = createBaseStyled(createCssFunction(generator), generator);
  const x = {};
- Object.keys(scStyled).forEach((tag) => {
+ Object.keys(scStyledInterop).forEach((tag) => {
    x[tag] = xstyled(tag)``;
  });
  return x;
};