基于Webpack的React项目安装@keplr-wallet/cosmos时遇加载器错误
问题:Webpack打包React项目引入@keplr-wallet/cosmos时出现加载器错误
我有一个基于Webpack的React项目,引入@keplr-wallet/cosmos包后触发了Webpack文件加载器错误,提示:
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file.
从错误截图能看出问题出在包含static关键字的文件里。我知道@babel/preset-env应该支持该特性,也查阅了@babel/plugin-proposal-class-static-block的相关文档,但还是搞不清问题根源。
我的Webpack配置
const path = require('path'); const HtmlWebpackPlugin = require('html-webpack-plugin'); const MiniCssExtractPlugin = require('mini-css-extract-plugin'); const NodePolyfillPlugin = require('node-polyfill-webpack-plugin'); const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer'); const CompressionPlugin = require('compression-webpack-plugin'); const UglifyJsPlugin = require('uglifyjs-webpack-plugin'); const webpack = require('webpack'); const Dotenv = require('dotenv-webpack'); module.exports = env => { const htmlPlugin = new HtmlWebpackPlugin({ template: path.join(__dirname, 'src/web', 'index.html'), filename: 'index.html', }); const miniCssExtractPlugin = new MiniCssExtractPlugin({ filename: 'css/style.[contenthash:8].css', chunkFilename: 'css/[id].style.[contenthash:8].css', }); return { entry: './src/web/index.tsx', output: { path: path.join(__dirname, 'build'), filename: '[name].[contenthash].js', publicPath: '/', }, mode: process.env.NODE_ENV || 'development', resolve: { extensions: ['.js', '.jsx', '.ts', '.tsx', '.json', '.css', '.scss'], modules: ['src', 'node_modules'], alias: { Store: path.resolve(__dirname, 'src/store/reducers'), }, fallback: { fs: false, os: false, path: false, }, }, stats: { errorDetails: true, children: true, }, devServer: { historyApiFallback: true, }, module: { rules: [ { test: /\.(js|jsx)$/, exclude: /node_modules/, use: { loader: 'babel-loader', } }, { test: /\.(ts|tsx)$/, exclude: /node_modules/, use: { loader: 'babel-loader', } }, { test: /\.(css|scss)$/, use: [MiniCssExtractPlugin.loader, 'css-loader', 'postcss-loader', 'sass-loader'], }, { test: /\.(jpg|jpeg|png|gif|mp3|svg)$/, use: [ { loader: 'file-loader', options: { name (file) { /*if (env === 'development') { return '[path][name].[ext]' }*/ return '[name]_[hash].[ext]' }, publicPath: '/public/assets/img/', outputPath: '../images/' } } ] }, ], }, performance: { hints: false, }, plugins: [ new webpack.ProvidePlugin({ $: 'jquery', jQuery: 'jquery', 'window.jQuery': 'jquery', }), miniCssExtractPlugin, htmlPlugin, new NodePolyfillPlugin(), // new BundleAnalyzerPlugin(), new CompressionPlugin({ algorithm: 'gzip', }), new Dotenv() ], optimization: { minimizer: [new UglifyJsPlugin()], usedExports: true, }, } };
我的babel.config.js配置
module.exports = { presets: [ [ '@babel/preset-env', { useBuiltIns: 'entry', modules: false, }, ], ["@babel/preset-typescript"], [ '@babel/preset-react', { targets: { node: 'current', }, }, ], ['@babel/preset-flow'], ], };
相关包版本
"@babel/preset-env": "^7.18.2", "@babel/preset-react": "^7.17.12", "@babel/node": "^7.17.10", "@babel/preset-typescript": "^7.17.12", "@babel/preset-flow": "^7.18.6",
解决方案
1. 让Babel转译@keplr-wallet包
当前Webpack配置排除了所有node_modules目录的文件,但@keplr-wallet/cosmos包的代码可能未做预转译,包含浏览器不兼容的语法(比如类static块)。修改规则,让babel-loader处理该包:
// 修改Webpack中js/jsx和ts/tsx的规则 { test: /\.(js|jsx)$/, exclude: /node_modules\/(?!@keplr-wallet)/, use: { loader: 'babel-loader', } }, { test: /\.(ts|tsx)$/, exclude: /node_modules\/(?!@keplr-wallet)/, use: { loader: 'babel-loader', } },
2. 修正Babel的targets配置
@babel/preset-react里的targets设置为node: 'current'是针对Node.js环境的,需改成浏览器目标。同时给@babel/preset-env指定浏览器范围,确保自动引入必要的语法兼容插件:
// 修改babel.config.js module.exports = { presets: [ [ '@babel/preset-env', { useBuiltIns: 'entry', modules: false, targets: { browsers: ['last 2 versions', 'not dead'] }, }, ], ["@babel/preset-typescript"], ['@babel/preset-react'], ['@babel/preset-flow'], ], };
3. 替换UglifyJsPlugin为TerserPlugin
UglifyJsPlugin已停止维护,对ES6+语法支持不佳,换成terser-webpack-plugin:
首先安装依赖:
npm install terser-webpack-plugin --save-dev
然后修改Webpack配置:
const TerserPlugin = require('terser-webpack-plugin'); // ... optimization: { minimizer: [new TerserPlugin()], usedExports: true, },
内容的提问来源于stack exchange,提问作者Ajay Singh
相关产品推荐
相关产品推荐

