使用您最喜欢的AI助手总结文档,并引用此页面和AI提供商
此页面的内容已使用 AI 翻译。
查看英文原文的最新版本如果您有改善此文档的想法,请随时通过在GitHub上提交拉取请求来贡献。
文档的 GitHub 链接复制文档 Markdown 到剪贴板
import AstroJSXTabs from '/components/tabs/AstroJSXTabs.astro';
import PackageManagerTabs from '/components/tabs/PackageManagerTabs.astro';
import { FileTree, LinkCard, CardGrid } from '@astrojs/starlight/components';
import ReadMore from '/components/ReadMore.astro';
import Badge from "/components/Badge.astro"
Astro 的 React 集成 支持在 Astro 组件中使用 React 组件,甚至包括像 Create React App (CRA) 这样的整个 React 应用程序!
复制代码到剪贴板
---// 导入你的根应用组件import App from '../cra-project/App.jsx';---<!-- 使用客户端指令加载你的应用 --><App client:load />
了解如何使用 React Router 在 Astro 中构建单页应用程序(SPA) 。
当你在已安装 React 集成的 Astro 项目中直接添加应用时,许多应用程序将会作为完整的 React 应用程序运行。这是一个快速启动项目并在迁移到 Astro 过程中保持应用功能的绝佳方式。
随着时间的推移,你可以逐步将结构转换为由 .astro 和 .jsx 组件组合而成的形式。届时,你可能会发现你需要的 React 组件比你想象中的要少!
以下是一些关键概念和迁移策略帮助你入门,也可以继续阅读我们的文档和参与我们的 Discord 社区 以获取更多帮助!
CRA 和 Astro 的关键相似之处
-
.astro 文件的语法与 JSX 类似。编写 Astro 应该会让你感到熟悉。
-
Astro 使用基于文件的路由,并允许通过特殊的文件命名来创建动态路由。
-
Astro 是基于组件的,你的标记结构在迁移前后将类似。
-
Astro 提供了 React、Preact 和 Solid 的官方集成,因此你可以使用现有的 JSX 组件。请注意,这意味着在 Astro 中,这些文件的扩展名必须为 .jsx 或 .tsx。
-
Astro 支持 安装 NPM 包,包括 React 库。许多现有的依赖项在 Astro 中可以正常工作。
CRA 和 Astro 的关键差异
在用 Astro 重新构建 CRA 站点时,你会注意到一些重要的差异:
-
CRA 是一个使用 index.js 作为项目根目录的单页面应用程序。Astro 是一个多页面站点,其中 index.astro 是你的首页。
-
.astro 组件 不是作为返回页面模板的导出函数而被构建。相反,你需要将代码分割到一个用于 JavaScript 的“代码围栏”和一个专门用于生成的 HTML 的“body”中。
-
内容驱动:Astro 的设计目标是展示你的内容,并允许你在需要时选择性地启用交互。如果现有的 CRA 应用用于构建高级的客户端交互,那么可能需要使用高级的 Astro 技术来让 .astro 组件来完成更具挑战性的复制,例如仪表板。
将 CRA 添加到 Astro
通常情况下,你可以直接在新的 Astro 项目中渲染现有的应用程序,而无需更改应用程序的代码。
创建一个新的 Astro 项目
通过你的包管理器来运行 create astro 命令启动 Astro 的 CLI 向导,并选择一个新的「空」Astro 项目。
添加集成和依赖
通过你的包管理器来运行 astro add 命令以添加 React 集成。如果你的应用程序使用了其他的支持 astro add 命令的包,例如 Tailwind 和 MDX,那么你便能够仅用一个命令就添加它们:
如果你的 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/ 文件夹中。
渲染你的应用
在 index.astro 的 frontmatter 部分导入你的应用程序的根组件,然后在页面模板中渲染 <App /> 组件:
复制代码到剪贴板
---import App from '../cra-project/App.jsx';---<App client:load />
:::note[客户端指令] 你的应用程序需要使用 客户端指令 来实现交互。在你选择启用客户端 JavaScript 之前,Astro 将把你的 React 应用程序呈现为静态 HTML。
而使用 client:load 来确保你的应用程序立即从服务器加载,或者使用 client:only="react" 来跳过在服务器上的渲染,完全在客户端运行你的应用程序。 :::
将 CRA 转换为 Astro
除了 将现有应用程序添加到 Astro,你可能也希望将应用程序本身直接转换为 Astro!
你可以在现有结构的基础上 使用 Astro 的 HTML 模板组件 以重构类似的基于组件的设计,同时导入和包含个别的 React 组件(它们本身可能是完整的应用程序!)来实现群岛交互。
每个迁移的过程都会有所不同,你可以逐步进行迁移,而不会影响你正在工作的应用程序。按照自己的节奏逐渐转换每个部分,从而使应用程序中越来越多的部分由 Astro 组件驱动。
当你转换你的 React 应用程序时,你需要决定哪些 React 组件你将会 重写为 Astro 组件。唯一的限制是 Astro 组件可以导入 React 组件,但 React 组件只能导入其他 React 组件:
复制代码到剪贴板
---import MyReactComponent from '../components/MyReactComponent.jsx';---<html> <body> <h1>Use React components directly in Astro!</h1> <MyReactComponent /> </body></html>
相比于在 React 组件中导入 Astro 组件而言,你可以在单个 Astro 组件中使用嵌套的 React 组件。
复制代码到剪贴板
---import MyReactSidebar from '../components/MyReactSidebar.jsx';import MyReactButton from '../components/MyReactButton.jsx';---<MyReactSidebar> <p>Here is a sidebar with some text and a button.</p> <div slot="actions"> <MyReactButton client:idle /> </div></MyReactSidebar>
在将你的 CRA 重构为 Astro 项目之前,了解 Astro 群岛 和 Astro 组件 可能会对你有所帮助。
比较:JSX 与 Astro
比较一下如下的 CRA 组件和相对应的 Astro 组件:
const Component = () => { const [stars, setStars] = useState(0); const [message, setMessage] = useState('');
useEffect(() => { const fetchData = async () => { const res = await fetch('https://api.github.com/repos/withastro/astro'); const json = await res.json(); setStars(json.stargazers_count || 0); setMessage(json.message); }; fetchData(); }, []); return ( <> <Header /> <p style={{ backgroundColor: `#f4f4f4`, padding: `1em 1.5em`, textAlign: `center`, marginBottom: `1em` }}>Astro has {stars} 🧑🚀</p> <Footer /> </> )};
export default Component; </Fragment> <Fragment slot="astro"> astro title="StarCount.astro" --- import Header from "./Header.astro"; import Footer from "./Footer.astro"; import "./layout.css"; const res = await fetch('https://api.github.com/repos/withastro/astro'); const json = await res.json(); const message = json.message; const stars = json.stargazers_count || 0; --- Astro has {stars} 🧑🚀 .banner { background-color: #f4f4f4; padding: 1em 1.5em; text-align: center; margin-bottom: 1em; } ```
将 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
在 Astro 中转换 CRA 导入语句
将任何 文件导入 准确地更新为相对引用的文件路径。可以通过使用 导入别名 或完整写出相对路径来实现。
注意,.astro 和其他一些文件类型必须使用它们的完整文件扩展名进行导入。
复制代码到剪贴板
---import Card from `../../components/Card.astro`;---<Card />
在 Astro 中转换 CRA 子组件属性
将任何 {children} 实例转换为 Astro 的 <slot />。Astro 不需要将 {children} 作为函数属性来传递,它会自动在 <slot /> 中渲染子组件内容。
复制代码到剪贴板
------export default function MyComponent(props) { return ( <div> {props.children} </div> ); }<div> <slot /></div>
传递多组子元素的 React 组件可以通过使用 命名插槽 转换为 Astro 组件。
了解更多有关于 特定 <slot /> 用法 的内容。
在 Astro 中转换 CRA 数据获取
在 Create React App 组件中获取数据与 Astro 类似,只有一些细微的差别。
你需要移除任何副作用钩子(useEffect)的实例,然后使用 import.meta.glob() 或 getCollection()(或 getEntry())从项目源代码的其他文件中获取数据。
要 获取远程数据,请使用 fetch()。
这些数据请求是在 Astro 组件的 frontmatter 中进行的,并使用顶层的 await。
复制代码到剪贴板
---import { getCollection } from 'astro:content';// 从 `src/content/blog/` 目录中获取所有条目const allBlogPosts = await getCollection('blog');// 从 `src/pages/posts/` 目录中获取所有条目const allPosts = Object.values(import.meta.glob('../pages/posts/*.md', { eager: true }));// 获取远程数据const response = await fetch('https://randomuser.me/api/');const data = await response.json();const randomUser = data.results[0];---
了解更多有关于 使用 import.meta.glob() 导入本地文件、 使用集合 API 查询 以及 获取远程数据 的内容。
在 Astro 中转换 CRA 样式
你可能需要用 Astro 中其他可用的 CSS 选项来替换任何 CSS-in-JS 库(例如 styled-components)。
如有必要,将任何行内样式对象(style={{ fontWeight: "bold" }})转换为行内的 HTML 样式属性(style="font-weight:bold;")。或者,使用 Astro 的 <style> 标签来实现作用域限定的 CSS 样式。
复制代码到剪贴板
<div style={{backgroundColor: `#f4f4f4`, padding: `1em`}}>{message}</div><div style="background-color: #f4f4f4; padding: 1em;">{message}</div>
如果已安装了 Tailwind Vite 插件,则可以支持 Tailwind,并且不需要更改现有的 Tailwind 代码!
了解更多有关于 Astro 中的样式 的内容。
故障排除
你的 CRA 可能可以在 Astro 中正常工作!但是,你可能需要进行微小调整,以复制现有应用程序的功能和(或)样式。
如果在文档中未找到答案,请访问 Astro 的 Discord,并在我们的支持论坛上提问!
社区资源
:::note[有想要分享的资源吗?] 如果你找到(或制作)了关于将 Create React App 转换为 Astro 的有用的视频或博客文章,请将其 添加到这个列表中! :::