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 声明的主要内容,如果未能解决你的问题,请参考以下文章