[英]TypeScript + React: Element type is invalid: expected a string (for built-in components)
I realize that there are several questions related to this error floating around, but as far as I can tell this is a unique situation and not related to an incorrect import
statement. 我意识到有几个与此错误有关的问题,但据我所知这是一种独特的情况,与不正确的
import
语句无关。
I'm building a React
component library with TypeScript
and webpack
. 我正在使用
TypeScript
和webpack
构建一个React
组件库。
My directory structure: 我的目录结构:
- src
- index.ts
- components
- Button
- Button.tsx
- index.ts
- Button.css
- Button.d.css (generated by webpack plugin)
- package.json
- tsconfig.json
- webpack.config.js
- postcss.config.js
My tsconfig.json
: 我的
tsconfig.json
:
{
"compilerOptions": {
"allowSyntheticDefaultImports": true,
"module": "es2015",
"target": "es5",
"lib": ["es6", "dom"],
"sourceMap": true,
"allowJs": false,
"jsx": "react",
"moduleResolution": "node",
"rootDir": "src",
"outDir": "dist",
"noImplicitReturns": true,
"noImplicitThis": true,
"noImplicitAny": true,
"strictNullChecks": true,
"declaration": true
},
"include": [
"src/**/*"
],
"exclude": [
"node_modules",
"build",
"dist",
"scripts",
"acceptance-tests",
"webpack",
"jest",
"src/setupTests.ts",
"**/*/*.test.ts",
"examples"
]
}
My webpack.config.js
: 我的
webpack.config.js
:
const path = require("path");
const ExtractTextPlugin = require("extract-text-webpack-plugin");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
module.exports = {
entry: "./src/index.ts",
output: {
path: path.resolve(__dirname, "dist"),
filename: "index.js"
},
mode: "development",
module: {
rules: [
{
test: /\.tsx?$/,
loader: "awesome-typescript-loader",
},
{
test: /\.css$/,
use: [
MiniCssExtractPlugin.loader,
{
loader: 'typings-for-css-modules-loader',
options: {
modules: true,
namedExport: true,
banner: "/* This file is generated during the webpack build. Please do not edit/remove. */",
localIdentName: '[name]__[local]'
}
},
{
loader: 'postcss-loader',
options: {
config: {
path: './postcss.config.js'
}
}
}
]
},
{
test: /\.(jpg|png|gif|svg)$/,
use: [
{
loader: "file-loader",
options: {
name: "[name].[ext]"
}
}
]
}
]
},
plugins: [
new MiniCssExtractPlugin({
filename: "[name].css",
chunkFilename: "[id].css"
})
],
devtool: "source-map",
resolve: {
extensions: [".js", ".ts", ".tsx", ".css"]
}
};
My postcss.config.js
: 我的
postcss.config.js
:
module.exports = {
modules: true,
plugins: [
require('precss'),
require('postcss-simple-vars'),
require('autoprefixer'),
require('postcss-nested'),
]
}
src/index.ts
is simply: src/index.ts
很简单:
import { Button } from './components/Button';
export {
Button,
};
src/components/Button/index.ts
: src/components/Button/index.ts
:
import Button from './Button';
export { Button };
and src/components/Button/Button.tsx
: 和
src/components/Button/Button.tsx
:
import * as React from 'react';
import { ReactNode } from 'react';
import { Link } from 'react-router-dom';
import * as styles from './Button.css';
export interface IButtonPropTypes {
onClick?: React.MouseEventHandler<any>;
label: string;
children?: ReactNode[] | string;
kind?: 'link' | 'action';
style?: { [key: string]: string };
href?: string;
target?: string;
className?: string;
}
export default function Button({
onClick,
label,
children,
kind = 'action',
style = {},
href,
target,
className,
}: IButtonPropTypes) {
const text = label || children;
const kindStyle = styles[kind] || '';
const classes = className || '';
if (href) {
return (
<Link
className={`${style.btn} ${kindStyle} ${classes}`}
to={href}
target={target}
onClick={onClick}
style={style}
>
<span className={style.background} />
<span>{text}</span>
</Link>
);
}
return (
<button className={`${style.btn} ${kindStyle}`} onClick={onClick} style={style}>
<div>{text}</div>
</button>
);
}
My dist
folder after running webpack
looks like: 运行
webpack
后,我的dist
文件夹如下所示:
- dist
- index.js
- index.js.map
- index.d.ts
- main.css
- main.css.map
- components
- Button
- Button.d.ts
- index.d.ts
and dist/index.js
seems to be compiled correctly by webpack
. 和
dist/index.js
似乎是由webpack
正确编译的。 In package.json
, I have: 在
package.json
,我有:
"main": "dist/index.js",
"types": "dist/index.d.ts",
"files": ["dist"]
After running yarn link
, I import and use my Button
component in a standalone app like so: 运行
yarn link
,我在一个独立的应用程序中导入并使用Button
组件,如下所示:
import { Button } from 'my-components';
class App extends React.Component {
render() {
return (
<div className="App">
<Button label="click me" />
</div>
);
}
}
export default App;
and receive the following 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.
您可能忘记了从定义文件中导出组件,或者可能混淆了默认导入和命名导入。
Check the render method of `App`.
If I remove the Button
component, App
renders without any errors. 如果删除
Button
组件,则App
呈现没有任何错误。
Testing by publishing a throwaway module to npm
yields the same error. 通过将一次性模块发布到
npm
产生相同的错误。
Additionally, if anyone has any suggestions as to better ways to bundle this library, I'd love to hear them as this is my first time using postcss
. 此外,如果有人对捆绑此库的更好方法有任何建议,我很想听听他们的建议,因为这是我第一次使用
postcss
。
It looks like you made a small mistake importing in index.ts
. 似乎在导入
index.ts
犯了一个小错误。 Since it's a default export, no curly braces should be used. 由于这是默认导出,因此不应该使用花括号。
import Button from './components/Button';
As it turns out, this was due to an issue with my webpack
config. 事实证明,这是由于我的
webpack
配置出现问题。 Adding the following lines to output
fixed the error: 添加以下行以
output
可修复错误:
output: {
. . .
library: "opentok-ux-components",
libraryTarget: 'umd',
umdNamedDefine: true
},
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.