antd+typescript webpack打包后样式丢失

在将项目迁移到typescript过程中,使用antd时遇到了样式丢失的问题。原因是webpack打包后未提取css代码。通过排查,发现tsx文件按需加载antd时存在问题。解决方法包括更新webpack配置,添加对less文件的支持,并正确配置less-loader,以解决行内javascript不被支持的错误,最终成功打包并恢复antd样式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

问题描述

最近笔者最近正在将老的项目迁移至typeseript,项目跑起来之后发现antd相关的样式全部丢失,发现webpack打包后css相关的代码没有被提取出来,导致antd的样式全部无效化,原先的webpack配置文件:

module: {
        rules: [
            {
                test: /\.(js|jsx)$/,
                exclude: /node_modules/,
                use: [
                    {
                        loader: 'babel-loader',
                        query: {
                            presets: [
                                '@babel/react', 
                                '@babel/preset-env'
                            ],
                            plugins: [
                                //  给antd做按需加载
                                ["import", {
                                    "libraryName": "antd",
                                    "libraryDirectory": "es",
                                    "style": "css" // `style: true` 会加载 less 文件
                                }],
                                //  这个拿来做注入代码优化的
                                ['@babel/plugin-transform-runtime',
                                {
                                    "corejs": false,
                                    "helpers": true,
                                    "regenerator": true,
                                    "useESModules": false
                                }],
                                //  支持类写法
                                "@babel/plugin-proposal-class-properties"
                            ]
                        }
                    }
                ]
            },
            {
                test: /\.(css|scss)$/,
                exclude: /node_modules/,
                use: [
                    'isomorphic-style-loader',
                    //  MiniCssExtractPlugin.loader,  //自动提取出css
                    //  'css-loader?modules&localIdentName=[name]__[local]--[hash:base64:5]',
                    {
                        loader: 'typings-for-css-modules-loader',
                        options: {
                            modules: true,
                            namedExport: true
                        }
                    }
                ]
            },
            {
                //  专门处理antd的css样式
                test: /\.(css|less)$/,
                include: /node_modules/,
                use: [
                    MiniCssExtractPlugin.loader,
                    'css-loader',
                ],
            },
            {
                test: /\.tsx?$/,
                exclude: /node_modules/,
                loader: 'babel-loader!awesome-typescript-loader',
            }
        ]
    },
    resolve: {
        alias: {
            // '@apiMap': path.resolve(__dirname, 'map/api.tsx'),
            // '@constants': path.resolve(__dirname, 'constants'),
            // '@utils': path.resolve(__dirname, 'utils'),
            // '@UI': path.resolve(__dirname, 'UIwidgets')
        },
        extensions: [
            '.ts', '.tsx', '.js', '.json'
        ]
    },
}

排查与解决

笔者思考了一下,同时参考网上的相关帖子,感觉可能是tsx文件中引入antd时按需加载的相关逻辑出现了问题,typescript下所有的js文件改写为tsx文件,需要添加新的支持按需加载的插件,即ts-import-plugin,将webpack配置文件修改为如下:

    module: {
        rules: [
            //  处理js的babel loader相关配置被删除
            {
                test: /\.(css|scss)$/,
                exclude: /node_modules/,
                use: [
                    'isomorphic-style-loader',
                    {
                        loader: 'typings-for-css-modules-loader',
                        options: {
                            modules: true,
                            namedExport: true
                        }
                    }
                ]
            },
            {
                //  专门处理antd的css样式
                test: /\.css$/,
                include: /node_modules/,
                use: [
                    MiniCssExtractPlugin.loader,
                    'css-loader',
                ],
            },
            {
                test: /\.tsx?$/,
                loader: "awesome-typescript-loader",
                options: {
                  useCache: true,
                  useBabel: false, // !important!
                  getCustomTransformers: () => ({
                    before: [tsImportPluginFactory({
                      libraryName: 'antd',
                      libraryDirectory: 'lib',
                      style: true
                    })]
                  }),
                },
                exclude: [
                    /node_modules/
                ]
              }
        ]
    },

进行打包之后报错:

发现是跟解析less文件相关的bug,接下来我们引入less-loader,删除对antd的css配置:

            // {
            //     //  专门处理antd的css样式
            //     test: /\.(css|less)$/,
            //     include: /node_modules/,
            //     use: [
            //         MiniCssExtractPlugin.loader,
            //         'css-loader',
            //     ],
            // },
            {
                //  专门处理antd的css样式
                test: /\.(less)$/,
                include: /node_modules/,
                use: [
                    MiniCssExtractPlugin.loader,
                    'css-loader',
                    'less-loader'
                ],
            },

继续报错:

根据提示,表示less-loader不支持行内javascript,要在选项中开启:

            {
                //  专门处理antd的css样式
                test: /\.(less)$/,
                include: /node_modules/,
                use: [
                    MiniCssExtractPlugin.loader,
                    'css-loader',
                    {
                        loader: "less-loader",
                        options: {
                            lessOptions: {
                                javascriptEnabled: true
                            }
                        }
                    }
                ],
            },

网上有些帖子说开启的配置写法是这样的:

    //  网上说的这样改是针对老版本,新版下会报错
    loader: "less-loader",
    options: {
        javascriptEnabled: true
    }

实践证明这样的配置写法在新版less-loader(6.0.0)中是会报错的。
再次打包,运行成功。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值