Jest 和 ES2015 导入。开玩笑地尊重 package.json 中的 pkg.module 声明

Posted

技术标签:

【中文标题】Jest 和 ES2015 导入。开玩笑地尊重 package.json 中的 pkg.module 声明【英文标题】:Jest and ES2015 imports. Make jest respect the pkg.module declaration in package.json 【发布时间】:2018-05-15 08:44:27 【问题描述】:

我在我的应用程序中通过 npm 导入 deepmerge。环境包括webpack、babel、typescript、react、redux、jest。

我设法让 Jest 与 ES2015 导入一起正常工作,但 Jest 拒绝使用 es.js 版本的 deepmerge(请参阅 pkg.module 以供参考)。

简而言之,deepmerge 使用了一个名为 rollup 的包,它编译了 ES2015 发行版和适用于 CommonJS 兼容环境和库(如 RequireJS)的不同发行版。然后在 deepmerge 的 package.json 中引用它们,如下所示:

  "main": "dist/umd.js",
  "module": "dist/es.js"

这样,当在应用程序中导入 deepmerge 时,编译器应该足够明智地根据运行环境使用正确的文件。

这可能过于简单,但你应该明白这一点。

现在,我的应用程序可以很好地解析所有内容,并且正在编译正确版本的脚本 (es.js)。相反,Jest 导入了错误的文件 (umd.js),从而破坏了测试 (TypeError: deepmerge_1.default is not a function)。

我找到了解决方法,例如在导入语句中指定正确文件的路径,而不是依赖import deepmerge from 'deepmerge';。但我觉得应该有更好的方法,以防包的维护者决定更改路径、文件名或其他任何东西。

有什么想法吗?


jest.config.json


  "transformIgnorePatterns": [
    "<rootDir>/node_modules/(?!deepmerge)"
  ],
  "transform": 
    ".(js|ts|tsx)": "<rootDir>/node_modules/ts-jest/preprocessor.js"
  ,
  "testRegex": "(/__tests__/.*|\\.(test|spec))\\.(ts|tsx|js)$",
  "moduleFileExtensions": ["ts", "tsx", "js", "jsx", "json"]

.babelrc


  "presets": ["env", "react"],
  "plugins": [
    "react-css-modules"
  ]

【问题讨论】:

【参考方案1】:

编辑:稍作调整,使其使用包的模块字段。由于 jest.mock 的 hoisting,无法创建辅助函数,不得不重复该名称三遍。

jest.mock('modulename', () => require('modulename/' + require('modulename/package.json').module));

原答案:

在导入我们自己的使用 package.module 的内部库之一时,我遇到了同样的问题。我的理解是,因为 JEST 在 node 中运行(而且我们的测试不通过 WebPack),所以 package.module 被忽略,而使用 package.main。

我能够使用测试中的模拟来解决这个问题:

jest.mock('modulename', () => require('modulename/builds/es'));

对于每个使用 pkg.module 的模块来说,这样做很乏味,但比手动模拟其内容要好,而且我可以保持测试代码的导入完好无损。

另一种方法可能是编写一个转换,将模块的 es 版本映射/代理到 commonjs 版本,但这并没有让我走得太远。

我希望将来有更好的解决方案。

【讨论】:

以上是关于Jest 和 ES2015 导入。开玩笑地尊重 package.json 中的 pkg.module 声明的主要内容,如果未能解决你的问题,请参考以下文章

Jest + ES2015 导入

如何将 jest 与 coffeescript 和 ES6/ES2015 一起使用(例如通过 Babel)?

babel-jest ES2015 导入语句

ES6类开玩笑嘲弄

开玩笑地监视模块功能

开玩笑,意外的令牌导入