项目太大没有办法分享出来。
最新新做了一个包,ui-components ,把 app 里面的一些共用的 ui 组件都放到这个包里。本来还好的,但是昨天,把一个文件 A (引用了 react-router-dom )的放到了 ui-components 包里,结果,在跑 app 的 unit test 的时候,就报这个错了。unit test 是用的 jest 。
但这个文件 A 对应的组件,是肯定要放到 ui-component 里面的。这个 A 组件,也是需要用到 react-router-dom 里面的组件,比如 Link.
那现在怎么办?是因为 jest 事先加载了一个 cjs 版本的 react-router-dom ,然后在调用到 A 的时候,又使用了一个 esm 版本的么?
可是,我尝试写了一个很简单的 test case ,引用 ui-component 里面一个纯组件(没有引入 react-router-dom ),运行,还是报这个错。
google 了一下,貌似很罕见,寥寥几条相关内容,看完,还是不是所云。
有没有什么想法或者头绪?谢谢!
1
duan602728596 2022-03-23 15:36:38 +08:00
报错原因都写了啊,你在 commonjs 环境中引入了 ESM 的包,所以报错啊。
然后像 react 、react-dom 、react-router-dom 这种包就不要放到 dependencies 里了,放 peerDependencies 里吧。 |
2
yyfearth 2022-03-23 15:49:41 +08:00
做 lib 的时候 这些东西要尽量放到 peerDeps 然后如果要打包 需要 external
另外就是 jest 的问题 主要是 jest 是用 nodejs 跑的 所以引入一些 esm 的包就会出现问题 可能需要转译一下才能跑 |
3
yazoox OP @duan602728596 thx
@yyfearth 我们的 nodejs 已经是 14+ 版本了,应该可以支持 esm 了啊。 你说的转译是什么意思?是类似于 babel 么?不清楚怎么操作,有没有可以用于搜索的关键字或者文档? 谢谢 |
4
qqqqqcy 2022-03-23 16:58:03 +08:00
可以统一 jest 执行时,第三方依赖的模块规范选择。自定义一个 jest resolver
// build/resolver.js const fs = require('fs') const path = require('path') const resolve = require('resolve') function mapModuleFieldToMain (pkg, pkgDir) { const moduleSrcPath = pkg.module const isModuleFieldAvailable = moduleSrcPath && fs.existsSync(path.resolve(pkgDir, moduleSrcPath)) if (isModuleFieldAvailable) { return Object.assign({ }, pkg, { main: moduleSrcPath }) } return pkg } function defaultResolver (pathStr, options) { return resolve.sync(pathStr, { basedir: options.basedir, extensions: options.extensions, moduleDirectory: options.moduleDirectory, paths: options.paths, packageFilter: mapModuleFieldToMain }) } module.exports = defaultResolver -------------------- // jest.config.js // A path to a custom resolver // 自定义一个 resolver ,优先读取依赖的 esm 入口。和 rollup 对齐 resolver: '<rootDir>/build/resolver.js' --------- 我之前先过一个 SDK 的脚手架工具,生成的 SDK 模板代码里用到了类似的逻辑 https://github.com/draftbookJs/cli 。不知道你碰到的是不是这种问题 |
5
yyfearth 2022-03-24 02:01:49 +08:00
|
6
qqqqqcy 2022-03-24 11:22:27 +08:00
@yyfearth 我用的 preset: 'ts-jest/presets/js-with-ts-esm'。可以处理 ts 和 esm
|
8
changehow 2022-08-11 18:17:13 +08:00
我也在单元测试中遇到这个问题了= - =
|