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;
这是我的 .babelrc 和 webpack.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
,但我们对此不感兴趣)
你好吗?
我有一个带有 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;
这是我的 .babelrc 和 webpack.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
,但我们对此不感兴趣)