React17+ts 使用 antd <Spin>组件
报错内容
'Spin' cannot be used as a JSX component.
Its instance type 'Spin' is not a valid JSX element.
Type 'Spin' is missing the following properties from type 'ElementClass': context, setState, forceUpdate, props, and 2 more.ts(2786)
也不能给 <Spin> 传递props
请问这是什么原因?
下面附上我的项目配置
tsconfig
{
"compilerOptions": {
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"target": "ES2017",
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"allowJs": true,
"outDir": "./dist/",
"esModuleInterop": true,
"noImplicitAny": false,
"sourceMap": true,
"module": "esnext",
"moduleResolution": "node",
"isolatedModules": true,
"importHelpers": true,
"lib": ["esnext", "dom", "dom.iterable"],
"skipLibCheck": false,
"jsx": "react",
"typeRoots": ["node", "node_modules/@types", "./typings"],
"rootDirs": ["./src"],
"baseUrl": "./src",
"paths": {
"src/*": ["*"],
"assets/*": ["assets/*"],
"components/*": ["components/*"],
"pages/*": ["pages/*"],
"utils/*": ["utils/*"],
"servers/*": ["servers/*"],
"actions/*": ["actions/*"],
"config": ["config"],
"routeConfig": ["routeConfig"],
"request": ["request"]
}
},
"include": ["./src/**/*", "./declaration.d.ts"],
"exclude": ["node_modules"]
}
webpack配置
const webpack = require('webpack');
const path = require('path');
const tsImportPluginFactory = require('ts-import-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const TerserPlugin = require('terser-webpack-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const AntdDayjsWebpackPlugin = require('antd-dayjs-webpack-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const ProgressBarPlugin = require('progress-bar-webpack-plugin');
const CompressionPlugin = require('compression-webpack-plugin');
const CopyPlugin = require('copy-webpack-plugin');
module.exports = {
stats: {
entrypoints: false,
children: false
},
optimization: {
minimizer: [
// 压缩js
new TerserPlugin({
test: /.(ts|tsx|js|jsx)$/,
extractComments: true,
parallel: true,
cache: true
})
],
splitChunks: {
cacheGroups: {
vendors: {
//node_modules里的代码
test: /[\/]node_modules[\/]/,
chunks: 'all',
name: 'vendors', //chunks name
priority: 10, //优先级
enforce: true
}
}
}
},
resolve: {
extensions: ['.ts', '.tsx', '.js', '.jsx', '.css', '.less', '.json'],
alias: {
src: path.resolve(__dirname, '../src/'),
assets: path.resolve(__dirname, '../src/assets/'),
components: path.resolve(__dirname, '../src/components/'),
utils: path.resolve(__dirname, '../src/utils/'),
servers: path.resolve(__dirname, '../src/servers/'),
actions: path.resolve(__dirname, '../src/actions/'),
pages: path.resolve(__dirname, '../src/pages/'),
request: path.resolve(__dirname, '../src/request.ts'),
config: path.resolve(__dirname, '../src/config.ts'),
routeConfig: path.resolve(__dirname, '../src/routeConfig.tsx')
}
},
module: {
rules: [
{
enforce: 'pre',
test: /.(ts|tsx|js|jsx)$/,
exclude: /node_modules/,
loader: 'eslint-loader',
options: {
cache: true,
emitWarning: true,
failOnError: true
}
},
{
test: /.(tsx|ts)?$/,
exclude: /node_modules/,
loader: 'awesome-typescript-loader',
options: {
getCustomTransformers: () => ({
before: [
tsImportPluginFactory([
{
libraryName: 'antd',
libraryDirectory: 'lib',
style: 'css'
}
])
]
})
}
},
{
test: /.(js|jsx)$/,
loader: 'babel-loader'
},
{
test: /.(css|less)$/,
use: [
process.env.ENV_LWD == 'development' ? { loader: 'style-loader' } : MiniCssExtractPlugin.loader,
{
loader: 'css-loader',
options: {
importLoaders: 1
}
},
{
loader: 'less-loader',
options: {
javascriptEnabled: true
}
}
]
},
{
test: /.(png|svg|jpg|gif|jpeg)$/,
loader: 'file-loader',
options: {
outputPath: './assets/images',
publicPath: '../assets/images/',
esModule: false
}
},
{
test: /.(mp3)$/,
loader: 'file-loader',
options: {
outputPath: './assets/audio',
publicPath: '../assets/audio/',
esModule: false
}
},
{
test: /.(woff|woff2|eot|ttf|otf)$/,
loader: 'file-loader',
options: {
esModule: false
}
}
]
},
plugins: {
// 配置入口页面
html: new HtmlWebpackPlugin({
title: 'commonVideoClient',
template: 'public/index.html',
removeComments: true,
collapseWhitespace: true,
removeRedundantAttributes: true,
useShortDoctype: true,
removeEmptyAttributes: true,
removeStyleLinkTypeAttributes: true,
keepClosingSlash: true,
minifyJS: true,
minifyCSS: true,
minifyURLs: true
}),
// 清理dist包
cleanWebpack: new CleanWebpackPlugin(),
// 抽取css
miniCssExtract: new MiniCssExtractPlugin({
filename: process.env.ENV_LWD == 'development' ? './css/[id].css' : './css/[id].[hash].css',
chunkFilename: process.env.ENV_LWD == 'development' ? './css/[id].css' : './css/[id].[hash].css',
ignoreOrder: true
}),
namedModules: new webpack.NamedModulesPlugin(),
// 压缩css
optimizeCssAssets: new OptimizeCssAssetsPlugin(),
// 生成包依赖图
bundleAnalyzer: new BundleAnalyzerPlugin({ analyzerPort: 8081 }),
// 打包进度
progressBarPlugin: new ProgressBarPlugin(),
// 加载中文包
ContextReplacementPlugin: new webpack.ContextReplacementPlugin(/moment/locale$/, /zh-cn/),
CompressionPlugin: new CompressionPlugin({
filename: '[path].gz[query]',
algorithm: 'gzip',
test: /.js$|.css$|.jsx$|.less$|.html$/,
threshold: 10240,
minRatio: 0.8
}),
AntdDayjsWebpackPlugin: new AntdDayjsWebpackPlugin({ preset: 'antdv3' }),
DefinePlugin: new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify(process.env.ENV_LWD)
}),
CopyPlugin: new CopyPlugin([{ from: './src/assets/js', to: '../dist/assets/js', toType: 'dir' }]),
HotModuleReplacementPlugin: new webpack.HotModuleReplacementPlugin()
},
devServer: {
contentBase: path.resolve(__dirname, 'dist'),
hot: true,
historyApiFallback: true,
compress: true
},
watchOptions: {
aggregateTimeout: 600
},
// externals 排除对应的包,注:排除掉的包必须要用script标签引入下
externals: {
react: 'React',
'react-dom': 'ReactDOM',
antd: 'antd'
}
};