跳转到内容

升级到 Astro v5

本指南将帮助你从 Astro v4 迁移到 Astro v5。

需要先将旧项目升级到 v4?请参阅我们的旧版迁移指南

需要查看 v4 文档?请访问旧版文档网站(未维护的 v4.16 快照)

使用你的包管理器将项目的 Astro 版本更新到最新版本

终端窗口
# Upgrade Astro and official integrations together
npx @astrojs/upgrade

如果需要,你还可以手动升级你的 Astro 集成,并且你可能还需要升级项目中的其他依赖项。

Astro v5.0 包含潜在的破坏性变更,以及一些功能的移除和弃用。

如果你的项目在升级到 v5.0 后无法按预期工作,请查看本指南,以获取所有破坏性变更的概述以及如何更新代码库的说明。

有关完整的发布说明,请参阅 Astro 更新日志

Astro 依赖项的任何主要升级都可能导致你的项目出现破坏性变更。

Astro v5.0 升级到 Vite v6.0 作为开发服务器和生产打包器。

如果你正在使用 Vite 特定的插件、配置或 API,请查看 Vite 迁移指南 以了解其破坏性变更,并根据需要升级你的项目。

在 Astro v4.x 中,Astro 为 @astrojs/mdx 集成执行内部 JSX 处理。

Astro v5.0 将处理和渲染 JSX 和 MDX 的责任直接移交给了 @astrojs/mdx 包。这意味着 Astro 5.0 不再与旧版本的 MDX 集成兼容。

如果你的项目包含 .mdx 文件,你必须将 @astrojs/mdx 升级到最新版本 (v4.0.0),以便你的 JSX 可以被集成正确处理。

如果你正在使用带有实验性 Astro 容器 API 的 MDX 服务器渲染器,你必须更新导入以反映新的位置

import mdxRenderer from "astro/jsx/server.js";
import mdxRenderer from "@astrojs/mdx/server.js";
了解更多关于在你的项目中使用 MDX 的信息。

以下功能现在被视为遗留功能。它们应该可以正常工作,但不再推荐使用,并处于维护模式。它们将不会有未来的改进,文档也不会更新。这些功能最终将被弃用,然后完全移除。

在 Astro 4.x 中,内容集合是使用在 Astro v2.0 中首次引入的内容集合 API 来定义、查询和渲染的。所有集合条目都是保留的 src/content/ 文件夹中的本地文件。此外,Astro 的排除构建单个页面的文件名约定也内置于内容集合 API 中。

Astro 5.0 引入了使用内容层 API 的新版本内容集合,带来了多项性能改进和新增功能。虽然旧的(遗留的)和新的(内容层 API)集合可以在此版本中并存,但对现有的遗留集合存在潜在的破坏性变更。

此版本还移除了使用下划线(_)作为集合条目文件名前缀以防止构建路由的选项。

我们建议你尽快将任何现有集合转换为新的内容层 API,并使用内容层 API 创建任何新的集合。

如果你无法转换你的集合,请查阅遗留集合的破坏性变更,以查看你现有的集合是否受到影响并需要更新。

如果你目前无法对集合进行任何更改,你可以启用 legacy.collections 标志,这将允许你在遗留标志不再被支持之前保持集合的当前状态。

了解更多关于更新后的内容集合的信息。

请参阅以下说明,将现有的内容集合(type: 'content'type: 'data')更新为使用内容层 API。

更新集合的分步说明
  1. 移动内容配置文件。此文件不再位于 src/content/ 文件夹内。此文件现在应该存在于 src/content.config.ts

  2. 编辑集合定义。你更新后的集合需要一个 loader,它同时指示你的集合位置的文件夹(base)和一个定义要匹配的集合条目文件名和扩展名的 pattern。(你可能需要相应地更新下面的示例。你可以使用 globster.xyz 来检查你的 glob 模式。)选择集合 type 的选项已不再可用。

    src/content.config.ts
    import { defineCollection, z } from 'astro:content';
    import { glob } from 'astro/loaders';
    const blog = defineCollection({
    // For content layer you no longer define a `type`
    type: 'content',
    loader: glob({ pattern: '**/[^_]*.{md,mdx}', base: "./src/data/blog" }),
    schema: z.object({
    title: z.string(),
    description: z.string(),
    pubDate: z.coerce.date(),
    updatedDate: z.coerce.date().optional(),
    }),
    });
  3. 将引用从 slug 更改为 id。内容层集合没有保留的 slug 字段。相反,所有更新的集合都将有一个 id

    src/pages/[slug].astro
    ---
    export async function getStaticPaths() {
    const posts = await getCollection('blog');
    return posts.map((post) => ({
    params: { slug: post.slug },
    params: { slug: post.id },
    props: post,
    }));
    }
    ---

    你还可以更新动态路由文件名,以匹配已更改的 getStaticPaths() 参数的值。

  4. 切换到新的 render() 函数。条目不再有 render() 方法,因为它们现在是可序列化的普通对象。相反,从 astro:content 导入 render() 函数。

    src/pages/index.astro
    ---
    import { getEntry, render } from 'astro:content';
    const post = await getEntry('blog', params.slug);
    const { Content, headings } = await post.render();
    const { Content, headings } = await render(post);
    ---
    <Content />
对遗留 contentdata 集合的破坏性变更
标题为“对遗留 content 和 data 集合的破坏性变更”的部分

默认情况下,使用旧 type 属性(contentdata)且未定义 loader 的集合,现在在底层使用内容层 API 的内置 glob() 加载器实现,并带有额外的向后兼容性处理。

此外,存在临时的向后兼容性,以将内容配置文件保留在其原始位置 src/content/config.ts

