Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
4.3k views
in Technique[技术] by (71.8m points)

React17+ts 使用 antd <Spin>组件报错?

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)

image.png

也不能给 <Spin> 传递props
image.png

请问这是什么原因?
下面附上我的项目配置

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'
    }
};

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)
等待大神解答

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...