React Native打包器无法识别@作用域私有模块问题求助
我之前也踩过Metro bundler处理作用域模块的坑,咱们来一步步解决这个@mapbox模块找不到的问题。
问题根源分析
从你的错误提示能看出来:
Unable to resolve module
@mapbox/react-native-mapbox-glfrom/Users/jose/Desktop/townapps/shared/components/mapPopup/index.tsx: Module@mapbox/react-native-mapbox-gldoes not exist in the Haste module map or in these directories: /Users/jose/Desktop/townapps/shared/node_modules/@mapbox
Metro在解析shared目录下的文件时,会优先去shared/node_modules里找模块,而你的作用域包实际在apps/node_modules里。虽然你在extraNodeModules里配置了完整包路径,但Metro对作用域模块的解析逻辑是先识别@mapbox这个作用域,再找里面的react-native-mapbox-gl,直接写完整包名的配置方式没法被正确识别。
解决方案
修改你的rn-cli.config.js里的extraNodeModules配置,把作用域模块改成嵌套对象的形式:
const Path = require('path'); const blacklist = require('metro-bundler/src/blacklist') module.exports = { extraNodeModules: { 'react-native': Path.resolve(__dirname, 'node_modules/react-native'), react: Path.resolve(__dirname, 'node_modules/react'), axios: Path.resolve(__dirname, 'node_modules/axios'), redux: Path.resolve(__dirname, 'node_modules/redux'), moment: Path.resolve(__dirname, 'node_modules/moment'), 'react-native-navigation': Path.resolve(__dirname, 'node_modules/react-native-navigation'), 'react-redux': Path.resolve(__dirname, 'node_modules/react-redux'), 'redux-thunk': Path.resolve(__dirname, 'node_modules/redux-thunk'), 'react-native-google-sign-in': Path.resolve(__dirname, 'node_modules/react-native-google-sign-in'), 'react-native-facebook-login': Path.resolve(__dirname, 'node_modules/react-native-facebook-login'), 'reactotron-react-native': Path.resolve(__dirname, 'node_modules/reactotron-react-native'), 'react-native-linear-gradient': Path.resolve(__dirname, 'node_modules/react-native-linear-gradient'), 'lodash': Path.resolve(__dirname, 'node_modules/lodash'), 'react-native-communications': Path.resolve(__dirname,'node_modules/react-native-communications'), 'react-native-vector-icons': Path.resolve(__dirname, 'node_modules/react-native-vector-icons'), 'react-native-fast-image': Path.resolve(__dirname, 'node_modules/react-native-fast-image'), 'react-native-share': Path.resolve(__dirname, 'node_modules/react-native-share'), 'react-native-fetch-blob': Path.resolve(__dirname, 'node_modules/react-native-fetch-blob'), // 作用域模块改为嵌套对象形式 '@mapbox': { 'react-native-mapbox-gl': Path.resolve(__dirname, 'node_modules/@mapbox/react-native-mapbox-gl') } }, getProjectRoots: () => [__dirname, Path.join(__dirname, '../../shared')], };
额外步骤:清理缓存
修改配置后,一定要重置Metro的缓存,避免旧的解析规则残留:
npx react-native start --reset-cache
为什么这样有效?
Metro解析@mapbox/react-native-mapbox-gl时,会先解析@mapbox这个作用域目录,我们通过把@mapbox作为extraNodeModules的key,内部映射对应的包路径,就能让Metro正确定位到apps/node_modules里的作用域包,而不是去shared/node_modules里查找。
内容的提问来源于stack exchange,提问作者troyz