这种向后兼容性实现能够模拟遗留集合的大部分功能,并允许许多遗留集合在不更新代码的情况下继续工作。然而,存在一些差异和限制,可能会对现有集合造成破坏性变更

  • 在 Astro 的先前版本中,即使没有在 src/content/config.ts 中定义,也会为 src/content/ 中的所有文件夹生成集合。此行为现已弃用,集合应始终在 src/content.config.ts 中定义。对于现有集合,这些可以是空的声明(例如 const blog = defineCollection({})),Astro 将以与新加载行为兼容的方式为你隐式定义遗留集合。
  • Markdown 集合条目不支持特殊的 layout 字段。此属性仅适用于位于 src/pages/ 中的独立页面文件,不太可能出现在你的集合条目中。但是,如果你正在使用此属性,现在必须创建包含页面样式的动态路由。
  • 生成集合的排序顺序是不确定的,并且依赖于平台。这意味着如果你调用 getCollection(),返回条目的顺序可能与以前不同。如果你需要特定的顺序,你必须自己对集合条目进行排序。
  • 不支持 image().refine()。如果你需要验证图像的属性,你需要在页面或组件的运行时执行此操作。
  • getEntry(collection, key)key 参数被类型化为 string,而不是为每个条目都有类型。
  • 以前,当使用静态字符串作为键调用 getEntry(collection, key) 时,返回类型是不可空的。现在该类型包括 undefined,因此在使用结果之前,你必须检查条目是否已定义,否则将出现类型错误。

如果你尚未准备好更新现有集合,可以启用 legacy.collections 标志,你现有的集合将继续像以前一样工作。

以下已弃用的功能不再受支持,也不再记录在文档中。请相应地更新你的项目。

一些已弃用的功能可能会在完全移除之前暂时继续工作。其他功能可能会悄无声息地不起作用,或者抛出一个错误,提示你更新代码。

在 Astro v4.x 中,你可以在 .astro 组件中使用 Astro.glob() 来查询项目中的多个文件。这有一些限制(例如使用位置、性能等),而使用内容集合 API 的查询函数或 Vite 自己的 import.meta.glob() 通常提供更多的功能和灵活性。

Astro 5.0 弃用了 Astro.glob(),推荐使用 getCollection() 查询你的集合,以及使用 import.meta.glob() 查询项目中的其他源文件。

将所有 Astro.glob() 的使用替换为 import.meta.glob()。请注意,import.meta.glob() 不再返回 Promise,因此你可能需要相应地更新代码。你的 glob 模式应该不需要任何更新。

src/pages/blog.astro
---
const posts = await Astro.glob('./posts/*.md');
const posts = Object.values(import.meta.glob('./posts/*.md', { eager: true }));
---
{posts.map((post) => <li><a href={post.url}>{post.frontmatter.title}</a></li>)}

在适当的情况下,考虑使用内容集合来组织你的内容,它有自己更新、性能更好的查询函数。

你可能还希望考虑使用来自 NPM 的 glob 包,例如 fast-glob

了解更多关于使用 import.meta.glob 导入文件的信息。

在 Astro v4.x 中,你可以选择为项目中定义的每个路由创建一个单独的文件,在构建文件夹中镜像你的 src/pages/ 目录。默认情况下,Astro 会生成一个 entry.mjs 文件,该文件负责在每个请求上输出渲染的页面。

Astro v5.0 移除了选择退出默认行为的选项。此行为现在是标准的,且不可配置。

从你的 adapterFeatures 配置中移除 functionPerRoute 属性。它已不再可用。

my-adapter.mjs
export default function createIntegration() {
return {
name: '@matthewp/my-adapter',
hooks: {
'astro:config:done': ({ setAdapter }) => {
setAdapter({
name: '@matthewp/my-adapter',
serverEntrypoint: '@matthewp/my-adapter/server.js',
adapterFeatures: {
functionPerRoute: true
}
});
},
},
};
}
了解更多关于用于构建适配器集成的适配器 API 的信息。

已弃用:astro:build:done 钩子中的 routes (集成 API)

标题为“已弃用:astro:build:done 钩子中的 routes (集成 API)”的部分

在 Astro v4.x 中,集成从 astro:build:done 钩子访问路由。

Astro v5.0 弃用了传递给此钩子的 routes 数组。取而代之的是,它公开了一个新的 astro:routes:resolved 钩子,该钩子在 astro:config:done 之前运行,并且在开发中每当路由发生变化时都会运行。它具有已弃用的 routes 列表的所有相同属性,除了 distURL,它只在构建期间可用。

移除传递给 astro:build:done 的任何 routes 实例,并将其替换为新的 astro:routes:resolved 钩子。在新公开的 assets map 上访问 distURL

my-integration.mjs
const integration = () => {
let routes
return {
name: 'my-integration',
hooks: {
'astro:routes:resolved': (params) => {
routes = params.routes
},
'astro:build:done': ({
routes
assets
}) => {
for (const route of routes) {
const distURL = assets.get(route.pattern)
if (distURL) {
Object.assign(route, { distURL })
}
}
console.log(routes)
}
}
}
}

以下功能现已从代码库中完全移除,不能再使用。其中一些功能可能在弃用后仍在你的项目中继续工作。其他功能可能已经悄无声息地不起作用。

现在包含这些已移除功能的项目将无法构建,并且将不再有任何支持文档提示你移除这些功能。

在 Astro v4.x 中,Lit 是通过 @astrojs/lit 包由核心维护的框架库。

Astro v5.0 移除了该集成,它将不会收到与 5.x及以上版本的兼容性更新。

