- 起步
- 核心概念
- 教程
- 基础内容
- 内置功能
- 集成
- 操作指南
- 使用指南
- 配置
- 参考
- 社区资源
- 其他
- 为文档做出贡献
- 手动安装 Astro
- 升级到 Astro v4
- 升级到 Astro v3
- 升级到 Astro v2
- Legacy v0.x Upgrade Guide
- 从 Create React App(CRA)迁移
- 关于本教程
- 第一单元:前期准备
- 准备开发环境
- 创建你的第一个 Astro 项目
- 你的第一行 Astro 代码
- 创建在线代码仓库
- 将你的网站部署到网络
- 第二单元:页面
- 创建你的第一个 Astro 页面
- 编写你的第一篇 Markdown 博客文章
- 添加「关于你」的动态内容
- 给你的「关于」页面添加样式
- 应用全局样式
- 第三单元:组件
- 创建一个可重复使用的导航组件
- 创建社交媒体 footer
- 自己动手搭建导航 Header
- 编写你的第一个浏览器脚本
- 第四单元:布局
- 编写你的第一个布局
- 创建并传递数据到博客布局
- 布局结合,两全其美
- 第五单元 - Astro API
- 创建文章存档页
- 生成标签页面
- 编写标签索引页面
- 添加 RSS 订阅源
- 第六单元 - Astro 群岛
- 搭建你的第一个 Astro 岛屿
- 回到干燥的陆地。让你的博客从白天到黑夜,无需岛屿!
- 恭喜你!
- @astrojs/mdx
- 添加阅读时间
- 创建开发者工具栏应用
- @astrojs/alpinejs
- @astrojs/lit
- @astrojs/preact
- @astrojs/react
- @astrojs/solid-js
- @astrojs/svelte
- @astrojs/vue
- @astrojs/cloudflare
- @astrojs/netlify
- @astrojs/node
- @astrojs/vercel
- @astrojs/db
- @astrojs/markdoc
- @astrojs/partytown
- @astrojs/sitemap
- @astrojs/tailwind
- 使用流式处理来提升页面性能
- 从 Gatsby 迁移
- 从 Next.js 迁移
- 从 NuxtJS 迁移
- 从 Docusaurus 迁移到 Astro
- 从 Eleventy 迁移到 Astro
- 从 GitBook 迁移到 Astro
- 从Gridsome迁移到Astro
- 从 Hugo 迁移
- 从 Jekyll 迁移
- 从 Pelican 迁移
- 从 SvelteKit 迁移
- 从VuePress迁移
- 从 WordPress 迁移
- 状态共享
- Storyblok 与 Astro
- Contentful 与 Astro
- ButterCMS & Astro
- Builder.io & Astro
- Cosmic 与 Astro
- DatoCMS 与 Astro
- Front Matter CMS 与 Astro
- Ghost & Astro
- Hashnode & Astro
- Hygraph 与 Astro
- Keystatic & Astro
- Kontent.ai 与 Astro
- 无头模式的 Statamic 与 Astro
- Strapi 与 Astro
- Tina CMS 与 Astro
- Umbraco & Astro
- 无头(headless)模式的 WordPress 与 Astro
- ApostropheCMS 与 Astro
- Caisy & Astro
- CloudCannon与Astro
- Crystallize 与 Astro
- Decap CMS 与 Astro
- Directus 与 Astro
- KeystoneJS 与 Astro
- microCMS & Astro
- Payload CMS 与 Astro
- Prepr CMS & Astro
- Prismic & Astro
- Sanity & Astro
- Sitecore 体验管理器 & Astro
- Spinal & Astro
- 创作内容
- Firebase 与 Astro
- Supabase 与 Astro
- Turso 和 Astro
- Xata 与 Astro
- Appwrite & Astro
- 部署你的 Astro 站点至 Netlify
- 部署你的 Astro 站点至 Vercel
- 如何将你的 Astro 网站部署到 Deno
- 部署你的 Astro 站点至 GitHub Pages
- 部署你的 Astro 站点至 GitLab Pages
- 部署你的 Astro 站点至 Cloudflare Pages
- 将你的 Astro 网站部署到 AWS
- 将你的 Astro 网站通过 Flightcontrol 部署到 AWS
- 将你的 Astro 网站通过 SST 部署到 AWS
- 将你的 Astro 网站部署至 Google Cloud
- 部署你的 Astro 站点至 Google Firebase 托管
- 将你的 Astro 网站部署到 Heroku
- 将你的 Astro 网站部署到 Microsoft Azure
- 部署你的 Astro 站点至 Buddy
- 将你的 Astro 网站部署到 Edgio
- 将你的 Astro 站点部署到 Fly.io
- 将你的 Astro 网站部署到 Render
- 将你的 Astro 网站部署到 Stormkit
- 将你的 Astro 网站部署到 Surge
- 通过 Cleavr 部署你的 Astro 网站
- 将你的 Astro 站点部署到 Kinsta 应用托管
- 将你的 Astro 网站部署到 Space
- 将你的 Astro 站点部署到 Zeabur
- 将你的 Astro 网站部署到 Zerops
- 添加 RSS 摘要
- 安装一个 Vite 或 Rollup 插件
- 构建自定义图像组件
- 使用 API 路由构建表单
- 在 Astro 页面中构建 HTML 表单
- 在 Astro 中使用 Bun
- 调用服务器端点
- 校验验证码
- 用 Docker 来构建你的 Astro 网站
- 动态导入图片
- 为链接添加图标
- 添加 i18n 功能
- 添加最后修改时间
- 在 Astro 组件中共享状态
- 使用 Tailwind Typography 美化渲染后的 Markdown
- Unknown compiler error.
- Astro.redirect is not available in static mode.
- Astro.clientAddress is not available in current adapter.
- Astro.clientAddress cannot be used inside prerendered routes.
- Astro.clientAddress is not available in static mode.
- No static path found for requested path.
- Invalid type returned by Astro page.
- Missing value for client:media directive.
- No matching renderer found.
- No client entrypoint specified in renderer.
- Missing hint on client:only directive.
- Invalid value returned by a getStaticPaths path.
- Invalid entry inside getStaticPath's return value
- Invalid value returned by getStaticPaths.
- getStaticPaths RSS helper is not available anymore.
- Missing params property on getStaticPaths route.
- Invalid value for getStaticPaths route parameter.
- getStaticPaths() function required for dynamic routes.
- Invalid slot name.
- Cannot use Server-side Rendering without an adapter.
- No import found for component.
- Invalid prerender export.
- Invalid component arguments.
- Page number param not found.
- Image missing required "alt" property.
- Error while loading image service.
- Missing image dimensions
- Failed to retrieve remote image dimensions
- Unsupported image format
- Unsupported image conversion
- Prerendered dynamic endpoint has path collision.
- Expected src to be an image.
- Expected image options.
- Cannot set both densities and widths
- Image not found.
- Could not process image metadata.
- Image not found.
- Could not transform image.
- Unable to set response.
- The middleware didn't return a Response.
- The middleware returned something that is not a Response object.
- The endpoint did not return a Response.
- Value assigned to locals is not accepted.
- Astro.response.headers must not be reassigned.
- Can't load the middleware.
- Local images must be imported.
- Astro.glob() used outside of an Astro file.
- Astro.glob() did not match any files.
- A redirect must be given a location with the Location header.
- Invalid dynamic route.
- Could not find Sharp.
- Unknown Vite Error.
- Could not import file.
- Invalid glob pattern.
- Astro couldn't find the correct page to render
- The provided locale does not exist.
- Index page not found.
- You can't use the current function with the current strategy
- Prerendered routes aren't supported when internationalization domains are enabled.
- 启用了手动国际化路由但没有提供中间件。
- Astro can't render the route.
- Unhandled rejection
- i18n Not Enabled
- Route not found.
- Unknown CSS Error
- CSS Syntax Error
- Unknown Markdown Error.
- Failed to parse Markdown frontmatter.
- Invalid frontmatter injection.
- MDX integration missing.
- Unknown configuration error.
- Specified configuration file not found.
- Legacy configuration detected.
- Unknown CLI Error.
- Failed to generate content types.
- Unknown Content Collection Error.
- Content entry frontmatter does not match schema.
- Invalid content entry slug.
- Content Schema should not contain slug.
- Collection does not exist
- Content and data cannot be in same collection.
- Collection contains entries of a different type.
- Data collection entry failed to parse.
- Duplicate content entry slug.
- Actions must be used with server output.
- Unsupported transform in content config.
从 Create React App(CRA)迁移
Astro 的 React 集成 支持在 Astro 组件中使用 React 组件,甚至包括像 Create React App (CRA) 这样的整个 React 应用程序!
src/pages/index.astro---
// 导入你的根应用组件
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 项目。
- npm
- pnpm
- Yarn
npm create astro@latest
pnpm create astro@latest
yarn create astro@latest
添加集成和依赖
通过你的包管理器来运行 astro add
命令以添加 React 集成。如果你的应用程序使用了 Tailwind 或 MDX,你可以使用相同的命令添加多个 Astro 集成:
- npm
- pnpm
- Yarn
npx astro add react
npx astro add react tailwind mdx
pnpm astro add react
pnpm astro add react tailwind mdx
yarn astro add react
yarn astro add react 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/
文件夹中。
文件夹public/
- logo.png
- favicon.ico
- …
文件夹src/
文件夹cra-project/
- App.jsx
- …
文件夹pages/
- index.astro
- astro.config.mjs
- package.json
- tsconfig.json
渲染你的应用
在 index.astro
的 frontmatter 部分导入你的应用程序的根组件,然后在页面模板中渲染 <App />
组件:
---
import App from '../cra-project/App.jsx';
---
<App client:load />
有关详细信息和可用选项,请参阅我们的 配置 Astro 指南。
将 CRA 转换为 Astro
除了 将现有应用程序添加到 Astro,你可能也希望将应用程序本身直接转换为 Astro!
你可以在现有结构的基础上 使用 Astro 的 HTML 模板组件 以重构类似的基于组件的设计,同时导入和包含个别的 React 组件(它们本身可能是完整的应用程序!)来实现群岛交互。
每个迁移的过程都会有所不同,你可以逐步进行迁移,而不会影响你正在工作的应用程序。按照自己的节奏逐渐转换每个部分,从而使应用程序中越来越多的部分由 Astro 组件驱动。
当你转换你的 React 应用程序时,你需要决定哪些 React 组件你将会 重写为 Astro 组件。唯一的限制是 Astro 组件可以导入 React 组件,但 React 组件只能导入其他 React 组件:
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 组件。
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 组件 可能会对你有所帮助。
比较:JSX 与 Astro
比较一下如下的 CRA 组件和相对应的 Astro 组件:
- JSX
- Astro
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;
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;
---
<Header />
<p class="banner">Astro has {stars}</p>
<Footer />
<style>
.banner {
background-color: #f4f4f4;
padding: 1em 1.5em;
text-align: center;
margin-bottom: 1em;
}
<style>
将 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()
替换为导入语句或Astro.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
)的实例,然后使用 Astro.glob()
或 getCollection()
(或 getEntryBySlug()
)从项目源代码的其他文件中获取数据。
要 获取远程数据,请使用 fetch()
。
这些数据请求是在 Astro 组件的 frontmatter 中进行的,并使用顶层的 await。
src/pages/index.astro---
import { getCollection } from 'astro:content';
// 从 `src/content/blog/` 目录中获取所有条目
const allBlogPosts = await getCollection('blog');
// 从 `src/pages/posts/` 目录中获取所有条目
const allPosts = await Astro.glob('../pages/posts/*.md');
// 获取远程数据
const response = await fetch('https://randomuser.me/api/');
const data = await response.json();
const randomUser = data.results[0];
---
了解更多有关于 使用 Astro.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 集成,则可以支持 Tailwind,并且不需要更改现有的 Tailwind 代码!
了解更多有关于 Astro 中的样式 的内容。
故障排除
你的 CRA 可能可以在 Astro 中正常工作!但是,你可能需要进行微小调整,以复制现有应用程序的功能和(或)样式。
如果在文档中未找到答案,请访问 Astro 的 Discord,并在我们的支持论坛上提问!
更多迁移指南
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论