vitejs / vite

Next generation frontend tooling. It's fast!
http://vite.dev
MIT License
68.49k stars 6.18k forks source link

Default exports of some libs causing class/function errors #15567

Closed mkilpatrick closed 9 months ago

mkilpatrick commented 10 months ago

Describe the bug

I'm not sure if this is a Vite error specifically, but I've been seeing the same error arise from some CJS libs. This occurs in SSR mode.

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

It occurs from react-slick - https://github.com/akiran/react-slick/issues/2206 and @material-tailwind-react -https://github.com/creativetimofficial/material-tailwind/issues/558

You can get around the issue by dynamically importing the library to only run client-side, but that's not an optimal solution.

Reproduction

https://stackblitz.com/edit/vitejs-vite-bs4gbs?file=server.js

Steps to reproduce

No response

System Info

System:
    OS: Linux 5.0 undefined
    CPU: (8) x64 Intel® Core™ i9-9880H CPU @ 2.30GHz
    Memory: 0 Bytes / 0 Bytes
    Shell: 1.0 - /bin/jsh
  Binaries:
    Node: 18.18.0 - /usr/local/bin/node
    Yarn: 1.22.19 - /usr/local/bin/yarn
    npm: 9.4.2 - /usr/local/bin/npm
    pnpm: 8.14.0 - /usr/local/bin/pnpm
  npmPackages:
    @vitejs/plugin-react: ^4.2.1 => 4.2.1 
    vite: ^5.0.8 => 5.0.11

Used Package Manager

npm

Logs

No response

Validations

stackblitz[bot] commented 10 months ago

Fix this issue in StackBlitz Codeflow Start a new pull request in StackBlitz Codeflow.

XiSenao commented 10 months ago

You can try using it in the following way.

import R from '@material-tailwind/react';
export async function render() {
  const foo = (
    <>
      <R.Collapse open>
        <div>HII</div>
      </R.Collapse>
    </>
  );

  return ReactDOMServer.renderToString(foo);
}
mkilpatrick commented 10 months ago

That doesn't work, at least for react-slick. ReferenceError: Slider is not defined

XiSenao commented 10 months ago

this could be a problem and this solution is not universal at the same time.

sapphi-red commented 9 months ago

For @material-tailwind/react, the way @XiSenao said is the correct way. For react-slick, you'll need to access it by

import SlickDefault from 'react-slick'
const Slick = SlickDefault.default

This is because react-slick exports it by

"use strict";

var _slider = _interopRequireDefault(require("./slider"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }

exports["default"] = _slider["default"];

This matches how Node.js works. https://nodejs.org/api/esm.html#interoperability-with-commonjs:~:text=When%20importing%20CommonJS%20modules%2C%20the%20module.exports%20object%20is%20provided%20as%20the%20default%20export.%20Named%20exports%20may%20be%20available%2C%20provided%20by%20static%20analysis%20as%20a%20convenience%20for%20better%20ecosystem%20compatibility

Closing as this is not a bug in Vite.