NextJS API生产环境失效:更新包或修改yarn.lock引发问题
问题根源
从Vercel日志的ReferenceError: window is not defined错误可明确:@memberstack/dom模块在服务器端(Node.js环境)被执行,而该模块直接访问了仅浏览器环境存在的window对象。
当yarn.lock更新后,@memberstack/react依赖的@memberstack/dom版本发生变化(即便锁定@memberstack/react版本,其子依赖仍可能存在版本浮动空间),新版本的@memberstack/dom在服务器初始化阶段就执行了依赖window的代码,导致服务器端渲染/API路由崩溃。Next.js在服务器报错时会默认返回页面HTML,这就是所有API调用返回index内容的原因。
解决方案
1. 强制锁定@memberstack/dom的稳定版本
找到之前正常运行的yarn.lock文件,查找@memberstack/dom的版本号,在package.json中添加resolutions字段(Yarn支持该字段)强制锁定版本:
"resolutions": { "@memberstack/dom": "x.y.z" }
将x.y.z替换为旧yarn.lock中的对应版本,执行yarn install生成新的yarn.lock。
2. 确保@memberstack/react仅在客户端加载
Next.js 13+中,将使用@memberstack/react的组件标记为客户端组件,在组件顶部添加:
'use client';
若在自定义App或Layout中使用,改用动态导入并禁用SSR:
import dynamic from 'next/dynamic'; const MemberstackProvider = dynamic(() => import('@memberstack/react').then(mod => mod.MemberstackProvider), { ssr: false, });
这样@memberstack/react及其依赖的@memberstack/dom只会在浏览器环境加载,避免服务器端执行。
3. 检查API路由是否意外引入客户端依赖
确认所有pages/api/或app/api/下的路由文件,未导入@memberstack/react或其他仅客户端的模块,确保API路由仅使用Node.js兼容的代码。
验证步骤
- 执行
yarn install后,检查yarn.lock中@memberstack/dom的版本是否为锁定的稳定版本 - 本地运行
next build && next start,模拟生产环境测试API调用 - 部署到Vercel测试,查看日志是否消除
window is not defined错误
内容的提问来源于stack exchange,提问作者srazzak

