从 Create React App(CRA)迁移
Astro 的 React 集成 支持在 Astro 组件中使用 React 组件,甚至包括像 Create React App (CRA) 这样的整个 React 应用程序!
当你在已安装 React 集成的 Astro 项目中直接添加应用时,许多应用程序将会作为完整的 React 应用程序运行。这是一个快速启动项目并在迁移到 Astro 过程中保持应用功能的绝佳方式。
随着时间的推移,你可以逐步将结构转换为由 .astro
和 .jsx
组件组合而成的形式。届时,你可能会发现你需要的 React 组件比你想象中的要少!
以下是一些关键概念和迁移策略帮助你入门,也可以继续阅读我们的文档和参与我们的 Discord 社区 以获取更多帮助!
CRA 和 Astro 的关键相似之处
段落标题 CRA 和 Astro 的关键相似之处-
.astro
文件的语法与 JSX 类似。编写 Astro 应该会让你感到熟悉。 -
Astro 使用基于文件的路由,并允许通过特殊的文件命名来创建动态路由。
-
Astro 是基于组件的,你的标记结构在迁移前后将类似。
-
Astro 提供了 React、Preact 和 Solid 的官方集成,因此你可以使用现有的 JSX 组件。请注意,这意味着在 Astro 中,这些文件的扩展名必须为
.jsx
或.tsx
。 -
Astro 支持 安装 NPM 包,包括 React 库。许多现有的依赖项在 Astro 中可以正常工作。
CRA 和 Astro 的关键差异
段落标题 CRA 和 Astro 的关键差异在用 Astro 重新构建 CRA 站点时,你会注意到一些重要的差异:
-
CRA 是一个使用
index.js
作为项目根目录的单页面应用程序。Astro 是一个多页面站点,其中index.astro
是你的首页。 -
.astro
组件 不是作为返回页面模板的导出函数而被构建。相反,你需要将代码分割到一个用于 JavaScript 的“代码围栏”和一个专门用于生成的 HTML 的“body”中。 -
内容驱动:Astro 的设计目标是展示你的内容,并允许你在需要时选择性地启用交互。如果现有的 CRA 应用用于构建高级的客户端交互,那么可能需要使用高级的 Astro 技术来让
.astro
组件来完成更具挑战性的复制,例如仪表板。
将 CRA 添加到 Astro
段落标题 将 CRA 添加到 Astro通常情况下,你可以直接在新的 Astro 项目中渲染现有的应用程序,而无需更改应用程序的代码。
创建一个新的 Astro 项目
段落标题 创建一个新的 Astro 项目通过你的包管理器来运行 create astro
命令启动 Astro 的 CLI 向导,并选择一个新的「空」Astro 项目。
添加集成和依赖
段落标题 添加集成和依赖通过你的包管理器来运行 astro add
命令以添加 React 集成。如果你的应用程序使用了 Tailwind 或 MDX,你可以使用相同的命令添加多个 Astro 集成:
如果你的 CRA 需要其他依赖项(例如 NPM 包),那么请使用命令行单独安装它们,或者将它们手动添加到你的新 Astro 项目的 package.json
中,然后运行安装命令。请注意,并非所有的 React 依赖项都能在 Astro 中正常工作。
添加现有的应用文件
段落标题 添加现有的应用文件将现有的 Create React App (CRA) 项目的源文件和文件夹(例如 components
、hooks
、styles
等)复制到 src/
内的一个新文件夹中,并保留其文件结构,以使你的应用程序继续正常工作。请注意,所有的 .js
文件扩展名必须重命名为 .jsx
或 .tsx
。
不要包含任何配置文件。你将使用 Astro 自己的 astro.config.mjs
、package.json
和 tsconfig.json
。
将应用程序的 public/
文件夹的内容(例如静态资源)移动到 Astro 的 public/
文件夹中。
文件夹public/
- logo.png
- favicon.ico
- …
文件夹src/
文件夹cra-project/
- App.jsx
- …
文件夹pages/
- index.astro
- astro.config.mjs
- package.json
- tsconfig.json
渲染你的应用
段落标题 渲染你的应用在 index.astro
的 frontmatter 部分导入你的应用程序的根组件,然后在页面模板中渲染 <App />
组件:
你的应用程序需要使用 客户端指令 来实现交互。在你选择启用客户端 JavaScript 之前,Astro 将把你的 React 应用程序呈现为静态 HTML。
而使用 client:load
来确保你的应用程序立即从服务器加载,或者使用 client:only="react"
来跳过在服务器上的渲染,完全在客户端运行你的应用程序。
将 CRA 转换为 Astro
段落标题 将 CRA 转换为 Astro除了 将现有应用程序添加到 Astro,你可能也希望将应用程序本身直接转换为 Astro!
你可以在现有结构的基础上 使用 Astro 的 HTML 模板组件 以重构类似的基于组件的设计,同时导入和包含个别的 React 组件(它们本身可能是完整的应用程序!)来实现群岛交互。
每个迁移的过程都会有所不同,你可以逐步进行迁移,而不会影响你正在工作的应用程序。按照自己的节奏逐渐转换每个部分,从而使应用程序中越来越多的部分由 Astro 组件驱动。
当你转换你的 React 应用程序时,你需要决定哪些 React 组件你将会 重写为 Astro 组件。唯一的限制是 Astro 组件可以导入 React 组件,但 React 组件只能导入其他 React 组件:
相比于在 React 组件中导入 Astro 组件而言,你可以在单个 Astro 组件中使用嵌套的 React 组件。
在将你的 CRA 重构为 Astro 项目之前,了解 Astro 群岛 和 Astro 组件 可能会对你有所帮助。
比较:JSX 与 Astro
段落标题 比较:JSX 与 Astro比较一下如下的 CRA 组件和相对应的 Astro 组件:
将 JSX 文件转换为 .astro
文件
段落标题 将 JSX 文件转换为 .astro 文件下面是将 CRA(Create React App)的 .js
组件转换为 .astro
组件的一些建议:
-
将现有 CRA 组件函数返回的 JSX 作为 HTML 模板的基础。
-
将任何 CRA 或 JSX 语法更改为 Astro 或 HTML 的标准规范。这包括
{children}
和className
等。 -
将任何必要的 JavaScript,包括导入语句,移动到 「代码围栏」(
---
) 中。注意:在 Astro 中,条件性渲染内容的 JavaScript 通常直接写在 HTML 模板中。 -
使用
Astro.props
访问之前传递给 CRA 函数的任何其他属性。 -
决定是否需要将任何导入的组件转换为 Astro。你可以将它们暂时保留为 React 组件,或永久保留为 React 组件。但是,如果它们不需要交互性,你可能最终会想将它们转换为
.astro
组件! -
将
useEffect()
替换为导入语句或import.meta.glob()
来查询本地文件,使用fetch()
来获取外部数据。
迁移测试
段落标题 迁移测试由于 Astro 输出原始的 HTML,因此可以使用构建步骤的输出来编写端到端测试。如果之前编写的端到端测试能够匹配 CRA 站点的标记,那么它们可能也可以直接使用。在 Astro 中,也可以导入和使用测试库(如 Jest 和 React Testing Library)来测试你的 React 组件。
了解更多详情,请参阅 Astro 的 测试指南。
参考:将 CRA 语法转换为 Astro
段落标题 参考:将 CRA 语法转换为 Astro在 Astro 中转换 CRA 导入语句
段落标题 在 Astro 中转换 CRA 导入语句将任何 文件导入 准确地更新为相对引用的文件路径。可以通过使用 导入别名 或完整写出相对路径来实现。
注意,.astro
和其他一些文件类型必须使用它们的完整文件扩展名进行导入。
在 Astro 中转换 CRA 子组件属性
段落标题 在 Astro 中转换 CRA 子组件属性将任何 {children}
实例转换为 Astro 的 <slot />
。Astro 不需要将 {children}
作为函数属性来传递,它会自动在 <slot />
中渲染子组件内容。
传递多组子元素的 React 组件可以通过使用 命名插槽 转换为 Astro 组件。
了解更多有关于 特定 <slot />
用法 的内容。
在 Astro 中转换 CRA 数据获取
段落标题 在 Astro 中转换 CRA 数据获取在 Create React App 组件中获取数据与 Astro 类似,只有一些细微的差别。
你需要移除任何副作用钩子(useEffect
)的实例,然后使用 import.meta.glob()
或 getCollection()
(或 getEntryBySlug()
)从项目源代码的其他文件中获取数据。
要 获取远程数据,请使用 fetch()
。
这些数据请求是在 Astro 组件的 frontmatter 中进行的,并使用顶层的 await。
了解更多有关于 使用 import.meta.glob()
导入本地文件、 使用集合 API 查询 以及 获取远程数据 的内容。
在 Astro 中转换 CRA 样式
段落标题 在 Astro 中转换 CRA 样式你可能需要用 Astro 中其他可用的 CSS 选项来替换任何 CSS-in-JS 库(例如 styled-components)。
如有必要,将任何行内样式对象(style={{ fontWeight: "bold" }}
)转换为行内的 HTML 样式属性(style="font-weight:bold;"
)。或者,使用 Astro 的 <style>
标签来实现作用域限定的 CSS 样式。
如果已安装了 Tailwind 集成,则可以支持 Tailwind,并且不需要更改现有的 Tailwind 代码!
了解更多有关于 Astro 中的样式 的内容。
故障排除
段落标题 故障排除你的 CRA 可能可以在 Astro 中正常工作!但是,你可能需要进行微小调整,以复制现有应用程序的功能和(或)样式。
如果在文档中未找到答案,请访问 Astro 的 Discord,并在我们的支持论坛上提问!