Skip to main content

迁移到 React 18

Backstage 核心库和插件兼容 React 从 v16.8 到 v18 的所有版本。 这意味着您可以按照自己的节奏迁移项目。 不过,我们鼓励您尽早迁移,一方面是为了跟上不断发展的生态系统,另一方面也是因为 React 18 带来了性能改进,尤其是在测试方面。

迁移

在深入了解之前,需要提醒大家的是,对于大型项目来说,这可能是一个棘手的迁移过程,因为很难将其分解为一个渐进的迁移过程。 在实践中,迁移的难点在于切换到新版本的"@testing-library/react "包进行测试,因为主要的 React 版本之间没有重叠的支持,这一点稍后会详细介绍。

切换到 React 18

要将项目切换到 React 18,一般需要进行三项更改。

  1. 将根目录 package.json 中的决议更新为新版本的 @types/react@types/react-dom
package.json
"resolutions": {
"@types/react": "^17",
"@types/react-dom": "^17",
"@types/react": "^18",
"@types/react-dom": "^18",
},
  1. packages/app/package.json中的reactreact-dom依赖项更新为新版本:
packages/app/package.json
"dependencies": {
...
"react": "^17.0.2",
"react-dom": "^17.0.2",
"react": "^18.0.2",
"react-dom": "^18.0.2",
...
},
  1. 更新 packages/app/src/index.tsx 以使用新的 react-dom/client API 来渲染应用程序:
packages/app/src/index.tsx
import '@backstage/cli/asset-types';
import React from 'react';
import ReactDOM from 'react-dom';
import ReactDOM from 'react-dom/client';
import App from './App';

ReactDOM.render(<App />, document.getElementById('root'));
ReactDOM.createRoot(document.getElementById('root')!).render(<App />);

完成这些步骤后,您就可以运行应用程序,看到它和以前一样工作,只不过现在使用的是 React 18。

TypeScript 错误

升级到 React 18 时,您很可能会看到相当数量的 TypeScript 类型错误。 有关破坏性更改的摘要,请参见引入它们的拉取请求此外,还提供了一个 codemod 以帮助迁移。

运行yarn tsc:full以评估损失。

好消息是,这些错误可以在 React 17 上得到修复。如果您有大量错误需要修复,您可以一次解决几个或多个错误,然后将它们合并到主分支中。没有这样,您就可以在尚未完全迁移到 React 18 的情况下,逐步迁移项目中的类型。 一旦修复了所有类型错误,您就可以进入下一步迁移测试。

###迁移测试

但如果运行测试,您可能会发现很多测试都失败了。@testing-library/react不幸的是,我们将要迁移到的新版本不支持 React 17,这就是为什么我们需要一次性完成这些工作。

info
如果一次性迁移整个项目不可行,您可以尝试添加devDependencies对于reactreact-dom我们还没有在实践中尝试过这种方法,如果您尝试过,请在社区 Discord 中告诉我们结果如何:

依赖性升级

要使测试恢复正常,我们需要更新@testing-library/react至少要升级到 v13 版,但由于额外的破坏性更改影响较小,因此至少要升级到 v14 版才是明智之举。 有关 v13 版更改的更多信息,请参见版本说明.

除了撞击@testing-library/react您还需要删除@testing-library/react-hooks软件包,因为它现在包含在@testing-library/react有关这一更改的更多信息,请参阅@testing-library/react-hooksREADME.md.

以下搜索和替换 RegEx 模式可能有助于更新您的package.json文件

查找:"@testing-library/react": ".*"
更换:"@testing-library/react": "^14.0.0"

查找:"@testing-library/react-hooks": ".*",?
更换:<nothing>

测试更新

一旦安装了新版本的依赖项,更新测试就变成了一个相当机械的过程。 请使用您自己喜欢的方法,先运行一次所有测试,找出故障点,然后每次集中处理一个测试文件,这样就会相当顺利。

在更新 Backstage 项目中的测试时,我们发现以下模式非常有用:

  • Many existing act(...) calls can be removed, it is built into most testing utilities like waitFor, .findBy*, and @testing-library/user-event. * Use .findBy* to wait for elements to appear. * Use waitFor(...) to wait for any other expected state changes or multiple elements. * Use @testing-library/user-event for user interactions. * The renderHook API has changes in several ways: - It no longer returns waitForValueToChange or waitForNextUpdate, you'll likely want to use waitFor instead. - It now throws errors rather than returns them as part of the result. - It no longer forwards initialProps to the wrapper, a workaround for this is provided in the docs. * Waiting for mock functions to be called by a component and then expecting render state to be updated is no longer reliable. * Rendered components often don't immediately update on user input, it's more common to need to use waitFor or

您还可以参考本节中的测试更改公关,也就是将 Backstage 项目本身迁移到 React 18。

祝您好运!如有问题,请加入社区 Discord如果您认为本文件可以改进,我们欢迎您打开问题或提交拉取请求。