你可以通过添加客户端脚本标签继续使用 Lit 作为客户端组件。例如

<script>
import "../components/MyTabs";
</script>
<my-tabs title="These are my tabs">...</my-tabs>

如果你有兴趣自己维护 Lit 集成,你可能希望使用@astrojs/lit 的最后一个发布版本作为起点,并升级相关包。

了解更多关于 Astro 的官方集成

在 Astro v4.x 中,Astro 提供了三种 output 渲染模式:'static''hybrid''server'

Astro v5.0 将 output: 'hybrid'output: 'static' 配置合并为一个单一的配置(现在称为 'static'),其工作方式与之前的混合选项相同。

在 Astro 配置中不再需要指定 output: 'hybrid' 来使用服务器渲染的页面。新的 output: 'static' 已包含此功能。

Astro 现在将自动允许你在静态站点中选择退出预渲染,而无需更改输出配置。任何页面路由或端点都可以包含 export const prerender = false 以按需进行服务器渲染,而你网站的其余部分则静态生成。

如果你的项目使用混合渲染,你现在必须从 Astro 配置中移除 output: 'hybrid' 选项,因为它不再存在。但是,你的项目不需要其他更改,并且应该没有破坏性变更。以前的 'hybrid' 行为现在是默认行为,新名称为 'static'

astro.config.mjs
import { defineConfig } from "astro/config";
export default defineConfig({
output: 'hybrid',
});

如果你之前使用 output: 'static'(默认)选项,你可以像以前一样继续使用它。默认情况下,你所有的页面都将继续被预渲染,你将拥有一个完全静态的网站。你的项目应该没有破坏性变更。

无论你的项目使用哪种 output 模式,部署带有任何服务器渲染页面的 Astro 项目仍然需要一个适配器。不包含适配器将在开发中导致警告,在构建时导致错误。

了解更多关于 Astro 中的按需渲染

已移除:对路由中动态 prerender 值的支持

标题为“已移除:对路由中动态 prerender 值的支持”的部分

在 Astro 4.x 中,环境变量可用于动态设置路由中 prerender 导出的值,例如 export const prerender = import.meta.env.SOME_VAR

Astro v5.0 移除了对 prerender 导出中动态值的支持。仅支持静态值 truefalse

  1. 移除你路由中的任何动态 prerender 导出

    src/pages/blog/[slug].astro
    ---
    export const prerender = import.meta.env.SOME_VAR;
    ---
  2. 在你的 astro.config.mjs 文件中使用 Astro 集成,在 "astro:route:setup" 钩子中设置需要动态的 prerender

    astro.config.mjs
    import { defineConfig } from 'astro/config';
    import { loadEnv } from 'vite';
    export default defineConfig({
    integrations: [
    {
    name: 'set-prerender',
    hooks: {
    'astro:route:setup': ({ route }) => {
    // Load environment variables from .env files (if needed)
    const { PRERENDER } = loadEnv(process.env.NODE_ENV, process.cwd(), '');
    // Find routes matching the expected filename.
    if (route.component.endsWith('/blog/[slug].astro')) {
    // Set the prerender value on routes as needed.
    route.prerender = PRERENDER;
    }
    },
    },
    }
    ],
    });

在 Astro 4.x 中,你可以配置 image.service: squooshImageService() 以使用 Squoosh 而不是 Sharp 来转换你的图像。但是,底层库 libsquoosh 已不再维护,并且存在内存和性能问题。

Astro 5.0 完全移除了 Squoosh 图像优化服务。

要切换到内置的 Sharp 图像服务,请从你的 Astro 配置中移除 squooshImageService 导入。默认情况下,你将使用 Sharp 处理 astro:assets

astro.config.mjs
import { squooshImageService } from "astro/config";
import { defineConfig } from "astro/config";
export default defineConfig({
image: {
service: squooshImageService()
}
});

如果你使用的是像 pnpm 这样的严格包管理器,你可能需要手动安装 sharp 包才能使用 Sharp 图像服务,即使它默认内置于 Astro 中。

如果你的适配器不支持 Astro 内置的 Sharp 图像优化,你可以配置一个空操作图像服务,以允许你使用 <Image /><Picture /> 组件。

或者,如果你无法使用 Sharp 图像服务,你可能希望考虑一个社区维护的 Squoosh 图像服务

如果你的适配器之前指定了其与 Squoosh 的兼容性状态,你现在应该从适配器配置中移除此信息。

my-adapter.mjs
supportedAstroFeatures: {
assets: {
isSquooshCompatible: true
}
}
阅读更多关于配置你的默认图像服务的信息。

在 Astro v4.x 中,@types/astro.ts 向用户公开了所有类型,无论它们是否仍在使用中或仅供内部使用。

Astro v5.0 重构了此文件,以移除过时和内部的类型。这次重构为你的编辑器带来了改进(例如,更快的自动补全、更低的内存使用和更相关的补全选项)。但是,此重构可能会在一些依赖于不再对公众可用的类型的项目中导致错误。

移除任何现在在你的项目中导致错误的类型,因为你已无法访问它们。这些主要是以前被弃用和移除的 API,但也可能包括现在是内部的类型。

以下实验性标志已在 Astro v5.0 中移除,这些功能现已可用

  • env
  • serverIslands

此外,以下实验性标志已被移除,并且现在是 Astro v5.0 中的默认或推荐行为

  • directRenderScript(有关对默认 <script> 行为的破坏性变更,请参见下文。)
  • globalRoutePriority(有关对默认路由优先级顺序的破坏性变更,请参见下文。)
  • contentLayer(有关将现有内容集合升级到新的、首选的内容层 API 的指导,请参见下文。)

