Material UI - 元素类型无效:应为字符串(对于内置组件)或 class/function(对于复合组件)但得到:对象

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

你好吗?

我有一个带有 Webpack 和 Babel 的 React 项目,我正在尝试添加 Material UI (https://mui.com/) 组件,但是,当我导入 MUI 组件到我的项目中我得到下一个错误:

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

我发现的解决方法 是添加 ".default" 导入,但我不明白为什么我不这样做能够以传统方式导入它。

这是产生错误的测试组件代码:

const React = require("react");
const Button = require("@mui/material/Button");

const Navbar = () => {
  return <Button variant="contained">Contained</Button>;
};

module.exports = Navbar;

这是我的 .babelrcwebpack.config 代码:

{
  "presets": ["@babel/preset-env", "@babel/preset-react"]
}

const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");

module.exports = {
  output: {
    path: path.join(__dirname, "/dist"),
    filename: "index.bundle.js",
  },
  devServer: {
    port: 8443,
  },
  module: {
    rules: [
      {
        test: /\.(js|jsx)$/,
        exclude: /node_modules/,
        use: {
          loader: "babel-loader",
        },
      },
      {
        test: /\.css$/,
        use: [MiniCssExtractPlugin.loader, "css-loader"],
      },
      {
        test: /\.scss$/,
        use: [MiniCssExtractPlugin.loader, "css-loader", "sass-loader"],
      },
    ],
  },
  plugins: [
    new HtmlWebpackPlugin({ template: "./src/index.html" }),
    new MiniCssExtractPlugin(),
  ],
};

有谁知道我做错了什么?我知道这可能很愚蠢,但我应该能够按照 MUI 文档中所述的“正常”方式导入这些组件,相反,我必须使用“.default”方式导入它们。

提前致谢,抱歉我的英语不好。

MUI 旨在与 EcmaScript 模块 (ESM) 一起使用,而不是与 CommonJs (CJS) 一起使用。如果您确实想使用 CJS,您可以这样做,但由于 ESM 和 CJS 不是 100% 兼容的,您将需要一些解决方法。

能够使用 CJS 语法导入

const Button = require("@mui/material/Button");

MUI 需要使用

导出(使用 CJS)
module.exports = function Button(props) { ... }

但是 Button 模块 的整个导出是 Button 组件,模块无法导出任何其他内容。 因此,所有内容都导出为命名导出,组件本身以名称 default.

导出

ESM 导入理解 default,您可以使用缩写形式,但 CJS 只导入 javascript 对象,即 { default: ... }.

一个

@mui/material/Button/index.js 出口:

export { default } from './Button';

可以使用 CJS 导入:

  • const Button = require("@mui/material/Button").default;,或
  • const Button = require("@mui/material/Button/index").default;

B

@mui/material/index.js 出口:

export { default as Button } from './Button';
export * from './Button';

可以使用 CJS 导入:

  • const Button = require("@mui/material/index").Button;

( export * 只是“来自 Button 的所有内容”,但没有从 Button 导出任何其他内容, 除了例如getButtonUtilityClass 来自 buttonClasses,但我们对此不感兴趣)