为WebPack和Jest配置映射别名,解决Jest模块查找失败问题
解决Webpack与Jest别名兼容的问题
我帮你分析下问题出在哪:你之前在jest.config.json里的moduleNameMapper配置只匹配了精确等于别名本身的模块(比如import Actions from 'Actions'),但实际代码里你大概率是这样导入的:import { fetchUser } from 'Actions/userActions'——这种带子路径的导入,你的正则^Actions$根本匹配不上,所以Jest找不到对应的模块。
核心解决方案:修改Jest的别名匹配规则
把moduleNameMapper里的别名规则改成能匹配别名开头的所有路径,具体配置如下:
"moduleNameMapper" : { "\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$" : "<rootDir>/src/__mocks__/fileMock.js", "\\.(css|less|scss|sass)$" : "<rootDir>/src/__mocks__/styleMock.js", // 匹配带子路径的导入(比如 Actions/userActions.js) "^Actions/(.*)$" : "<rootDir>/src/actions/$1", "^Components/(.*)$" : "<rootDir>/src/components/$1", "^Reducers/(.*)$" : "<rootDir>/src/reducers/$1", "^Sagas/(.*)$" : "<rootDir>/src/sagas/$1", // 匹配直接引用别名本身的情况(比如 import Actions from 'Actions') "^Actions$" : "<rootDir>/src/actions/", "^Components$" : "<rootDir>/src/components/", "^Reducers$" : "<rootDir>/src/reducers/", "^Sagas$" : "<rootDir>/src/sagas/" }
这里的关键是^Actions/(.*)$:
^Actions/匹配所有以Actions/开头的模块名(.*)捕获后面的子路径部分$1把捕获到的子路径拼到目标路径里,这样Actions/userActions就会被映射到<rootDir>/src/actions/userActions
优化方案:统一维护别名配置(避免重复修改)
如果不想Webpack和Jest两边重复写别名,可以把配置抽成单独的文件,两边共用:
- 新建
aliases.js文件:
const path = require('path'); // 基础别名配置(和Webpack里的一致) const baseAliases = { Actions: path.resolve(__dirname, 'src/actions/'), Components: path.resolve(__dirname, 'src/components/'), Reducers: path.resolve(__dirname, 'src/reducers/'), Sagas: path.resolve(__dirname, 'src/sagas/'), }; // 转换为Jest需要的moduleNameMapper格式 const jestAliases = {}; Object.entries(baseAliases).forEach(([alias, targetPath]) => { // 替换绝对路径为Jest的<rootDir>变量 const jestTarget = targetPath.replace(__dirname, '<rootDir>'); // 添加带子路径的匹配规则 jestAliases[`^${alias}/(.*)$`] = `${jestTarget}$1`; // 添加直接引用别名的匹配规则 jestAliases[`^${alias}$`] = jestTarget; }); module.exports = { webpackAliases: baseAliases, jestAliases, };
- 修改
webpack.config.js:
const { webpackAliases } = require('./aliases'); module.exports = { // ...其他配置 resolve: { alias: webpackAliases, }, };
- 修改
jest.config.json:
{ // ...其他配置 "moduleNameMapper": { "\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/src/__mocks__/fileMock.js", "\\.(css|less|scss|sass)$": "<rootDir>/src/__mocks__/styleMock.js", ...require('./aliases').jestAliases } }
这样以后要加新别名,只需要修改aliases.js就行,不用两边改,更省心。
内容的提问来源于stack exchange,提问作者Jplus2
相关产品推荐
相关产品推荐

