Next.js项目编译报错:缺少合适的Loader处理文件类型(可选链语法相关)
Next.js项目编译报错:缺少合适的Loader处理文件类型(可选链语法相关)
嗨,我来帮你搞定这个编译失败的问题!先理清楚你的情况:你克隆了一个数字标牌项目,在加载部分页面时遇到了Webpack解析错误,核心是react-draggable里用到的可选链(?.)和空值合并(??)语法不被当前的编译环境支持。
你遇到的错误信息:
Failed To Compile ./node_modules/react-grid-layout/node_modules/react-resizable/node_modules/react-draggable/build/cjs/Draggable.js 210:22 Module parse failed: Unexpected token (210:22) You may need an appropriate loader to handle this file type. | // the underlying DOM node ourselves. See the README for more information. | findDOMNode() /*: ?HTMLElement*/{ > return this.props?.nodeRef?.current ?? _reactDom.default.findDOMNode(this); | } | render() /*: ReactElement<any>*/{
问题根源分析:
你用的是Next.js 8.0.1,这个版本默认的Babel/Webpack配置还不支持ES2020引入的可选链和空值合并语法;同时项目依赖的react-grid-layout嵌套了一个较新版本的react-draggable,这个版本用了这些新语法,但Next.js默认不会转译node_modules目录下的代码,所以Webpack无法解析这些语法,导致报错。
解决方案:
下面给你几个可行的解决办法,按推荐程度排序:
方法1:让Next.js转译指定的第三方包
这个是最直接的方案,通过next-transpile-modules插件告诉Webpack去转译那些用了新语法的依赖包:
- 安装对应版本的插件(因为你的Next.js是8.x,要装v3版本的插件):
npm install next-transpile-modules@3 --save-dev
- 在项目根目录创建/修改
next.config.js,把需要转译的包加进去:
const withCSS = require('@zeit/next-css'); const withTM = require('next-transpile-modules')([ 'react-draggable', 'react-resizable', 'react-grid-layout' ]); // 合并CSS插件和转译插件的配置 module.exports = withTM(withCSS({ // 这里可以加其他Next.js配置项 }));
- 重启你的开发服务,重新编译试试。
方法2:添加Babel插件支持新语法
如果方法1没生效,你可以直接给Babel添加支持可选链和空值合并的插件:
- 安装Babel插件:
npm install @babel/plugin-proposal-optional-chaining @babel/plugin-proposal-nullish-coalescing-operator --save-dev
- 在项目根目录创建/修改
.babelrc文件:
{ "presets": ["next/babel"], "plugins": [ "@babel/plugin-proposal-optional-chaining", "@babel/plugin-proposal-nullish-coalescing-operator" ] }
这个方法会让Babel在编译时处理这些新语法,但同样需要确保这些第三方包被纳入编译范围,所以最好和方法1配合使用。
方法3:升级Next.js版本(可选)
如果你的项目没有强依赖旧版Next.js的特性,可以考虑升级到较新的Next.js版本(比如10.x及以上)。新版Next.js默认支持ES2020语法,而且内置了CSS处理,不需要再用@zeit/next-css,配置更简洁。不过升级前要注意检查其他依赖的兼容性,比如react、react-dom的版本是否匹配,避免出现新的兼容问题。
内容来源于stack exchange
相关产品推荐
相关产品推荐

