了解应用未注册错误的含义以及如何在 Expo 或 React Native 应用中解决该错误。
在开发 Expo 或 React Native 应用时,遇到如下错误的情况并不少见:
¥When developing an Expo or React Native app, it's not uncommon to run into an error that looks like:
Application "main" has not been registered.
# Or
Invariant Violation: "main" has not been registered.
在此特定错误中,"main"
可以是任何字符串。
¥In this particular error, "main"
can be any string.
¥What this error means
¥An exception may be preventing your app from registering itself
导致此错误的最常见原因是应用在能够自行注册之前引发了异常。当 React Native 应用加载时,有两个步骤:
¥The most common cause of this error is that there is an exception thrown in your application before it's able to register itself. When a React Native application loads, there are two steps:
加载 JavaScript 代码,如果一切成功,那么你的应用将被注册。如果加载打包包时出现任何异常,则执行将中止,并且永远不会到达应用注册的部分。
¥Load the JavaScript code, and if everything is successful, then your application will be registered. If there is any exception when loading the bundle then execution will be aborted and it will never reach the part where your application is registered.
运行注册的应用。如果加载代码失败,则应用将不会注册,你将看到本页主题的错误。
¥Run the registered application. If loading the code failed, then the application won't be registered and you will see the error that is the subject of this page.
如果你遇到这种情况,你看到的错误消息是 红鲱鱼,它会分散你对导致应用未注册的真正错误的注意力。
¥If you're in this situation, the error message you're seeing is a red herring, it's distracting you from the real error that led to the application not being registered.
查看此错误消息之前的日志,了解可能导致该错误的原因。一个常见的原因是原生模块依赖的多个版本将自身注册为视图 - 例如 这个 Stack Overflow 线程,其中发布者的依赖中有多个版本的 react-native-safe-area-context
。
¥Look at your logs before this error message to see what may have caused it. A frequent cause is multiple versions of a native module dependency that registers itself as a view — for example this Stack Overflow thread where the poster has multiple versions of react-native-safe-area-context
in their dependencies.
¥Your app root component may not be registered
另一种可能性是提供给 AppRegistry.registerComponent
的 AppKey
与在原生 iOS 或 Android 端注册的 AppKey
之间存在不匹配。
¥Another possibility is that there is a mismatch between the AppKey
being provided to AppRegistry.registerComponent
, and the AppKey
being registered on the native iOS or Android side.
在托管项目中,默认行为是使用 "main" 作为 AppKey
。这是自动为你处理的,只要你不更改 package.json 中的 "main"
字段的默认值,那么这就会起作用。如果你想自定义应用入口点,请参阅 registerRootComponent API 参考。
¥In managed projects, the default behavior is to use "main" as the AppKey
. This is handled for you automatically, and as long as you don't change the "main"
field in your package.json from the default value then this will just work. If you want to customize the app entry point, please refer to the registerRootComponent API reference.
在使用原生代码的项目中,默认情况下你将在 index.js 中看到类似以下内容:
¥In projects with native code, you will see something like this in your index.js by default:
import { registerRootComponent } from 'expo';
import App from './App';
registerRootComponent(App);
其中 registerRootComponent
的实现为:
¥where registerRootComponent
is implemented as:
function registerRootComponent(component) {
AppRegistry.registerComponent('main', () => component);
}
在原生方面,在 AppDelegate.m 中你应该看到:
¥And on the native side, in AppDelegate.m you should see:
RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge moduleName:@"main" initialProperties:nil];
在 MainActivity.java 中:
¥and in MainActivity.java:
@Override
protected String getMainComponentName() {
return "main";
}
默认情况下,"main" 在整个项目中一致使用。如果你遇到此错误,则某些内容可能已发生变化,并且这些值不再一致。确保你在 JavaScript 端注册的名称是原生端所需的名称(如果你使用 Expo 的 registerRootComponent
函数,则为 "main")。
¥By default, "main" is consistently used throughout the project. If you're running into this error, something has likely changed and these values no longer coincide. Ensure that the names you are registering on the JavaScript side are the ones expected on the native side (if you're using Expo's registerRootComponent
function, that would be "main").
¥Other considerations
此错误也可能发生在其他一些情况下,但它不太可预测,并且修复将更针对你的项目。例如,其他一些情况是:
¥This error can also occur in a few other scenarios, but it's less predictable and the fixes would be more specific to your project. For example, some other cases are:
你正在连接到错误项目的本地开发服务器。尝试关闭其他 Expo CLI 或 React Native 社区 CLI 进程(使用 ps -A | grep "expo\|react-native"
查找它们)。
¥You're connecting to the wrong project's local development server. Try closing out other Expo CLI or React Native community CLI processes (find them with ps -A | grep "expo\|react-native"
).
如果此错误仅发生在你的生产应用中,请尝试使用 npx expo start --no-dev --minify
在生产模式下本地运行该应用以查找错误根源。
¥If this error is only occurring in your production app, then try running the app locally in production mode with npx expo start --no-dev --minify
to find the source of the error.