Skip to main content

React 路由器 6.0 迁移

长期以来,Backstage 一直在使用react-router版本6.0.0-beta.0我们之所以采用这个不稳定版本,是因为 v6 有一些新功能与 Backstage 非常契合,尤其是相对路由功能。 因为我们很早就采用了这个不稳定版本,所以我们知道在某些时候我们需要向稳定版迁移。react-router第 6 版,也就是我们现在所处的阶段!

这种迁移是必需的,但可由每个应用程序控制,也就是说,您可以选择何时迁移您的应用程序。 不过,在未来的某个时间点,我们将放弃对测试版的支持。react-router届时,您将被迫迁移。

React Router v6 稳定版带来了许多改进和错误修复。 值得注意的是,路径的解析方式得到了改进,修复了一个错误,在该错误中,路径如/catalog/catalog-import可能会混淆。

迁移

步骤 1 - 升级至 Backstage 1.6

Backstage 首次发布支持react-routerv6 是1.6如果您是早起的鸟儿,想在该版本发布前尝试迁移,也可以在1.6.0-next.1.

第 2 步 - 将 react-router 移到 peerDependencies

重要的是,只有一个版本的react-router的方式类似。react版本时,所有插件和软件包现在都会声明对 React Router 依赖项的对等依赖,而不是直接依赖。 唯一的例外是应用程序软件包(在packages/app/package.json),其中的直接依赖关系最终会决定您在项目中使用的 React Router 版本。

您的内部软件包可能会指定依赖于react-routerreact-router-dom在其package.json重要的是,要将这些转换为peerDependencies的版本,这样我们就可以控制react-router在应用程序中package.json.

您可以通过运行以下命令自动完成这一步骤:

yarn backstage-cli migrate react-router-deps

有兴趣手动操作的用户,请将以下更改应用到所有package.json的文件除外。packages/app/package.json或任何其他应用程序软件包。 跳过移动任何尚不存在的依赖项,同时移动dependenciesdevDependencies.

package.json
dependencies {
...
- "react-router-dom": "^6.0.0-beta.0",
- "react-router": "^6.0.0-beta.0"
},
peerDependencies: {
...
+ "react-router-dom": "6.0.0-beta.0 || ^6.3.0",
+ "react-router": "6.0.0-beta.0 || ^6.3.0"
},

第 3 步 - 确保更新外部插件

重要的是,您还应将外部插件更新到最新版本,因为这些插件必须执行相同的功能peerDependencies更新。

在迁移过程中,可能有外部插件需要更新。@backstage请确保在插件的 GitHub 代码库中检查现有问题或提出新问题。

第 4 步 - 在应用程序中调整 React 路由器依赖关系

现在是时候迁移到最新版本的 React Router 了。 在撰写本文的时候,这就是6.3.0但这当然是一个不断变化的目标。

第一步是修改packages/app/package.json:

package.json
-    "react-router": "6.0.0-beta.0",
- "react-router-dom": "6.0.0-beta.0",
+ "react-router": "^6.3.0",
+ "react-router-dom": "^6.3.0",

如果您的项目中恰好有多个应用程序软件包,请对所有这些软件包应用相同的更改。

更改完成后,运行yarn install然后yarn why react-router你会在日志中看到下面一行作为唯一的结果条目:

如果您看到多个条目,特别是=> Found "[email protected]"那么您的依赖项还没有完全迁移到支持 React Router v6 稳定版。 请使用 Yarn 中的信息仔细检查上述步骤。why命令记录。yarn why react-router-dom.

如果您最终无法将整个项目干净利落地转移到稳定版本,那么您可以使用 Yarn"resolutions"在根目录中覆盖package.json尽量避免使用该选项,因为它可能会在运行时导致隐藏的故障,并验证任何需要覆盖的插件。 更好的选择可能是暂缓迁移,直到插件有时间更新。

第 5 步 - 打破常规更改

对于使用npx @backstage/create-app如果您创建了内部插件和自定义,请务必查看React 路由器更新日志我们将最重要的重大变更总结如下。

打破常规

参见更新日志下面我们重点介绍几项最重要的变更。

路线路径

Route组件必须始终包含一个pathindex托。

<Routes>
{/* Invalid */}
<Route element={<Example />} />

{/* Valid */}
<Route path="/" element={<Example />} />

{/* Valid but discouraged due to incompatibility with react-router beta */}
<Route index element={<Example />} />
</Routes>

每个Routes元素现在必须与自己的位置相匹配,这意味着以下内容无效:

<Routes>
<Route path="/foo">
<Route path="/bar" /> {/* INVALID, must be "/foo/bar" or "bar" */}
</Route>
</Routes>

路由和路由组件

RoutesRoute组件都进行了大量的相关修改。Route元素和 React 片段是一个Routes这意味着像这样的结构

<Routes>
<MyComponent path="/foo" />
...
</Routes>

需要迁移至此:

<Routes>
<Route path="/foo" element={<MyComponent />} />
...
</Routes>

Routes改变,就无法再渲染Route元素之外的Routes以前,渲染这样的Route元素的内容会导致其element道具,但现在会出错。

PermissionedRoute 允许的路径

由于上述变化,"......PermissionedRoute组件已不再适用于 React Router v6 稳定版的所有情况。 该组件已被弃用,转而使用新的RequirePermission组件,它可以放置在任何地方,以便执行权限检查。

更新到RequirePermission的同时更新到 React Router v6 稳定版。PermissionedRoute组件将不再起作用。

<PermissionedRoute
path="/catalog-import"
permission={catalogEntityCreatePermission}
element={<CatalogImportPage />}
<Route
path="/catalog-import"
element={
<RequirePermission permission={catalogEntityCreatePermission}>
<CatalogImportPage />
</RequirePermission>
}
/>

###<Navigate /> 组件

迁移到 React Router v6 稳定版时,您可能还会看到浏览器控制台针对Navigate这需要用一个Route组件的Navigate组件中的element托。

{
}
<Navigate key="/" to="catalog" />;
{
}
<Route path="/" element={<Navigate to="catalog" />} />;

NavLink组件不再具有activeClassNameactiveStyle道具。classNamestyle道具接受一个回调,该回调接收一个布尔值,表示链接是否激活。

面向插件作者

在迁移已发布的插件时,有几件事需要注意。 当然,您需要确保 React Router 的依赖关系被迁移到peerDependencies此外,您还需要确保您的插件在运行时真正兼容两个版本的 React Router。 为了帮助您实现这一目标,您可以遵循以下附加指南:

  • 在你自己的项目中提升 react-routerreact-router-dom 的版本,以使用稳定版本。 如果你的插件是单包项目,请将它们放在 devDependencies 中。 稳定版本更加严格,因此这是更好的工作基准。 * 确保所有 Route 元素都有一个 path prop。 不要使用新的 index prop,因为 beta 版本不支持它。 Routes 中的索引路由使用 path="/" 。 * 如果你正在使用 NavLink,请同时使用新旧 API,并绕过任何 TypeScript 错误。

疑难解答

检查浏览器控制台,查看 React 路由器相关的错误信息。

检查yarn.lock版本的软件包react-router:

yarn why react-router