Skip to content

从 Create React App (CRA) 迁移

Astro 的 反应集成 提供对 在 Astro 组件中使用 React 组件 的支持,包括整个 React 应用,例如 Create React App (CRA)!

¥Astro’s React integration provides support for using React components inside Astro components, including entire React apps like Create React App (CRA)!

src/pages/index.astro
---
// Import your root App component
import App from '../cra-project/App.jsx';
---
<!-- Use a client directive to load your app -->
<App client:load />
See how to Build a Single Page Application (SPA) with Astro External using React Router.

当你将许多应用直接添加到安装了 React 集成的 Astro 项目时,许多应用将 “只是工作” 作为完整的 React 应用。这是让你的项目立即启动并运行并在迁移到 Astro 时保持应用正常运行的好方法。

¥Many apps will “just work” as full React apps when you add them directly to your Astro project with the React integration installed. This is a great way to get your project up and running immediately and keep your app functional while you migrate to Astro.

随着时间的推移,你可以将结构逐个转换为 .astro.jsx 组件的组合。你可能会发现你需要的 React 组件比你想象的要少!

¥Over time, you can convert your structure piece-by-piece to a combination of .astro and .jsx components. You will probably discover you need fewer React components than you think!

以下是一些可帮助你入门的关键概念和迁移策略。使用我们的其余文档和 Discord 社区 继续前进!

¥Here are some key concepts and migration strategies to help you get started. Use the rest of our docs and our Discord community to keep going!

CRA 和 Astro 之间的主要相似之处

Section titled CRA 和 Astro 之间的主要相似之处

¥Key Similarities between CRA and Astro

CRA 和 Astro 之间的主要区别

Section titled CRA 和 Astro 之间的主要区别

¥Key Differences between CRA and Astro

当你在 Astro 中重建 CRA 站点时,你会注意到一些重要的差异:

¥When you rebuild your CRA site in Astro, you will notice some important differences:

  • CRA 是一个单页应用,使用 index.js 作为项目的根目录。Astro 是一个多页面网站,index.astro 是你的主页。

  • .astro 组件 未编写为返回页面模板的导出函数。相反,你将把代码拆分为 JavaScript 的 “代码围栏” 和专门用于你生成的 HTML 的正文。

  • content-driven:Astro 旨在展示你的内容并允许你仅根据需要选择加入交互。现有的 CRA 应用可能是为高客户端交互性而构建的,并且可能需要高级的 Astro 技术来包含使用 .astro 组件复制更具挑战性的项目,例如仪表板。

¥Add your CRA to Astro

你现有的应用可以直接在新的 Astro 项目中渲染,通常无需更改应用的代码。

¥Your existing app can be rendered directly inside a new Astro project, often with no changes to your app’s code.

创建一个新的 Astro 项目

Section titled 创建一个新的 Astro 项目

¥Create a new Astro project

使用包管理器的 create astro 命令启动 Astro 的 CLI 向导并选择新的 “empty” Astro 项目。

¥Use the create astro command for your package manager to launch Astro’s CLI wizard and select a new “empty” Astro project.

Terminal window
npm create astro@latest

¥Add integrations and dependencies

使用包管理器的 astro add 命令添加 React 集成。如果你的应用使用 Tailwind 或 MDX,你可以使用相同的命令添加多个 Astro 集成:

¥Add the React integration using the astro add command for your package manager. If your app uses Tailwind or MDX, you can add multiple Astro integrations using the same command:

Terminal window
npx astro add react
npx astro add react tailwind mdx

如果你的 CRA 需要任何依赖(例如 NPM 软件包),请使用命令行单独安装它们,或者手动将它们添加到新 Astro 项目的 package.json,然后运行安装命令。请注意,许多(但不是全部)React 依赖都可以在 Astro 中运行。

¥If your CRA requires any dependencies (e.g. NPM packages), then install them individually using the command line or by adding them to your new Astro project’s package.json manually and then running an install command. Note that many, but not all, React dependencies will work in Astro.

添加你现有的应用文件

Section titled 添加你现有的应用文件

¥Add your existing app files

将现有的 Create React App (CRA) 项目源文件和文件夹(例如 componentshooksstyles 等)复制到 src/ 内的新文件夹中,保留其文件结构,以便你的应用将继续工作。请注意,所有 .js 文件扩展名必须重命名为 .jsx.tsx

¥Copy your existing Create React App (CRA) project source files and folders (e.g. components, hooks, styles, etc.) into a new folder inside src/, keeping its file structure so your app will continue to work. Note that all .js file extensions must be renamed to .jsx or .tsx.

不要包含任何配置文件。你将使用 Astro 自己的 astro.config.mjspackage.jsontsconfig.json

¥Do not include any configuration files. You will use Astro’s own astro.config.mjs, package.json, and tsconfig.json.

