导入react-virtuoso报错:需适配对应文件加载器
问题
项目原本运行正常,安装并导入react-virtuoso后出现如下报错:
ERROR in ./~/react-virtuoso/dist/index.mjs Module parse failed: C:\Users\Rocky\Documents\betterdash\node_modules\react-virtuoso\dist\index.mjs Unexpected token (364:22) You may need an appropriate loader to handle this file type. | } | const Component = forwardRef((propsWithChildren, ref) => { | const { children, ...props } = propsWithChildren; | const [system2] = useState(() => { | return tap(init(systemSpec), (system22) => applyPropsToSystem(system22, props)); @ ./src/components/order-viewer.jsx 13:21-46 @ ./src/main.js @ multi whatwg-fetch ./src/main.js
当前webpack.config.js配置:
const path = require("path"); const webpack = require("webpack"); const ExtractTextPlugin = require("extract-text-webpack-plugin"); module.exports = { entry: ["whatwg-fetch", "./src/main.js"], output: { path: path.join(__dirname, "dist"), filename: "bundle.js", publicPath: "/", }, module: { loaders: [ { test: /.jsx?$/, loader: "babel-loader", include: path.join(__dirname, "src"), exclude: /node_modules/, query: { presets: ["es2015", "react", "flow"], plugins: ["transform-flow-strip-types"], }, }, { test: /\.s?css$/, loaders: ExtractTextPlugin.extract({ use: ["css-loader", "sass-loader"], fallback: "style-loader", }), }, ], }, plugins: [ new webpack.HotModuleReplacementPlugin(), new webpack.NoEmitOnErrorsPlugin(), new ExtractTextPlugin({ filename: "style.css", allChunks: true, disable: process.env.NODE_ENV === "development", }), ], devtool: "source-map", };
已尝试删除node_modules后重新执行npm install,问题未解决;移除import { Virtuoso } from "react-virtuoso";语句后报错消失。
解决方案
方案一:让babel-loader处理react-virtuoso并添加解构支持
报错核心原因是react-virtuoso的index.mjs使用了ES6+的剩余解构语法(...props),当前配置中babel-loader仅处理src目录,排除了所有node_modules文件,导致webpack无法解析该语法。
- 安装处理剩余解构的babel插件:
npm install babel-plugin-transform-object-rest-spread --save-dev
- 修改webpack配置中的babel-loader规则:
- 扩展文件匹配规则,加入
.mjs; - 将
react-virtuoso加入include范围; - 添加刚安装的插件到babel配置:
- 扩展文件匹配规则,加入
{ test: /\.(jsx?|mjs)$/, loader: "babel-loader", include: [ path.join(__dirname, "src"), path.join(__dirname, "node_modules/react-virtuoso") ], query: { presets: ["es2015", "react", "flow"], plugins: ["transform-flow-strip-types", "transform-object-rest-spread"] }, }
方案二:升级babel到现代版本(推荐)
旧的es2015 preset已废弃,改用@babel/preset-env能更好地兼容现代ES语法:
- 安装新版babel依赖:
npm install @babel/core @babel/preset-env @babel/preset-react @babel/preset-flow @babel/plugin-transform-flow-strip-types @babel/plugin-proposal-object-rest-spread babel-loader --save-dev
- 更新webpack配置中的babel规则:
{ test: /\.(jsx?|mjs)$/, loader: "babel-loader", include: [ path.join(__dirname, "src"), path.join(__dirname, "node_modules/react-virtuoso") ], query: { presets: ["@babel/preset-env", "@babel/preset-react", "@babel/preset-flow"], plugins: ["@babel/plugin-transform-flow-strip-types", "@babel/plugin-proposal-object-rest-spread"] }, }
方案三:配置webpack直接处理.mjs文件(仅适用于文件已转译的情况)
如果react-virtuoso的mjs文件已完成转译,可添加规则让webpack直接识别:
module: { rules: [ // webpack4+推荐用rules替代loaders // 保留原有jsx、css规则... { test: /\.mjs$/, include: /node_modules/, type: "javascript/auto" } ] }
注:若文件仍包含未转译的ES语法,此方案无效,优先选择前两种。
内容的提问来源于stack exchange,提问作者Rocky Caturan Mendiola
相关产品推荐
相关产品推荐

