【问题标题】:Prevent CommonJS module imported into ES module from executing code阻止导入到 ES 模块中的 CommonJS 模块执行代码
【发布时间】:2021-12-02 04:25:23
【问题描述】:

我正在尝试将 CommonJS 模块 (KeyboardJS) 导入到我在 ES 模块中编写的一些测试中。

这是我的测试代码给你一个想法:

import { JSDOM } from 'jsdom'
import assert from 'assert'
import keyboardjs from 'keyboardjs' // <-- this line throws an error

// create mocked window object
const window = new JSDOM().window
const document = window.document

// pass this to keyboardjs?
keyboardjs.watch(document)

这是错误:

Error: Cannot find window functions addEventListener or attachEvent.
    at Keyboard.watch (./node_modules/keyboardjs/dist/keyboard.js:614:19)
    at Keyboard.setContext (./node_modules/keyboardjs/dist/keyboard.js:587:14)
    at new Keyboard (./node_modules/keyboardjs/dist/keyboard.js:439:12)
    at ./node_modules/keyboardjs/dist/keyboard.js:1076:18
    at ./node_modules/keyboardjs/dist/keyboard.js:2:83
    at Object.<anonymous> (./node_modules/keyboardjs/dist/keyboard.js:5:2)
    at Module._compile (internal/modules/cjs/loader.js:1063:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:1092:10)
    at Module.load (internal/modules/cjs/loader.js:928:32)
    at Function.Module._load (internal/modules/cjs/loader.js:769:14)
    at ModuleWrap.<anonymous> (internal/modules/esm/translators.js:199:29)
    at ModuleJob.run (internal/modules/esm/module_job.js:152:23)
    at async Loader.import (internal/modules/esm/loader.js:166:24)
    at async formattedImport (./node_modules/mocha/lib/nodejs/esm-utils.js:7:14)
    at async Object.exports.requireOrImport (./node_modules/mocha/lib/nodejs/esm-utils.js:48:32)
    at async Object.exports.loadFilesAsync (./node_modules/mocha/lib/nodejs/esm-utils.js:88:20)
    at async singleRun (./node_modules/mocha/lib/cli/run-helpers.js:125:3)
    at async Object.exports.handler (./node_modules/mocha/lib/cli/run.js:374:5)

似乎keyboardjs 正在尝试访问window 对象在它被加载时,这当然不能工作,因为我在一些测试代码中加载它。

是否有一些特殊的方法可以在不触发此行为的情况下导入它?

【问题讨论】:

  • 为什么找不到window.addEventListener()函数呢? window 未定义吗?
  • 是的,这段代码是作为单元测试的一部分运行的,所以 window 是未定义的。
  • 那为什么不模拟这个模块呢?我认为现在是集成测试而不是单元测试!

标签: javascript es6-modules commonjs


【解决方案1】:

我可以使用dynamic imports 来实现它。

您可以使用 import 函数,该函数在导入模块时返回一个 Promise。

JSDOM 可以先导入,然后用于创建嵌入的窗口对象,然后我们将其添加到全局范围。

然后,我们可以使用相同的机制导入keyboardjs

这是我最终得到的大致代码:

// import JSDOM first
import('jsdom').then(async module => {
  const window = new module.JSDOM().window

  // now set the global window object to the JSDOM window
  globalThis.window = window

  // _now_ import keyboardjs
  const keyboardjs = await import('keyboardjs')
  const document = window.document
  return { keyboardjs, document }
}).then(({ keyboardjs, document }) => {
  // test code goes here, and can use keyboardjs and document
})

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-11-20
    • 1970-01-01
    • 2020-10-06
    • 2012-06-15
    • 2021-04-07
    • 2018-06-22
    • 2019-03-03
    • 2019-04-13
    相关资源
    最近更新 更多