以下实验性标志已被移除,并且其相应功能不属于 Astro v5.0 的一部分

  • contentCollectionsCache

如果你之前正在使用这些实验性标志,请移除它们,并将你的 env 配置移动到 Astro 配置的根目录

astro.config.mjs
import { defineConfig } from 'astro/config';
export default defineConfig({
experimental: {
directRenderScript: true,
globalRoutePriority: true,
contentLayer: true,
serverIslands: true,
contentCollectionsCache: true,
env: {
schema: {...}
}
},
env: {
schema: {...}
}
})

这些功能在 Astro v5.0 中都默认可用。

v5.0 博客文章中阅读有关这些激动人心的功能以及更多信息。

Astro v5.0 中一些默认行为已更改,你的项目代码可能需要更新以适应这些更改。

在大多数情况下,唯一需要的操作是审查你现有项目的部署,并确保其继续按预期运行,必要时对代码进行更新。在某些情况下,可能有一个配置设置允许你继续使用以前的默认行为。

在 Astro v4.x 中,security.checkOrigin 的默认值为 false。以前,你必须明确将此值设置为 true 才能启用跨站请求伪造(CSRF)保护。

Astro v5.0 将此选项的默认值更改为 true,并将在按需渲染的页面中自动检查每个请求发送的 “origin” 标头是否与 URL 匹配。

如果你之前配置了 security.checkOrigin: true,你不再需要在 Astro 配置中保留这一行。这现在是默认设置。

要禁用此行为,你必须明确设置 security.checkOrigin: false

astro.config.mjs
export default defineConfig({
output: "server",
security: {
checkOrigin: false
}
})
阅读更多关于安全配置选项的信息

注入路由和重定向的路由优先级顺序

标题为“注入路由和重定向的路由优先级顺序”的部分

在 Astro v4.x 中,experimental.globalRoutePriority 是一个可选标志,可确保注入的路由、基于文件的路由和重定向都使用所有路由的路由优先级顺序规则进行优先级排序。这通过不自动优先处理某些类型的路由并标准化路由优先级顺序,从而更好地控制项目中的路由。

Astro v5.0 移除了此实验性标志,并将其作为 Astro 中新的默认行为:重定向和注入的路由现在与基于文件的项目路由具有同等优先级。

请注意,这已经是 Starlight 中的默认行为,不应影响已更新的 Starlight 项目。

如果你的项目包含注入的路由或重定向,请检查你的路由是否按预期构建页面 URL。下面显示了新的预期行为示例。

在一个包含以下路由的项目中

  • 基于文件的路由:/blog/post/[pid]
  • 基于文件的路由:/[page]
  • 注入的路由:/blog/[...slug]
  • 重定向:/blog/tags/[tag] -> /[tag]
  • 重定向:/posts -> /blog

将构建以下 URL(而不是遵循 Astro v4.x 的路由优先级顺序)

  • /blog/tags/astro 由重定向到 /tags/[tag] 构建(而不是由注入的路由 /blog/[...slug] 构建)
  • /blog/post/0 由基于文件的路由 /blog/post/[pid] 构建(而不是由注入的路由 /blog/[...slug] 构建)
  • /posts 由重定向到 /blog 构建(而不是由基于文件的路由 /[page] 构建)

如果发生路由冲突,即两个具有相同路由优先级的路由尝试构建相同的 URL,Astro 将记录一条警告,指出冲突的路由。

阅读更多关于路由优先级顺序规则的信息。

在 Astro v4.x 中,experimental.directRenderScript 是一个可选标志,用于直接渲染在 .astro 文件中声明的 <scripts>(包括 TypeScript、导入 node_modules 和脚本去重等现有功能)。此策略可防止脚本在未使用它们的地方执行。此外,条件渲染的脚本以前是隐式内联的,就像自动为它们添加了 is:inline 指令一样。

Astro 5.0 移除了此实验性标志,并将其作为 Astro 中新的默认行为:脚本不再被提升到 <head>,页面上的多个脚本不再被打包在一起,并且 <script> 标签可能会干扰 CSS 样式。此外,条件渲染的脚本不再隐式内联。

请检查你的 <script> 标签,并确保它们的行为符合预期。

如果你之前有条件渲染的 <script> 标签,你需要添加一个 is:inline 属性以保持与以前相同的行为

src/components/MyComponent.astro
---
type Props = {
showAlert: boolean
}
const { showAlert } = Astro.props;
---
{
showAlert && <script is:inline>alert("Some very important code!!")</script>
}
阅读更多关于在 Astro 中使用 script 标签的信息。

以下更改在 Astro v5.0 中被视为破坏性变更。破坏性变更可能提供也可能不提供临时的向后兼容性。如果你正在使用这些功能,你可能需要按照每个条目中的建议更新你的代码。

在 Astro 4.x 中,Astro 的视图过渡 API 包含一个 <ViewTransitions /> 路由器组件,以启用客户端路由、页面过渡等功能。

Astro 5.0 将此组件重命名为 <ClientRouter />,以阐明该组件在 API 中的作用。这使得从 Astro 的 <ClientRouter /> 路由组件获得的功能与原生的基于 CSS 的 MPA 路由器略有不同这一点更加清晰。

功能没有改变。这个组件只是改了名字。

将所有 ViewTransitions 的导入和组件替换为 ClientRouter

src/layouts/MyLayout.astro
import { ViewTransitions } from 'astro:transitions';
import { ClientRouter } from 'astro:transitions';
<html>
<head>
...
<ViewTransitions />
<ClientRouter />
</head>
</html>
阅读更多关于 Astro 中的视图过渡和客户端路由的信息。

