我在我的应用中通过npm导入deepmerge。环境包括webpack,babel,typescript,react,redux,jest。
我设法让Jest在ES2015导入时工作得很好,但是Jest拒绝使用esmer的es.js版本(参见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语句中指定正确文件的路径,而不是依赖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"
]
}
答案 0 :(得分:2)
编辑:稍微调整一下,使用包的模块字段。由于jest.mock的hoisting,无法创建辅助函数并且不得不重复三次名称。
jest.mock('modulename', () => require('modulename/' + require('modulename/package.json').module));
原始答案:
我在导入一个使用package.module的内部库时遇到了同样的问题。我的理解是因为JEST在节点中运行(并且我们的测试不通过WebPack),所以将忽略package.module并改为使用package.main。
我能够在测试中使用模拟来解决这个问题:
jest.mock('modulename', () => require('modulename/builds/es'));
对于使用pkg.module的每个模块来说,这很麻烦,但是要手动模拟其内容,我可以保持测试代码的导入完整。
另一种方法可能是编写一个转换,将模块的es版本映射/代理到commonjs版本,但它并没有让我走得太远。
我希望将来有更好的解决方案。