首页
/ Expo Router 从 SDK 55 升级到 56 后如何用 codemod 替换 @react-navigation/* 导入

Expo Router 从 SDK 55 升级到 56 后如何用 codemod 替换 @react-navigation/* 导入

2026-09-08 19:44:34作者:胡易黎Nicole

从 SDK 56 开始,Expo Router 不再支持在应用代码中从外部 @react-navigation/* 包导入,需要把这些导入换成对应的 expo-router 入口。运行时 API 本身没有变化,只有模块说明符(module specifier)发生了移动。如果你的项目已从 SDK 55 升到 SDK 56、应用代码里仍残留 @react-navigation/* 导入,就可以按本文流程:在仓库根目录运行官方的 expo-codemod transform 批量改写导入,处理两个没有直接替代项的包,再用 bundler 验证没有漏改的旧导入。

本文依据官方迁移页 SDK 55 to 56expo-codemod 包文档

变更范围:只是导入路径

先确认改动边界:这次升级只替换导入的包名,你调用的 API 不变。文档给出的映射如下:

React Navigation source Expo Router target
@react-navigation/native expo-router/react-navigation
@react-navigation/core expo-router/react-navigation
@react-navigation/elements expo-router/react-navigation
@react-navigation/routers expo-router/react-navigation
@react-navigation/stack expo-router/js-stack
@react-navigation/bottom-tabs expo-router/js-tabs
@react-navigation/material-top-tabs expo-router/js-top-tabs
@react-navigation/native-stack 无直接替代,改用 Stack layout
@react-navigation/drawer 无直接替代,改用 Drawer layout

最后两个包不会被 codemod 自动改写,需要结构化的手动迁移,见“处理两个没有直接替代项的包”。

运行 codemod

项目根目录执行。注意这条命令会改写指定路径下源文件中的导入语句,transform 只处理你传入的路径或 glob 匹配到的文件:

# npm
npx expo-codemod sdk-56-expo-router-react-navigation-replace src

# yarn
yarn dlx expo-codemod sdk-56-expo-router-react-navigation-replace src

# pnpm
pnpm dlx expo-codemod sdk-56-expo-router-react-navigation-replace src

# bun
bunx expo-codemod sdk-56-expo-router-react-navigation-replace src

src 替换成你应用代码所在的目录或 glob。expo-codemod CLI 的用法是 npx expo-codemod <transform> <paths...>,可以传多个路径;glob 需要加引号防止 shell 先展开:

npx expo-codemod sdk-56-expo-router-react-navigation-replace '**/*.{ts,tsx,js,jsx}'

这个 transform 做的事:

  • 把映射表中的 @react-navigation/* 命名导入改写为对应的 expo-router 入口;
  • 把同一文件中重复的 expo-router 导入合并成一条(type-only 导入与 value 导入混合时按 inline type 标记处理)。

两个限制来自 codemod 的文档与实现 sdk-56-expo-router-react-navigation-replace.ts

  • 对映射包而言,默认导入(import X from ...)和命名空间导入(import * as X from ...)不支持,只有命名导入(import { A } from ...)能被安全改写。遇到时 codemod 会输出 “Unsupported import style — manual change needed” 错误块,要求你改成命名导入后重新运行;
  • 遇到不支持的包(native-stackdrawer)时不会改写该文件的导入,只输出 “Migration required — manual change needed” 并列出文件位置。

处理两个没有直接替代项的包

如果代码里用了 @react-navigation/native-stack@react-navigation/drawer,codemod 无法自动替换,它只报告位置并提示手动修改:

  • @react-navigation/native-stack → 改用 expo-router 的 Stack layout;
  • @react-navigation/drawer → 改用 expo-router 的 Drawer layout。

迁移页的映射表中这两行分别链到对应的 layout 文档(/router/advanced/stack/router/advanced/drawer),按这些页面把对应导航代码改为基于文件的 layout。这两处是唯一需要真正重构代码的部分,codemod 覆盖不到。

验证迁移是否完整

文档给出了两类可核对的信号:

  1. codemod 的输出。运行后,错误块中列出的文件需要逐个手动处理;没有出现在输出里、且文件内容已按映射表改写的,即为完成。
  2. bundler 报错。SDK 56 中,应用代码如果仍从 @react-navigation/* 导入,bundler 会报错。改完后正常启动项目(如 npx expo start),不再出现这类报错,说明应用代码中的旧导入已清完。

阅读改写后的代码时,按第一节的映射表核对导入路径。这里有一处文档不一致需要你注意:expo-codemod README 的表格把 @react-navigation/native 写成映射到 expo-router(主入口),而迁移页和 codemod 实现源码都使用 expo-router/react-navigation。本文以迁移页与代码实际生成的导入为准;./react-navigation 入口在 expo-router 包的 exports 中确有声明,./js-stack./js-tabs./js-top-tabs 同样如此。

手动迁移:codemod 跑不了时的替代路径

如果环境不允许运行 codemod,就按映射表逐个改。文档给出的示例:

// Before (SDK 55)
import { ThemeProvider, DarkTheme } from '@react-navigation/native';
import { createMaterialTopTabNavigator } from '@react-navigation/material-top-tabs';

// After (SDK 56)
import { ThemeProvider, DarkTheme } from 'expo-router/react-navigation';
import { createMaterialTopTabNavigator } from 'expo-router/js-top-tabs';

完整映射见第一节表格;native-stackdrawer 仍需改用 Stack / Drawer layout。

第三方库与兼容 shim

很多第三方库仍然从 @react-navigation/core 导入。为平滑 SDK 56 过渡,Expo CLI 会在这些导入来自 node_modules 时自动把它们改写成 expo-router,你的应用代码不受这次改写影响。文档明确说明这是临时的兼容 shim:在自动改写移除之前,会有一份专门的库迁移指南解释替代方式。

如果你要关闭这个行为,在启动 bundler 前设置环境变量 EXPO_ROUTER_DISABLE_RN_NAVIGATION_CHECK=1。注意这同时会禁用“应用代码从 @react-navigation/* 导入”时的 bundler 报错:

# npm
EXPO_ROUTER_DISABLE_RN_NAVIGATION_CHECK=1 npx expo start

# yarn
EXPO_ROUTER_DISABLE_RN_NAVIGATION_CHECK=1 yarn expo start

# pnpm
EXPO_ROUTER_DISABLE_RN_NAVIGATION_CHECK=1 pnpm expo start

# bun
EXPO_ROUTER_DISABLE_RN_NAVIGATION_CHECK=1 bun expo start

这个变量会同时关掉检测漏改旧导入的报错,迁移完成前使用它会让未改完的导入不被暴露,只在你明确需要绕过这个检查时使用。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.14 K
2.75 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
857
1.35 K
docsdocs
暂无描述
Markdown
898
5.82 K
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
921
1.84 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.8 K
1.02 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
531
596
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
1.02 K
519
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.36 K
1.46 K
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
548
391