在 Astro v4.x 中,Astro 依赖 src/env.d.ts 文件进行类型推断和为依赖于生成类型的功能定义模块。

Astro 5.0 转而使用 .astro/types.d.ts 文件进行类型推断,并现在推荐在 tsconfig.json 中设置 includeexclude,以从 Astro 类型中受益并避免检查已构建的文件。

运行 astro sync 不再创建或更新 src/env.d.ts,因为它对于类型检查标准的 Astro 项目不是必需的。

要将你的项目更新为 Astro 推荐的 TypeScript 设置,请将以下 includeexclude 属性添加到你现有的 tsconfig.json

tsconfig.json
{
"extends": "astro/tsconfigs/base",
"include": [".astro/types.d.ts", "**/*"],
"exclude": ["dist"]
}

请注意,只有在你添加了自定义配置,或者你没有使用 tsconfig.json 文件时,才需要 src/env.d.ts

阅读更多关于Astro 中的 TypeScript 配置的信息。
标题为“已更改:通过 HTML 表单提交的 Action 不再使用 cookie 重定向”的部分

在 Astro 4.x 中,从 HTML 表单调用的 action 会触发一个重定向,并通过 cookie 转发结果。这对于大型表单错误和超过 4 KB cookie 存储限制的返回值造成了问题。

Astro 5.0 现在将 action 的结果呈现为 POST 结果,而没有任何转发。当用户尝试刷新页面时,这将引入一个“确认表单重新提交?”对话框,但它不再对 action 返回值施加 4 KB 的限制。

你应该更新依赖重定向的 action 结果处理,并可选择使用中间件来处理“确认表单重新提交?”对话框。

如果你的 HTML 表单 action 指向一个不同的路由(即 action={"/success-page" + actions.name}),Astro 将不再在出错时重定向到上一个路由。你可以使用 Astro 组件中的重定向来手动实现此行为。此示例在成功时重定向到一个新路由,否则在当前页面处理错误

src/pages/newsletter.astro
---
import { actions } from 'astro:actions';
const result = Astro.getActionResult(actions.newsletter);
if (!result?.error) {
// Embed relevant result data in the URL if needed
// example: redirect(`/confirmation?email=${result.data.email}`);
return redirect('/confirmation');
}
---
<form method="POST" action={'/confirmation' + actions.newsletter}>
<label>E-mail <input required type="email" name="email" /></label>
<button>Sign up</button>
</form>

要处理刷新时的“确认表单重新提交?”对话框,或跨会话保留 action 结果,你现在可以通过中间件自定义 action 结果处理

我们建议使用会话存储提供程序,如我们的 Netlify Blob 示例中所述。但是,如果你更喜欢 4.X 中的 cookie 转发行为并接受 4 KB 的大小限制,你可以实现如此示例代码段中所示的模式

src/middleware.ts
import { defineMiddleware } from 'astro:middleware';
import { getActionContext } from 'astro:actions';
export const onRequest = defineMiddleware(async (context, next) => {
// Skip requests for prerendered pages
if (context.isPrerendered) return next();
const { action, setActionResult, serializeActionResult } = getActionContext(context);
// If an action result was forwarded as a cookie, set the result
// to be accessible from `Astro.getActionResult()`
const payload = context.cookies.get('ACTION_PAYLOAD');
if (payload) {
const { actionName, actionResult } = payload.json();
setActionResult(actionName, actionResult);
context.cookies.delete('ACTION_PAYLOAD');
return next();
}
// If an action was called from an HTML form action,
// call the action handler and redirect with the result as a cookie.
if (action?.calledFrom === 'form') {
const actionResult = await action.handler();
context.cookies.set('ACTION_PAYLOAD', {
actionName: action.name,
actionResult: serializeActionResult(actionResult),
});
if (actionResult.error) {
// Redirect back to the previous page on error
const referer = context.request.headers.get('Referer');
if (!referer) {
throw new Error('Internal: Referer unexpectedly missing from Action POST request.');
}
return context.redirect(referer);
}
// Redirect to the destination page on success
return context.redirect(context.originPathname);
}
return next();
})

已更改:compiledContent() 现在是一个异步函数

标题为“已更改:compiledContent() 现在是一个异步函数”的部分

在 Astro 4.x 中,Markdown 模块中包含了顶层 await。这导致了自定义图像服务和 Markdown 内部图像的一些问题,导致 Node 突然退出且没有错误消息。

Astro 5.0 将 Markdown 导入上的 compiledContent() 属性设为异步函数,需要使用 await 来解析内容。

更新你的代码,在调用 compiledContent() 时使用 await

src/pages/post.astro
---
import * as myPost from "../blog/post.md";
const content = myPost.compiledContent();
const content = await myPost.compiledContent();
---
<Fragment set:html={content} />
阅读更多关于compiledContent() 函数以返回编译后的 Markdown 的信息。

变更:astro:content 不能再在客户端上使用

标题为“变更:astro:content 不能再在客户端上使用”的部分

在 Astro 4.x 中,可以在客户端上访问 astro:content 模块。

Astro 5.0 移除了这种访问方式,因为它从未被有意地暴露给客户端使用。以这种方式使用 astro:content 存在限制,并且会增大客户端包的体积。

如果你当前正在客户端使用 astro:content,请改为通过 props 将所需数据传递给你的客户端组件。

src/pages/blog.astro
---
import { getCollection } from 'astro:content';
import ClientComponent from '../components/ClientComponent';
const posts = await getCollection('blog');
const postsData = posts.map(post => post.data);
---
<ClientComponent posts={postsData} />
阅读更多关于 astro:content API 的信息。

