升级Jest、jest-cli及braces后global.window未定义问题求助
Jest升级到29.x后
global.window未定义的排查方向 问题背景
我们通过Dependabot完成以下依赖升级:
braces:3.0.2 → 3.0.3jest:26.6.3 → 29.7.0jest-cli:26.6.3 → 29.7.0
项目中jest.config.js已配置通过setupFilesAfterEnv引入testSetup.jsx,但升级后所有引用global.window的代码均执行失败,报错示例:
TypeError: Cannot set properties of undefined (setting 'ApptentiveSDK')
117 | } 118 | */ > 119 | global.window.ApptentiveSDK = { createConversation: jest.fn(() => { }), engage: jest.fn(() => { }) } | ^
以下是具体排查方向:
1. 确认Jest的测试环境配置
Jest 28及以后版本不再默认模拟浏览器环境的window对象,必须显式指定testEnvironment:
- 前端项目需将
jest.config.js中的testEnvironment设置为jsdom - 配置示例:
module.exports = { testEnvironment: 'jsdom', // 其他原有配置... };
同时要确保已单独安装jsdom依赖(Jest 28+将其从核心包拆分):
npm install --save-dev jsdom # 或 yarn add -D jsdom
2. 调整全局对象的访问逻辑
Jest 29.x对全局对象的处理逻辑有变化,可尝试两种修改方式:
- 直接使用
window而非global.window,在jsdom环境下window本身就是全局变量:
window.ApptentiveSDK = { createConversation: jest.fn(() => { }), engage: jest.fn(() => { }) };
- 若需兼容旧代码,先判断并初始化
global.window:
global.window = global.window || {}; global.window.ApptentiveSDK = { createConversation: jest.fn(() => { }), engage: jest.fn(() => { }) };
3. 检查setup文件的执行时机
setupFilesAfterEnv是在测试框架初始化完成后执行,若测试环境未正确配置,此时window可能还未被模拟。可尝试将window初始化代码移至setupFiles(测试框架初始化前执行):
修改jest.config.js:
module.exports = { setupFiles: ['<rootDir>/testSetup.jsx'], // 若需保留原setupFilesAfterEnv的其他配置,可拆分文件:将window初始化放到单独文件,通过setupFiles引入 };
4. 核对Jest版本迁移的关键变更
从26.x升级到29.x存在大量重大变更,重点关注:
- 测试环境的默认值变化及
jsdom的拆分逻辑 - 全局对象的访问方式调整
内容的提问来源于stack exchange,提问作者Constantine
相关产品推荐
相关产品推荐

