ES模块导入CommonJS模块keyboardjs时如何避免加载时自动执行代码
问题解决方法
方案1:使用动态导入控制加载时机
ES模块的静态import语句会被提升,在模块内所有代码执行前就完成依赖加载,因此你需要先创建全局模拟DOM,再通过动态import加载keyboardjs,示例代码如下:
import { JSDOM } from 'jsdom' import assert from 'assert' // 先创建模拟DOM并挂载到全局对象 const dom = new JSDOM() globalThis.window = dom.window globalThis.document = dom.window.document // 可选补充:挂载navigator等浏览器常用全局属性,避免其他兼容问题 globalThis.navigator = dom.window.navigator // 动态导入keyboardjs,此时全局已存在window对象 const { default: keyboardjs } = await import('keyboardjs') // 后续正常调用即可 keyboardjs.watch(document)
如果是在mocha测试用例中使用,可将上述逻辑放到before异步钩子中执行。
方案2:测试环境预注入全局DOM
如果有多个测试文件都需要用到DOM模拟,可提前配置测试启动参数预注入JSDOM,无需每个文件单独处理:
- 新建全局初始化脚本
jsdom-init.js,内容如下:
import { JSDOM } from 'jsdom' const dom = new JSDOM() globalThis.window = dom.window globalThis.document = dom.window.document globalThis.navigator = dom.window.navigator
- 运行mocha时添加启动参数:
mocha --import ./jsdom-init.js 你的测试文件路径
配置完成后,可直接在测试文件顶部静态导入keyboardjs,不会再触发找不到window的报错。
报错原因
keyboardjs的CommonJS模块顶层代码包含初始化逻辑,会在模块被加载时立即执行并尝试访问全局window对象,而你原本的代码中静态导入keyboardjs的时机早于JSDOM实例创建的时机,因此模块加载时全局不存在window对象,触发报错。
内容的提问来源于stack exchange,提问作者scottysseus
相关产品推荐
相关产品推荐