重命名:Shiki css-variables 主题颜色令牌名称

标题为“重命名:Shiki css-variables 主题颜色令牌名称”的部分

在 Astro v4.x 中,Shiki css-variables 主题分别使用 --astro-code-color-text--astro-code-color-background 令牌来设置代码块的前景色和背景色。

Astro v5.0 将它们分别重命名为 --astro-code-foreground--astro-code-background,以更好地与 Shiki v1 的默认值保持一致。

你可以在你的项目中执行全局查找和替换,以迁移到新的令牌名称。

src/styles/global.css
:root {
--astro-code-color-text: #000;
--astro-code-color-background: #fff;
--astro-code-foreground: #000;
--astro-code-background: #fff;
}
阅读更多关于 Astro 中的语法高亮 的信息。

已更改:用于高亮代码块的内部 Shiki rehype 插件

标题为“变更:用于高亮代码块的内部 Shiki rehype 插件”的部分

在 Astro 4.x 中,Astro 的内部 Shiki rehype 插件将代码块高亮为 HTML。

Astro 5.0 更新了此插件,将代码块高亮为 hast。这使得 Markdown 和 MDX 的处理更加直接,并提高了项目构建时的性能。然而,这可能会导致现有 Shiki transformers 出现问题。

如果你正在使用传递给 markdown.shikiConfig.transformers 的 Shiki transformers,你必须确保它们不使用 postprocess 钩子。这个钩子不再对 .md.mdx 文件中的代码块运行。(更多信息请参阅 Shiki 关于 transformer 钩子的文档)。

.mdoc 文件和 Astro 的内置 <Code /> 组件中的代码块不使用内部 Shiki rehype 插件,因此不受影响。

阅读更多关于 Astro 中的语法高亮 的信息。

变更:Markdown 和 MDX 页面的自动 charset=utf-8 行为

标题为“变更:Markdown 和 MDX 页面的自动 charset=utf-8 行为”的部分

在 Astro 4.0 中,Markdown 和 MDX 页面(位于 src/pages/)会在 Content-Type 头中自动响应 charset=utf-8,这允许在你的页面中渲染非 ASCII 字符。

Astro 5.0 更新了行为,改为添加 <meta charset="utf-8"> 标签,并且仅对不使用 Astro 特殊 layout frontmatter 属性的页面生效。类似地,对于 MDX 页面,只有当 MDX 内容没有导入一个包裹的 Layout 组件时,Astro 才会添加该标签。

如果你的 Markdown 或 MDX 页面使用了 layout frontmatter 属性,或者 MDX 页面内容导入了一个包裹的 Layout 组件,那么 HTML 编码将由指定的布局组件来处理,并且 <meta charset="utf-8"> 标签将不会被默认添加到你的页面中。

如果你需要 charset=utf-8 来正确渲染你的页面,请确保你的布局组件包含了 <meta charset="utf-8"> 标签。如果你还没有添加,你可能需要添加它。

阅读更多关于 Markdown 布局 的信息。

已更改:在 remark 和 rehype 插件中附加的 Astro 特定元数据

标题为“变更:在 remark 和 rehype 插件中附加的 Astro 特定元数据”的部分

在 Astro 4.x 中,附加到 remark 和 rehype 插件中 vfile.data 的 Astro 特定元数据被附加在不同的位置,并且名称不一致。

Astro 5 清理了 API,元数据现在被重命名如下:

  • vfile.data.__astroHeadings -> vfile.data.astro.headings
  • vfile.data.imagePaths -> vfile.data.astro.imagePaths

imagePaths 的类型也从 Set<string> 更新为 string[]vfile.data.astro.frontmatter 元数据保持不变。

虽然我们不认为这些是公共 API,但希望重用 Astro 元数据的 remark 和 rehype 插件可以访问它们。如果你正在使用这些 API,请确保在新的位置访问它们。

阅读更多关于 在 Astro 中使用 Markdown 插件 的信息。

在 Astro 4.x 中,你可以在你的 image 配置中设置一个端点用于图片优化。

Astro 5.0 允许你自定义 image.endpoint 配置的 routeentrypoint。在默认路由 /_image 与现有路由或你的本地服务器设置冲突的特定情况下,这可能很有用。

如果你之前自定义了 image.endpoint,请将该端点移动到新的 endpoint.entrypoint 属性。可选地,你可以自定义一个 route

astro.config.mjs
import { defineConfig } from "astro/config";
defineConfig({
image: {
endpoint: './src/image-endpoint.ts',
endpoint: {
route: "/image",
entrypoint: "./src/image_endpoint.ts"
}
},
})
阅读更多关于 设置用于图片优化的端点 的信息。

变更:build.clientbuild.server 的解析行为

标题为“变更:build.client 和 build.server 的解析行为”的部分

在 Astro v4.x 中,根据文档,build.clientbuild.server 选项应该相对于 outDir 选项进行解析,但它并不总是按预期工作。

Astro 5.0 修复了此行为,使其能够正确地从 outDir 选项进行解析。例如,如果 outDir 设置为 ./dist/nested/,那么默认情况下:

  • build.client 将解析为 <root>/dist/nested/client/
  • build.server 将解析为 <root>/dist/nested/server/

之前这些值被错误地解析为:

  • build.client 被解析为 <root>/dist/nested/dist/client/
  • build.server 被解析为 <root>/dist/nested/dist/server/

如果你依赖于之前的构建路径,请确保你的项目代码已更新为新的构建路径。

阅读更多关于 Astro 中的 build 配置选项 的信息。

已更改:配置文件中的 JS 依赖不再由 Vite 处理

