纯React Native项目执行npx expo start报错‘main’未注册,如何自定义名称?
npx expo start时"main"未注册的问题 问题描述
我用React Native CLI创建了纯RN项目,执行npx expo start启动时出现以下错误:
iOS Bundling complete 36518ms
ERROR Invariant Violation: "main" has not been registered. This can happen if:
- Metro (the local dev server) is run from the wrong folder. Check if Metro is running, stop it and restart it in the current project.
- A module failed to load due to an error and
AppRegistry.registerComponentwasn't called., js engine: hermes
我确认package.json、AppDelegate.mm和从app.json导入名称的index.js中,应用名称均为sotravelapp,但错误提示却指向main。将名称改为main后项目可正常运行,但我希望使用自定义名称,该如何调整?
解决方案
1. 配置app.json明确应用名称与入口
在app.json中指定自定义的name和entryPoint(确保entryPoint指向你的项目入口文件,通常是./index.js):
{ "name": "sotravelapp", "displayName": "sotravelapp", "entryPoint": "./index.js" }
2. 修正index.js的组件注册逻辑
选择以下两种方式之一:
方式一:使用Expo的registerRootComponent(推荐)
确保已安装expo,然后在index.js中替换原生注册逻辑:
import { registerRootComponent } from 'expo'; import App from './App'; registerRootComponent(App);
这个方法会自动读取app.json中的name作为注册名称,无需手动指定。
方式二:保留原生RN注册方式
确保注册的名称与app.json的name一致:
import { AppRegistry } from 'react-native'; import App from './App'; import { name as appName } from './app.json'; AppRegistry.registerComponent(appName, () => App);
3. 调整iOS端AppDelegate.mm配置
修改didFinishLaunchingWithOptions方法中的模块名称,确保它指向你的自定义应用名称:
#import <Expo/Expo.h> - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { [EXAppLoaderProvider prepare]; RCTBridge *bridge = [[RCTBridge alloc] initWithDelegate:self launchOptions:launchOptions]; // 这里使用Info.plist中的DisplayName或直接写你的应用名称 NSString *moduleName = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleDisplayName"]; RCTRootView *rootView = [[RCTRootView alloc] initWithBridge:bridge moduleName:moduleName initialProperties:nil]; // 保留后续原有代码 rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1]; self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds]; UIViewController *rootViewController = [UIViewController new]; rootViewController.view = rootView; self.window.rootViewController = rootViewController; [self.window makeKeyAndVisible]; return YES; }
4. 清理缓存并重启Metro
执行命令清理缓存,避免旧配置干扰:
npx expo start --clear
原因说明
在React Native CLI项目中使用npx expo start时,Expo工具链默认会以main作为入口模块名称。只有当你在app.json明确指定name,并确保index.js和原生端的注册名称与之一致时,才能覆盖默认的main,使用自定义应用名称。
内容的提问来源于stack exchange,提问作者Nathan Tew

