admin管理员组文章数量:1390192
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.
I'm building a React
ponent library with TypeScript
and webpack
.
My directory structure:
- src
- index.ts
- ponents
- 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
:
{
"pilerOptions": {
"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
:
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
:
module.exports = {
modules: true,
plugins: [
require('precss'),
require('postcss-simple-vars'),
require('autoprefixer'),
require('postcss-nested'),
]
}
src/index.ts
is simply:
import { Button } from './ponents/Button';
export {
Button,
};
src/ponents/Button/index.ts
:
import Button from './Button';
export { Button };
and src/ponents/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:
- dist
- index.js
- index.js.map
- index.d.ts
- main.css
- main.css.map
- ponents
- Button
- Button.d.ts
- index.d.ts
and dist/index.js
seems to be piled correctly by webpack
. In package.json
, I have:
"main": "dist/index.js",
"types": "dist/index.d.ts",
"files": ["dist"]
After running yarn link
, I import and use my Button
ponent in a standalone app like so:
import { Button } from 'my-ponents';
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 ponents) or a class/function (for posite ponents) but got:
undefined. You likely forgot to export your ponent 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
ponent, App
renders without any errors.
Testing by publishing a throwaway module to npm
yields the same error.
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
.
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.
I'm building a React
ponent library with TypeScript
and webpack
.
My directory structure:
- src
- index.ts
- ponents
- 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
:
{
"pilerOptions": {
"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
:
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
:
module.exports = {
modules: true,
plugins: [
require('precss'),
require('postcss-simple-vars'),
require('autoprefixer'),
require('postcss-nested'),
]
}
src/index.ts
is simply:
import { Button } from './ponents/Button';
export {
Button,
};
src/ponents/Button/index.ts
:
import Button from './Button';
export { Button };
and src/ponents/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:
- dist
- index.js
- index.js.map
- index.d.ts
- main.css
- main.css.map
- ponents
- Button
- Button.d.ts
- index.d.ts
and dist/index.js
seems to be piled correctly by webpack
. In package.json
, I have:
"main": "dist/index.js",
"types": "dist/index.d.ts",
"files": ["dist"]
After running yarn link
, I import and use my Button
ponent in a standalone app like so:
import { Button } from 'my-ponents';
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 ponents) or a class/function (for posite ponents) but got:
undefined. You likely forgot to export your ponent 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
ponent, App
renders without any errors.
Testing by publishing a throwaway module to npm
yields the same error.
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
.
-
Did you omit your
export
statement in yourApp.tsx
file...? – Andrew Commented Apr 11, 2018 at 23:03 - @Andrew No, I just didn't include it in the code snippet. I'll make an edit so it's not confusing. – adrice727 Commented Apr 11, 2018 at 23:06
2 Answers
Reset to default 7As it turns out, this was due to an issue with my webpack
config. Adding the following lines to output
fixed the error:
output: {
. . .
library: "opentok-ux-ponents",
libraryTarget: 'umd',
umdNamedDefine: true
},
It looks like you made a small mistake importing in index.ts
. Since it's a default export, no curly braces should be used.
import Button from './ponents/Button';
版权声明:本文标题:javascript - TypeScript + React: Element type is invalid: expected a string (for built-in components) - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744749856a2623109.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论