标题为“变更:配置文件中的 JS 依赖项不再由 Vite 处理”的部分

在 Astro 4.x 中,本地链接的 JS 依赖项(例如 npm link、在 monorepo 中等)在被 Astro 配置文件导入时,能够使用像 import.meta.glob 这样的 Vite 功能。

Astro 5 更新了 Astro 配置文件的加载流程,以忽略使用 Vite 处理本地链接的 JS 依赖项。导出原始 TypeScript 文件的依赖项不受影响。取而代之的是,这些 JS 依赖项将像 node_modules 中的其他依赖项一样,由 Node.js 运行时正常导入。

进行此项更改是因为之前的行为在集成作者中引起了困惑,他们测试的包在本地可以工作,但发布后却不行。这也限制了 CJS-only 依赖项的使用,因为 Vite 要求代码必须是 ESM。虽然此更改只影响 JS 依赖项,但仍建议包尽可能导出 JavaScript 而不是原始 TypeScript,以防止意外使用 Vite 特定的功能,因为这是 Astro 配置加载流程的一个实现细节。

在运行你的 Astro 项目之前,请确保你的本地链接的 JS 依赖项已经构建。然后,配置加载应该会像以前一样工作。

阅读更多关于 Astro 中的 Vite 配置设置 的信息。

在 Astro v4.x 中,由 paginate() 返回的 URL(例如 page.url.nextpage.url.first 等)不包括你在 Astro 配置中为 base 设置的值。你必须手动将配置的 base 值前置到 URL 路径。

Astro 5.0 会自动在 page.url 中包含 base 值。

如果你正在对这些 URL 使用 paginate() 函数,请移除任何现有的 base 值,因为它现在已经为你添加好了:

---
export async function getStaticPaths({ paginate }) {
const astronautPages = [{
astronaut: 'Neil Armstrong',
}, {
astronaut: 'Buzz Aldrin',
}, {
astronaut: 'Sally Ride',
}, {
astronaut: 'John Glenn',
}];
return paginate(astronautPages, { pageSize: 1 });
}
const { page } = Astro.props;
// `base: /'docs'` configured in `astro.config.mjs`
const prev = "/docs" + page.url.prev;
const prev = page.url.prev;
---
<a id="prev" href={prev}>Back</a>
阅读更多关于 Astro 中的分页 的信息。

已更改:非布尔值的 HTML 属性值

标题为“变更:非布尔值 HTML 属性值”的部分

在 Astro v4.x 中,非布尔值 HTML 属性在渲染为 HTML 时可能没有包含它们的值。

Astro v5.0 会将值显式地渲染为 ="true"="false",以匹配浏览器中正确的属性处理方式。

在下面的 .astro 示例中,只有 allowfullscreen 是一个布尔属性:

src/pages/index.astro
<!-- `allowfullscreen` is a boolean attribute -->
<p allowfullscreen={true}></p>
<p allowfullscreen={false}></p>
<!-- `inherit` is *not* a boolean attribute -->
<p inherit={true}></p>
<p inherit={false}></p>
<!-- `data-*` attributes are not boolean attributes -->
<p data-light={true}></p>
<p data-light={false}></p>

Astro v5.0 现在在渲染非布尔属性的 HTML 时,会保留完整的 data 属性及其值:

<p allowfullscreen></p>
<p></p>
<p inherit="true"></p>
<p inherit></p>
<p inherit="false"></p>
<p data-light></p>
<p data-light="true"></p>
<p></p>
<p data-light="false"></p>

如果你依赖于属性值,例如,用于定位元素或条件渲染,请更新你的代码以匹配新的非布尔属性值:

el.getAttribute('inherit') === ''
el.getAttribute('inherit') === 'false'
el.hasAttribute('data-light')
el.dataset.light === 'true'
阅读更多关于 在 Astro 中使用 HTML 属性 的信息。

在 Astro 4.x 中,当添加新值时,可以在中间件、API 端点和页面中完全替换整个 locals 对象。

Astro 5.0 要求你将值附加到现有的 locals 对象上,而不是删除它。中间件、API 端点和页面中的 Locals 不能再被完全覆盖。

在你之前覆盖对象的地方,现在必须改为给它赋值:

src/middleware.js
ctx.locals = {
Object.assign(ctx.locals, {
one: 1,
two: 2
}
})
查看更多关于 context.locals 中存储数据 的信息。

在 Astro v4.x 中,传递给 getStaticPath()params 会自动使用 decodeURIComponent 进行解码。

Astro v5.0 不再解码传递给 getStaticPathsparams 的值。如果需要,你必须手动解码它们。

如果你之前依赖于自动解码,请在传递 params 时使用 decodeURI

src/pages/[id].astro
---
export function getStaticPaths() {
return [
{ params: { id: "%5Bpage%5D" } },
{ params: { id: decodeURI("%5Bpage%5D") } },
]
}
const { id } = Astro.params;
---

请注意,不鼓励对 getStaticPaths 使用 decodeURIComponent,因为它会解码比预期更多的字符,例如 /?# 等。

阅读更多关于 使用 params 创建动态路由 的信息。

变更:RouteData 类型被 IntegrationsRouteData 替换 (Integrations API)

标题为“变更:RouteData 类型被 IntegrationsRouteData 替换 (Integrations API)”的部分

在 Astro v4.x 中,astro:build:ssrastro:build:done 钩子中的 entryPoints 类型是 RouteData

Astro v5.0 中,entryPoints 的类型现在是 IntegrationRouteData,它包含 RouteData 类型的一个子集。字段 isIndexfallbackRoutes 已被移除。

