React Native Expo项目绝对路径模块无法解析问题求助
使用babel-plugin-root-import和TypeScript配置绝对路径时,通过import {Config} from "~/Config/Config"导入根目录文件,出现「Unable to resolve module」错误。
错误信息:
Unable to resolve module ./src/Config/Config from D:\project\src\api\mos-api\fetchMosDataAsync.ts:
不存在以下文件:
- src\api\mos-api\src\Config\Config(.native|.ios.ts|.native.ts|.ts|.ios.tsx|.native.tsx|.tsx|.ios.js|.native.js|.js|.ios.jsx|.native.jsx|.jsx|.ios.json|.native.json|.json)
- src\api\mos-api\src\Config\Config\index(.native|.ios.ts|.native.ts|.ts|.ios.tsx|.native.tsx|.tsx|.ios.js|.native.js|.js|.ios.jsx|.native.jsx|.jsx|.ios.json|.native.json|.json)
从错误路径可见,TypeScript或Babel未生成绝对路径,反而将~/解析为当前文件相对路径下的src,导致路径拼接错误。
现有配置文件
package.json
"dependencies": { "@babel/runtime": "^7.20.7", "@expo/vector-icons": "^13.0.0", "@react-native-async-storage/async-storage": "~1.17.3", "@react-native-community/datetimepicker": "6.1.2", "@react-navigation/bottom-tabs": "^6.3.1", "@react-navigation/native": "^6.0.10", "@react-navigation/stack": "^6.2.2", "babel": "^6.23.0", "expo": "~45.0.0", "expo-font": "latest", "expo-linear-gradient": "~11.3.0", "expo-network": "~4.2.0", "expo-status-bar": "~1.3.0", "expo-updates": "~0.13.4", "html-entities": "^2.3.3", "lodash": "^4.17.21", "react": "17.0.2", "react-dom": "17.0.2", "react-native": "0.68.2", "react-native-app-intro-slider": "^4.0.4", "react-native-gesture-handler": "~2.2.1", "react-native-modal-datetime-picker": "^13.1.2", "react-native-reanimated": "~2.8.0", "react-native-safe-area-context": "4.2.4", "react-native-screens": "~3.11.1", "react-native-svg": "12.3.0", "react-native-web": "0.17.7" }, "devDependencies": { "@babel/core": "^7.12.9", "@types/lodash": "^4.14.182", "@types/react": "~17.0.21", "@types/react-native": "~0.66.13", "babel-plugin-root-import": "^6.6.0", "typescript": "^4.8.4" },
babel.config.js
module.exports = function(api) { api.cache(true); return { presets: ['babel-preset-expo'], plugins: [ 'react-native-reanimated/plugin', [ 'babel-plugin-root-import', { rootPathPrefix: '~', rootPathSuffix: 'src', } ] ], };
tsconfig.json
{ "extends": "expo/tsconfig.base", "compilerOptions": { "strict": true, "baseUrl": "src", "rootDir": "src", "paths": { "~/*": ["*"] } }
问题核心是Babel与TypeScript的路径配置不匹配,且babel-plugin-root-import在Expo/React Native环境下的路径解析逻辑存在兼容性问题。以下是修复步骤:
1. 统一路径映射规则(适配原插件)
TypeScript的paths将~/*映射到*(因baseUrl设为src),但Babel插件的rootPathSuffix为src,导致Babel把~/Config/Config解析为当前文件相对路径下的src/Config/Config,而非项目根目录下的对应文件。
修改babel.config.js,将rootPathSuffix指定为项目根目录:
module.exports = function(api) { api.cache(true); return { presets: ['babel-preset-expo'], plugins: [ 'react-native-reanimated/plugin', [ 'babel-plugin-root-import', { rootPathPrefix: '~', rootPathSuffix: process.cwd(), // 动态获取项目根目录 } ] ], };
同时调整tsconfig.json的baseUrl和paths,与Babel保持一致:
{ "extends": "expo/tsconfig.base", "compilerOptions": { "strict": true, "baseUrl": "./", // 改为项目根目录 "rootDir": "src", "paths": { "~/*": ["src/*"] // 直接映射到src下的文件 } }
2. 替换为更兼容的插件(推荐)
babel-plugin-root-import在Expo环境中易出问题,推荐使用babel-plugin-module-resolver,配置更清晰且兼容性更好:
安装依赖
npm install --save-dev babel-plugin-module-resolver
修改babel.config.js
module.exports = function(api) { api.cache(true); return { presets: ['babel-preset-expo'], plugins: [ 'react-native-reanimated/plugin', [ 'module-resolver', { root: ['./src'], alias: { '~': './src', }, }, ], ], };
修改tsconfig.json
{ "extends": "expo/tsconfig.base", "compilerOptions": { "strict": true, "baseUrl": "./", "rootDir": "src", "paths": { "~/*": ["src/*"] } }
3. 清除缓存并重启项目
修改配置后,清除Expo/React Native缓存避免旧配置残留:
# Expo项目 expo r -c # React Native项目 npx react-native start --reset-cache
完成以上步骤后,import {Config} from "~/Config/Config"即可正确解析到项目根目录下的src/Config/Config.ts文件。
内容的提问来源于stack exchange,提问作者Jostar

