使用 Jest 和 Webpack 别名进行测试
Posted
技术标签:
【中文标题】使用 Jest 和 Webpack 别名进行测试【英文标题】:Testing with Jest and Webpack aliases 【发布时间】:2017-07-26 13:50:25 【问题描述】:我希望能够在使用 jest 时使用 webpack 别名来解析导入,最好是引用 webpack.aliases
以避免重复。
开玩笑的:
"jest":
"modulePaths": ["src"],
"moduleDirectories": ["node_modules"],
"moduleNameMapper":
"^@shared$": "<rootDir>/shared/",
"^@components$": "<rootDir>/shared/components/"
,
Webpack 别名:
exports.aliases =
'@shared': path.resolve(paths.APP_DIR, 'shared'),
'@components': path.resolve(paths.APP_DIR, 'shared/components'),
;
进口:
import Ordinal from '@shared/utils/Ordinal.jsx';
import Avatar from '@components/common/Avatar.jsx';
由于某种原因,@
会导致问题,因此在删除时(在别名和导入中),它可以找到 shared
但仍然无法解决 components
。
FAIL src/shared/components/test/Test.spec.jsx
● Test suite failed to run
Cannot find module '@shared/utils/Ordinal.jsx' from 'Test.jsx'
我尝试过使用jest-webpack-alias、babel-plugin-module-resolver 和Jest/Webpack docs
【问题讨论】:
因为你使用 webpack-2 你在 env:test 中使用transform-es2015-modules-commonjs
吗?见:using-with-webpack-2
***.com/questions/33190795/…的可能重复
@
符号表示scoped package,通常在您的第三方包路径中搜索。
【参考方案1】:
假设您的 webpack 别名位于“resolved_paths”块中的 webpack.yml 中。
要在 jest 中添加相同的别名,如果您的 jest 配置在 package.json 中:
"jest":
"moduleDirectories":
".",
"<rootDir>/shared/components/",
"<rootDir>/shared/",
"node_modules"
【讨论】:
【参考方案2】:对于任何使用@
作为其模块的root
的人,您必须更加具体,因为其他库可以在节点模块中使用@
。
moduleNameMapper:
"^@/(.*)$": "<rootDir>/src/$1"
,
它翻译为“任何与@/
匹配的东西都应该发送到<rootDir>/src/<rest of the path>
【讨论】:
【参考方案3】:使用:"jest": "^26.5.3",
和 "webpack": "4.41.5",
我能够将jest.config.js
中的 webpack/typescript 别名与此模式正确匹配:
Webpack 配置:
module.exports =
// the rest of your config
resolve:
alias:
'components': path.resolve(__dirname, 'js/app/components'),
'modules': path.resolve(__dirname, 'js/app/modules'),
'types': path.resolve(__dirname, 'js/types'),
'hooks': path.resolve(__dirname, 'js/app/hooks'),
'reducers': path.resolve(__dirname, 'js/app/reducers'),
'__test-utils__': path.resolve(__dirname, 'js/app/__test-utils__')
,
Jest.config.js:
moduleNameMapper:
'^types/(.*)$': '<rootDir>/js/types/$1',
'^components/(.*)$': '<rootDir>/js/app/components/$1',
'^modules/(.*)$': '<rootDir>/js/app/modules/$1',
'^hooks/(.*)$': '<rootDir>/js/app/hooks/$1',
'^reducers/(.*)$': '<rootDir>/js/app/reducers/$1',
'^__test-utils__/(.)$': '<rootDir>/js/app/__test-utils__/$1'
下面是对符号的解释:
(.*)$
:捕获完全匹配之后的任何内容(目录)
$1
:映射到我指定的目录中的这个值。
和 tsconfig.json:
"paths":
"config": ["config/dev", "config/production"],
"components/*": ["js/app/components/*"],
"modules/*": ["js/app/modules/*"],
"types/*": ["js/types/*"],
"hooks/*": ["js/app/hooks/*"],
"reducers/*": ["js/app/reducers/*"],
"__test-utils__/*": ["js/app/__test-utils__/*"]
【讨论】:
如果你确信你做的一切都是正确的,但 TS 仍然抱怨没有找到导入:友好提醒重新启动你的 TS 服务器。 这个答案值得更多的支持 =)【参考方案4】:这真是太疯狂了,但是当我尝试像这样在 package.json 中映射模块时:
"jest":
"moduleNameMapper":
'@root/(.*)': '<rootDir>/../$1'
它不起作用。
但是当我在jest.config.js
中做同样的事情时,它会起作用:
module.exports =
moduleNameMapper:
'@root/(.*)': '<rootDir>/../$1'
【讨论】:
【参考方案5】:这个解决方案对我很有效:
moduleNameMapper:
'^Screens(.*)': '<rootDir>/src/screens/$1',
'^Components(.*)': '<rootDir>/src/components/$1',
'^Assets(.*)': '<rootDir>/src/assets/$1',
'^Services/(.*)': '<rootDir>/src/services/$1',
,
【讨论】:
【参考方案6】:没有一个规定的答案对我有用。
能够使用以下模式解决:
Jest 版本 25+
moduleNameMapper:
'^Screens(.*)': '<rootDir>/src/screens/$1',
'^Components(.*)': '<rootDir>/src/components/$1',
'^Assets(.*)': '<rootDir>/src/assets/$1',
'^Services/(.*)': '<rootDir>/src/services/$1',
,
【讨论】:
【参考方案7】:这似乎已经解决了。
下面是一个工作设置:
版本
"jest": "~20.0.4"
"webpack": "^3.5.6"
package.json
"jest":
"moduleNameMapper":
"^@root(.*)$": "<rootDir>/src$1",
"^@components(.*)$": "<rootDir>/src/components$1",
webpack.shared.js
const paths =
APP_DIR: path.resolve(__dirname, '..', 'src'),
;
exports.resolveRoot = [paths.APP_DIR, 'node_modules'];
exports.aliases =
'@root': path.resolve(paths.APP_DIR, ''),
'@components': path.resolve(paths.APP_DIR, 'components'),
;
【讨论】:
请注意,配置可能位于jest.config.js
。
我的问题似乎是moduleNameMapper
只适用于您的源代码,但不适用于您的包代码。如何解决 node_modules 中具有 @
或 @@
别名的一些包?比如包umi
。【参考方案8】:
因为我在再次阅读之前遇到了同样的问题,这次更仔细地阅读了文档。正确的配置应该是:
"jest":
"moduleNameMapper":
"^@shared(.*)$": "<rootDir>/shared$1",
"^@components(.*)$": "<rootDir>/shared/components$1"
,
【讨论】:
我尝试实现此配置,但仍然遇到同样的问题。找不到导入的文件:Cannot find module '@shared/utils/Ordinal.jsx' from 'Test.jsx'
.
我必须用"modulePaths": ["src"]
解决我的路径。那么是的,这个解决方案奏效了:"^Commons$": "./Commons"
我遇到了与 OP 相同的问题,@mayid 的解决方案最终为我解决了这个问题。
如果你像我一样是个新手,这个配置可以在你的package.json
文件中找到【参考方案9】:
FWIW,尝试切换别名顺序,保持更具体的向上和不太具体的向下,例如
"moduleNameMapper":
"^@components$": "<rootDir>/shared/components/",
"^@shared$": "<rootDir>/shared/"
【讨论】:
结合leo的回答试过了,还是有同样的错误。 能不能把完整的代码分享给大家,最好是github? 不幸的是,它不是一个私有的公司存储库。 你能用最小可行的代码创建一个 git repo,这个问题可以重现吗? 我也收到了与作用域包相同的错误消息。我在 gist.github.com/batwicket/da72ffa7d5324d8f7c5eb11f0ba07fad 创建了一个非常小的项目。我尝试了别名方法..没有运气。我可能错过了一些简单的东西。任何帮助表示赞赏。以上是关于使用 Jest 和 Webpack 别名进行测试的主要内容,如果未能解决你的问题,请参考以下文章
我无法通过 symfony/webpack-encore 使用 Jest 和 Vuejs 运行测试