将应用的 public/ 文件夹的内容(例如静态资源)移动到 Astro 的 public/ 文件夹中。

¥Move the contents of your app’s public/ folder (e.g. static assets) into Astro’s public/ folder.

  • Directorypublic/
    • logo.png
    • favicon.ico
  • Directorysrc/
    • Directorycra-project/
      • App.jsx
    • Directorypages/
      • index.astro
  • astro.config.mjs
  • package.json
  • tsconfig.json

¥Render your app

index.astro 的 frontmatter 部分导入应用的根组件,然后在页面模板中渲染 <App /> 组件:

¥Import your app’s root component in the frontmatter section of index.astro, then render the <App /> component in your page template:

src/pages/index.astro
---
import App from '../cra-project/App.jsx';
---
<App client:load />

有关更多详细信息和可用选项,请参阅我们的 配置 Astro 指南。

¥See our guide for configuring Astro for more details and available options.

¥Convert your CRA to Astro

将你现有的应用添加到 Astro 之后,你可能希望将你的应用本身转换为 Astro!

¥After adding your existing app to Astro, you will probably want to convert your app itself to Astro!

你将复制类似的基于组件的设计 使用 Astro HTML 模板组件作为你的基本结构,同时导入并包含单个 React 组件(它们本身可能是整个应用!)以实现交互岛。

¥You will replicate a similar component-based design using Astro HTML templating components for your basic structure while importing and including individual React components (which may themselves be entire apps!) for islands of interactivity.

每次迁移看起来都会有所不同,并且可以增量完成,而不会中断你的工作应用。按照你自己的节奏转换各个部分,以便随着时间的推移,越来越多的应用由 Astro 组件提供支持。

¥Every migration will look different and can be done incrementally without disrupting your working app. Convert individual pieces at your own pace so that more and more of your app is powered by Astro components over time.

当你转换 React 应用时,你将决定要使用哪些 React 组件。唯一的限制是 Astro 组件可以导入 React 组件,但 React 组件只能导入其他 React 组件:

¥As you convert your React app, you will decide which React components you will rewrite as Astro components. Your only restriction is that Astro components can import React components, but React components must only import other React components:

src/pages/static-components.astro
---
import MyReactComponent from '../components/MyReactComponent.jsx';
---
<html>
<body>
<h1>Use React components directly in Astro!</h1>
<MyReactComponent />
</body>
</html>

你可以将 React 组件嵌套在单个 Astro 组件中,而不是将 Astro 组件导入到 React 组件中:

¥Instead of importing Astro components into React components, you can nest React components inside a single Astro component:

src/pages/nested-components.astro
---
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 组件 很有帮助。

¥You may find it helpful to learn about Astro islands and Astro components before restructuring your CRA as an Astro project.

¥Compare: JSX vs Astro

比较以下 CRA 组件和相应的 Astro 组件:

¥Compare the following CRA component and a corresponding Astro component:

StarCount.jsx
import React, { useState, useEffect } from 'react';
import Header from './Header';
import Footer from './Footer';
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;

将 JSX 文件转换为 .astro 文件

Section titled 将 JSX 文件转换为 .astro 文件

¥Converting JSX files to .astro files

以下是将 CRA .js 组件转换为 .astro 组件的一些提示:

¥Here are some tips for converting a CRA .js component into a .astro component:

  1. 使用现有 CRA 组件函数返回的 JSX 作为 HTML 模板的基础。

  2. 更改任何 Astro 的 CRA 或 JSX 语法 或 HTML Web 标准。例如,这包括 {children}className

  3. 将任何必要的 JavaScript(包括 import 语句)移至 “代码围栏” (---).js 文件中。注意:JavaScript 到 有条件地渲染内容 通常直接在 Astro 中编写在 HTML 模板内。

  4. 使用 Astro.props 访问之前传递给 CRA 函数的任何其他 props。

  5. 确定是否有任何导入组件也需要转换为 Astro。你可以暂时或永远将它们保留为 React 组件。但是,你最终可能希望将它们转换为 .astro 组件,尤其是当它们不需要交互时!

  6. useEffect() 替换为导入语句或 Astro.glob() 以查询本地文件。使用 fetch() 获取外部数据。

¥Migrating Tests

由于 Astro 输出原始 HTML,因此可以使用构建步骤的输出编写端到端测试。如果你能够匹配 CRA 站点的标记,之前编写的任何端到端测试都可以开箱即用。可以在 Astro 中导入和使用 Jest 和 React 测试库等测试库来测试你的 React 组件。

¥As Astro outputs raw HTML, it is possible to write end-to-end tests using the output of the build step. Any end-to-end tests written previously might work out-of-the-box if you have been able to match the markup of your CRA site. Testing libraries such as Jest and React Testing Library can be imported and used in Astro to test your React components.

