Next.js部署Vercel生产环境调用API路由返回500错误
问题复现代码
在Next.js项目中创建API目录存放服务端接口,实现代码如下:
import { NextApiRequest, NextApiResponse } from 'next' import Cors from 'cors' // 初始化cors中间件 const cors = Cors({ methods: ['GET', 'HEAD', 'POST'], origin: '*', optionsSuccessStatus: 200, }) // 中间件执行包装方法,中间件执行报错时直接抛出异常 function runMiddleware(req, res, fn) { return new Promise((resolve, reject) => { fn(req, res, (result) => { if (result instanceof Error) { return reject(result) } return resolve(result) }) }) } export default async (req, res) => { await runMiddleware(req, res, cors) const POSKEY = process.env.POSKEY const PAYEE = process.env.PAYEE const { currency, url, locale, price } = req.body const currentUrl = url const apiResult = await fetch( 'https://api.test.barion.com/v2/Payment/Start', { method: 'POST', headers: { 'Content-Type': 'application/json', 'Content-Length': 3495, }, body: JSON.stringify({ PosKey: POSKEY, PaymentType: 'Immediate', GuestCheckout: true, FundingSources: ['All'], Currency: currency, RedirectUrl: currentUrl, CallbackUrl: currentUrl, Locale: locale, Transactions: [ { Payee: PAYEE, Total: price, Items: [ { Name: 'Teszt', Description: 'Test item comment', Quantity: 1, Unit: 'pc', UnitPrice: 1, ItemTotal: 1, SKU: 'SM-01', }, ], }, ], }), } ) .then((result) => { return result.json() }) .catch((error) => { console.error(error) }) res.status(200).json({ url: apiResult.GatewayUrl }) }
报错现象
本地开发环境调用接口完全正常,部署到Vercel生产环境后接口返回500错误,Vercel控制台输出错误如下:
[POST] /apigateway/ 23:30:28:53
2022-06-27T21:30:28.595Z e8c57750-4647-4e7a-b62e-6221abc141ac ERROR Error: Cannot find module
'/var/task/node_modules/next/dist/server/next.js'.
Please verify that the package.json has a valid "main" entry
at tryPackage (internal/modules/cjs/loader.js:321:19)
at Function.Module._findPath (internal/modules/cjs/loader.js:534:18)
at Function.Module._resolveFilename (internal/modules/cjs/loader.js:888:27)
at Function.Module._load (internal/modules/cjs/loader.js:746:27)
at Module.require (internal/modules/cjs/loader.js:974:19)
at require (internal/modules/cjs/helpers.js:101:18)
at Object.5199 (/var/task/.next/server/pages/api/gateway.js:20:39)
at webpack_require (/var/task/.next/server/webpack-api-runtime.js:25:42)
at webpack_exec (/var/task/.next/server/pages/api/gateway.js:109:39)
at /var/task/.next/server/pages/api/gateway.js:110:28 { code: 'MODULE_NOT_FOUND', path:
'/var/task/node_modules/next/package.json', requestPath: 'next' }
RequestId: e8c57750-4647-4e7a-b62e-6221abc141ac Error: Runtime exited
with error: exit status 1 Runtime.ExitError
问题原因与修复
这个问题和next.config.js配置没有关系,不需要在配置文件中添加任何特殊规则。报错核心是生产环境部署时没有正确安装next核心依赖,属于Vercel部署时常见的依赖识别问题,按以下步骤操作即可修复:
- 打开项目根目录的
package.json文件,检查dependencies字段下是否存在next包。如果next被错误放到了devDependencies开发依赖分类下,立刻移到生产依赖中——Vercel生产构建默认不会安装devDependencies下的包,这是触发这个MODULE_NOT_FOUND错误的最常见原因。 - 如果依赖分类没有问题,删除本地的
node_modules目录、对应包管理器的锁文件(package-lock.json/yarn.lock/pnpm-lock.yaml),重新执行依赖安装命令生成全新的锁文件,再推送代码到Vercel触发重新部署即可。 - 上述两步操作后仍报错的话,进入Vercel项目后台设置页,手动指定构建命令为
npm run build(如果用yarn/pnpm就替换为对应构建命令),同时把Node.js版本调整为和本地开发使用的大版本一致,避免版本兼容导致的依赖解析异常。
内容的提问来源于stack exchange,提问作者rkris26