更新你的适配器,将 entryPoints 的类型从 RouteData 更改为 IntegrationRouteData

import type {RouteData} from 'astro';
import type {IntegrationRouteData} from "astro"
function useRoute(route: RouteData) {
function useRoute(route: IntegrationRouteData) {
}

变更:distURL 现在是一个数组 (Integrations API)

标题为“变更:distURL 现在是一个数组 (Integrations API)”的部分

在 Astro v4.x 中,RouteData.distURLundefined 或一个 URL

Astro v5.0 更新了 IntegrationRouteData.distURL 的形状,使其为 undefined 或一个 URL 数组。这修复了以前的一个错误,因为一个路由可以在磁盘上生成多个文件,尤其是在使用动态路由如 [slug][...slug] 时。

更新你的代码以处理作为数组的 IntegrationRouteData.distURL

if (route.distURL) {
if (route.distURL.endsWith('index.html')) {
// do something
}
for (const url of route.distURL) {
if (url.endsWith('index.html')) {
// do something
}
}
}

变更:传递给 app.render() 的参数 (Adapter API)

标题为“变更:传递给 app.render() 的参数 (Adapter API)”的部分

在 Astro 4.x 中,Adapter API 方法 app.render() 可以接收三个参数:一个强制性的 request,一个选项对象或一个 routeData 对象,以及 locals

Astro 5.0 将后两个参数合并为一个名为 renderOptions 的选项参数。

将一个对象作为第二个参数传递给 app.render(),该对象可以包含 routeDatalocals 作为属性。

const response = await app.render(request, routeData, locals);
const response = await app.render(request, {routeData, locals});

变更:supportedAstroFeatures 上的属性 (Adapter API)

标题为“变更:supportedAstroFeatures 上的属性 (Adapter API)”的部分

在 Astro 4.x 中,supportedAstroFeatures 允许适配器作者指定他们的集成支持哪些功能,其中包括一个 assets 属性来指定支持 Astro 的哪些图片服务。

Astro 5.0 将此属性替换为一个专用的 sharpImageService 属性,用于确定适配器是否与内置的 sharp 图片服务兼容。

v5.0 还为 supportedAstroFeatures 的不同属性为适配器增加了一个新的 limited 值,表示适配器与该功能兼容,但存在一些限制。这对于那些支持某个功能,但并非在所有情况下或所有选项下都支持的适配器很有用。

此外,适配器的 supportedAstroFeatures 上不同属性的值现在可以是对象,包含 supportmessage 属性。message 属性的内容将在适配器与某个功能不兼容时,在 Astro CLI 中显示一条有用的消息。这对于新的 limited 值尤其有用,可以向用户解释为什么支持是有限的。

如果你正在使用 assets 属性,请移除它,因为它已不再可用。要指定你的适配器支持内置的 sharp 图片服务,请将其替换为 sharpImageService

你可能还希望使用新的 limited 选项更新你支持的功能,并包含一条关于你的适配器支持情况的消息。

my-adapter.mjs
supportedAstroFeatures: {
assets: {
supportKind: "stable",
isSharpCompatible: true,
isSquooshCompatible: true,
},
sharpImageService: {
support: "limited",
message: 'This adapter supports the built-in sharp image service, but with some limitations.'
}
}
阅读更多关于 在适配器中指定支持的 Astro 功能 的信息。

已移除:开发工具栏应用的已弃用定义形式 (开发工具栏 API)

标题为“移除:已弃用的开发工具栏应用程序定义形状 (Dev Toolbar API)”的部分

在 Astro 4.x 中,构建开发工具栏应用程序时,仍然可以使用之前已弃用的 addDevToolbarApp(string); 签名。然后,用于定义应用程序的 idtitleicon 属性通过应用程序 entrypoint 的默认导出提供。

Astro 5.0 完全移除了这个选项,转而采用在集成中定义开发工具栏应用程序时更直观的当前对象形状,这使得 Astro 在工具栏应用程序加载失败时能够提供更好的错误信息。

如果你正在使用已弃用的形状,请更新你的开发工具栏应用程序以使用新的形状:

my-integration.mjs
// Old shape
addDevToolbarApp("./my-dev-toolbar-app.mjs");
// New shape
addDevToolbarApp({
id: "my-app",
name: "My App",
icon: "<svg>...</svg>",
entrypoint: "./my-dev-toolbar-app.mjs",
});
my-dev-toolbar-app.mjs
export default {
id: 'my-dev-toolbar-app',
title: 'My Dev Toolbar App',
icon: '🚀',
init() {
// ...
}
}

移除:在 create-astro 期间配置 Typescript

标题为“移除:在 create-astro 期间配置 Typescript”的部分

在 Astro v4.x 中,当使用 create astro 创建新项目时,可以通过回答问题或传递相关的 --typescript 标志并附带所需的 TypeScript 设置,在 Astro 的三种 TypeScript 设置之间进行选择。

Astro 5.0 更新了 create astro CLI 命令,移除了 TypeScript 问题及其相关的 --typescript 标志。“strict”预设现在是所有通过命令行创建的新项目的默认设置,并且在该时间点无法再进行自定义。但是,仍然可以在 tsconfig.json 中手动更改 TypeScript 模板。

如果你正在使用 create-astro--typescript 标志,请从你的命令中移除它。

终端窗口
npm create astro@latest -- --template <example-name> --typescript strict
npm create astro@latest -- --template <example-name>

知道有关 Astro v5.0 的好资源吗?编辑此页并在下方添加链接!

请查看 Astro 在 GitHub 上的 issues 以了解任何已报告的问题,或者自己提交一个 issue。

贡献 社区 赞助