用于非树形平台的 Metro 配置
如何设置和诊断 react-native-macos
和 react-native-windows
的 Metro 配置问题。本文档中的许多说明可能只提及 react-native-windows
,但这些步骤同样适用于 react-native-macos
。
版本要求
这里的信息仅适用于 react-native-macos
>=0.62.11 和 react-native-windows
>=0.62.0 的版本。此外,还要求您拥有 @react-native-community/cli
>=4.9.0。旧版本需要更复杂的配置,本文档不予涵盖。
macOS/Windows 的 Metro 配置需要做什么
react-native-macos
和 react-native-windows
通过提供一份额外的 react-native
JavaScript 文件副本,实现了各自平台的实现。这些 JavaScript 代码不包含在 react-native
包中。当您通常执行 import from 'react-native'
时,Metro 会在文件路径中向上查找 node_modules/react-native
以找到该模块。不幸的是,当使用 react-native-macos
或 react-native-windows
时,这将返回错误的 JavaScript 代码。一个简单的解决方案可能是添加一个包含以下内容的 Metro 配置:
resolver {
extraNodeModules: {
'react-native': <path-to-react-native-windows>
}
}
虽然这可以使 Metro 在构建 Windows 捆绑包时找到正确的 JavaScript 文件,但该配置不适用于 macOS、iOS 和 Android。相反,我们真正需要的是 Metro 根据当前正在捆绑的平台以不同的方式解析 react-native
。
解决方案是为 Metro 提供一个自定义解析器,该解析器考虑了当前正在解析的平台。从 @react-native-community/cli@4.9.0
开始,react-native
CLI 中添加了一个更改,用于配置 Metro 以使用恰好能做到这一点的自定义解析器。
诊断 Metro 配置问题
这些问题通常表现为类似如下的失败:
Error: Unable to resolve module `./Libraries/Components/AccessibilityInfo/AccessibilityInfo` from <Some file path here>
通常是导入 AccessibilityInfo
失败,这是因为这是 react-native
本身尝试解析的第一个模块,而该模块在 react-native
中只包含 .ios
和 .android
版本的文件。
重置你的 Metro 缓存
有时在更新包版本或修改 Metro 配置后,Metro 缓存可能会不同步。一个简单的尝试是重置 Metro 的文件缓存。这可以通过运行 yarn start --reset-cache
来完成。
验证平台已安装并挂接到 CLI
运行 npx react-native config
。查看输出并根据您正在使用的平台,验证 JSON 是否包含 platforms.macos.npmPackageName
属性或 platforms.windows.npmPackageName
属性(或两者)。
{
...
"platforms": {
"ios": {},
"android": {},
"macos": {
"npmPackageName": "react-native-macos"
},
"windows": {
"npmPackageName": "react-native-windows"
}
},
...
}
如果在单一仓库中,请验证 react-native-macos/react-native-windows 未包含在您的 exclusionList 中
如果您不确定 react-native-windows
安装在哪里,可以运行 node -p require.resolve('react-native-windows')
。确保 react-native-windows
文件夹未包含在您的 metro.config.js
的 exclusionList 中。
watchFolders
中
验证 react-native-macos/react-native-windows 在你的 默认情况下,Metro 配置会看到您的包文件夹中的所有文件。许多包管理器,尤其是在单仓库(yarn workspaces 等)中运行时,会将包提升到包本地文件结构之外的位置。在这种情况下,您可能需要向 Metro 的观察列表添加额外的文件夹。这可以通过添加到 Metro 配置来完成:
watchFolders: [
// Include hoisted modules
path.resolve(__dirname, '../..', 'node_modules'),
],
上述文件位置应包含 node -p require.resolve('react-native-windows')
返回的 react-native-windows
路径。
如果您的设置包含符号链接
各种包管理器可能会在 node_modules
中创建符号链接。Metro 不支持跟随符号链接,因此如果 node_modules/react-native-windows
是一个符号链接,Metro 将无法找到它。如果是这种情况,您可以添加:
resolver {
extraNodeModules: {
'react-native-windows': <path-to-react-native-windows>
}
}
到您的 Metro 配置中,以通知 Metro react-native-windows
的真实位置。
再次重置缓存
如果您按顺序遵循这些步骤,您可能已经对 Metro 配置文件进行了一系列更改。您是否尝试过再次重置 Metro 缓存?yarn start --reset-cache