有关更多信息,请参阅 Astro 的 测试指南

¥See Astro’s testing guide for more.

参考:将 CRA 语法转换为 Astro

Section titled 参考:将 CRA 语法转换为 Astro

¥Reference: Convert CRA Syntax to Astro

¥CRA Imports to Astro

更新任何 file imports 以准确引用相对文件路径。这可以使用 import aliases 或通过完整写出相对路径来完成。

¥Update any file imports to reference relative file paths exactly. This can be done using import aliases, or by writing out a relative path in full.

请注意,.astro 和其他几种文件类型必须以其完整文件扩展名导入。

¥Note that .astro and several other file types must be imported with their full file extension.

src/pages/authors/Fred.astro
---
import Card from '../../components/Card.astro';
---
<Card />

CRA 子级向 Astro 提供属性

Section titled CRA 子级向 Astro 提供属性

¥CRA Children Props to Astro

{children} 的任何实例转换为 Astro <slot />。Astro 不需要接收 {children} 作为函数 prop,并且会自动渲染 <slot /> 中的子内容。

¥Convert any instances of {children} to an Astro <slot />. Astro does not need to receive {children} as a function prop and will automatically render child content in a <slot />.

src/components/MyComponent.astro
---
---
export default function MyComponent(props) {
return (
<div>
{props.children}
</div>
);
}
<div>
<slot />
</div>

传递多组子级的 React 组件可以使用 命名槽 迁移到 Astro 组件。

¥React components that pass multiple sets of children can be migrated to an Astro component using named slots.

查看更多有关 Astro 中 <slot /> 的具体用法 的信息。

¥See more about specific <slot /> usage in Astro.

¥CRA Data Fetching to Astro

在 Create React App 组件中获取数据与 Astro 类似,但有一些细微的差别。

¥Fetching data in a Create React App component is similar to Astro, with some slight differences.

你需要删除 Astro.glob()getCollection()/getEntryBySlug() 的副作用钩子 (useEffect) 的任何实例,才能访问项目源中其他文件的数据。

¥You will need to remove any instances of a side effect hook (useEffect) for either Astro.glob() or getCollection()/getEntryBySlug() to access data from other files in your project source.

对于 获取远程数据,请使用 fetch()

¥To fetch remote data, use fetch().

这些数据请求是在 Astro 组件的 frontmatter 中发出的,并使用顶层等待。

¥These data requests are made in the frontmatter of the Astro component and use top-level await.

src/pages/index.astro
---
import { getCollection } from 'astro:content';
// Get all `src/content/blog/` entries
const allBlogPosts = await getCollection('blog');
// Get all `src/pages/posts/` entries
const allPosts = await Astro.glob('../pages/posts/*.md');
// Fetch remote data
const response = await fetch('https://randomuser.me/api/');
const data = await response.json();
const randomUser = data.results[0];
---

查看有关 local files imports with Astro.glob()使用 Collections API 进行查询获取远程数据 的更多信息。

¥See more about local files imports with Astro.glob(), querying using the Collections API or fetching remote data.

¥CRA Styling to Astro

你可能需要将任何 CSS-in-JS 库(例如样式组件)替换为 Astro 中其他可用的 CSS 选项。

¥You may need to replace any CSS-in-JS libraries (e.g. styled-components) with other available CSS options in Astro.

如有必要,将任何内联样式对象 (style={{ fontWeight: "bold" }}) 转换为内联 HTML 样式属性 (style="font-weight:bold;")。或者,使用 Astro <style> 标签 作为作用域 CSS 样式。

¥If necessary, convert any inline style objects (style={{ fontWeight: "bold" }}) to inline HTML style attributes (style="font-weight:bold;"). Or, use an Astro <style> tag for scoped CSS styles.

src/components/Card.astro
<div style={{backgroundColor: `#f4f4f4`, padding: `1em`}}>{message}</div>
<div style="background-color: #f4f4f4; padding: 1em;">{message}</div>

安装 Tailwind 整合 后支持 Tailwind。无需更改你现有的 Tailwind 代码!

¥Tailwind is supported after installing the Tailwind integration. No changes to your existing Tailwind code are required!

查看更多有关 Astro 样式 的信息。

¥See more about Styling in Astro.

¥Troubleshooting

你的 CRA 在 Astro 中可能为 “只是工作”!但是,你可能需要进行细微调整以复制现有应用的功能和/或样式。

¥Your CRA might “just work” in Astro! But, you may likely need to make minor adjustments to duplicate your existing app’s functionality and/or styles.

如果你在这些文档中找不到答案,请访问 Astro Discord 并在我们的支持论坛中提问!

¥If you cannot find your answers within these docs, please visit the Astro Discord and ask questions in our support forum!

More migration guides

Astro 中文网 - 粤ICP备13048890号