使用intuit-oauth编译Next.js应用时出现makeErrorCause重复定义错误
makeErrorCause重复定义的解决办法 问题背景
我在构建Next.js应用时使用intuit-oauth库,此前在Express.js中使用该库一切正常,但Next.js编译时出现如下错误:
Error:
x the namemakeErrorCauseis defined multiple times
,-[/Users/alan/Repositories/balancer/balancer-next/node_modules/make-error-cause/dist/index.js:5:1]
5 | d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
6 | };
7 | var makeError = require('make-error');
8 | function makeErrorCause(value, _super) {
: ^^^^^^|^^^^^
: `-- previous definition of `makeErrorCause` here
9 | if (_super === void 0) { _super = makeErrorCause.BaseError; }
10 | return makeError(value, _super);
11 | }
12 | var makeErrorCause;
: ^^^^^^|^^^^^
: `-- `makeErrorCause` redefined here
13 | (function (makeErrorCause) {
14 | var BaseError = (function (_super) {
15 | __extends(BaseError, _super);
`----
查看make-error-cause库的源码,发现确实存在重复定义:
function makeErrorCause(value, _super) { if (_super === void 0) { _super = makeErrorCause.BaseError; } return makeError(value, _super); } var makeErrorCause;
依赖链为:intuit-oauth -> popsicle -> make-error -> make-error-cause,Next.js的编译规则不允许这种重复定义写法。
解决方案
1. 转译依赖包
Next.js默认不会转译node_modules中的包,将make-error-cause加入转译列表,让Next.js用Babel重新处理它的代码:
修改next.config.js:
/** @type {import('next').NextConfig} */ const nextConfig = { transpilePackages: ['make-error-cause'], } module.exports = nextConfig
2. 给依赖包打补丁
使用patch-package工具修复make-error-cause的代码问题:
- 安装工具:
npm install patch-package --save-dev - 打开
node_modules/make-error-cause/dist/index.js,删除第12行的var makeErrorCause;; - 生成补丁文件:
npx patch-package make-error-cause - 在
package.json的scripts中添加自动应用补丁的命令:"scripts": { "postinstall": "patch-package" }
3. 锁定依赖版本
检查make-error-cause是否有修复该问题的更新版本,或者通过resolutions锁定兼容版本:
在package.json中添加:
"resolutions": { "make-error-cause": "^2.2.0" }
- 若使用npm,需先安装
npm-force-resolutions:
并添加预安装脚本:npm install npm-force-resolutions --save-dev"scripts": { "preinstall": "npx npm-force-resolutions" } - 重新安装依赖:
npm install
4. 服务端隔离使用
如果intuit-oauth仅用于服务端逻辑,将相关代码放在Next.js的pages/api目录下。API路由运行在服务端,不会经过客户端编译流程,可规避该语法错误。
内容的提问来源于stack exchange,提问作者Glenn

