Skip to content

故障排除

Astro 提供了多种不同的工具来帮助你排除故障和调试代码。

¥Astro provides several different tools to help you troubleshoot and debug your code.

¥Tips and tricks

使用 console.log() 进行调试

Section titled 使用 console.log() 进行调试

¥Debugging with console.log()

console.log() 是一种简单但流行的调试 Astro 代码的方法。编写 console.log() 语句的位置将决定打印调试输出的位置:

¥console.log() is a simple-but-popular method of debugging your Astro code. Where you write your console.log() statement will determine where your debugging output is printed:

---
console.log('Hi! I’m the server. This is logged in the terminal where Astro is running.');
---
<script>
console.log('Hi! I’m the client. This is logged in browser dev console.');
</script>

Astro 前言中的 console.log() 语句将始终输出到运行 Astro CLI 的终端。这是因为 Astro 在服务器上运行,而不是在浏览器中运行。

¥A console.log() statement in Astro frontmatter will always output to the terminal running the Astro CLI. This is because Astro runs on the server, and never in the browser.

在 Astro <script> 标签内编写或导入的代码在浏览器中运行。任何 console.log() 语句或其他调试输出都将打印到浏览器的控制台中。

¥Code that is written or imported inside of an Astro <script> tag is run in the browser. Any console.log() statements or other debug output will be printed to the console in your browser.

¥Debugging framework components

框架组件(如 React 和 Svelte)是独一无二的:它们默认渲染服务器端,这意味着 console.log() 调试输出将在终端中可见。但是,它们也可以为浏览器水合,这可能会导致你的调试日志也出现在浏览器中。

¥Framework components (like React and Svelte) are unique: They render server-side by default, meaning that console.log() debug output will be visible in the terminal. However, they can also be hydrated for the browser, which may cause your debug logs to also appear in the browser.

这对于调试 SSR 输出和浏览器中的水合组件之间的差异非常有用。

¥This can be useful for debugging differences between the SSR output and the hydrated components in the browser.

¥Astro <Debug /> component

为了帮助你调试 Astro 组件,Astro 提供了内置 <Debug /> 组件,该组件可将任何值直接渲染到组件 HTML 模板中。这对于在浏览器中快速调试非常有用,而无需在终端和浏览器之间来回切换。

¥To help you debug your Astro components, Astro provides a built-in <Debug /> component which renders any value directly into your component HTML template. This is useful for quick debugging in the browser without having to flip back-and-forth between your terminal and your browser.

---
import { Debug } from 'astro:components';
const sum = (a, b) => a + b;
---
<!-- Example: Outputs {answer: 6} to the browser -->
<Debug answer={sum(2, 4)} />

调试组件支持多种语法选项,使调试更加灵活和简洁:

¥The Debug component supports a variety of syntax options for even more flexible and concise debugging:

---
import { Debug } from 'astro:components';
const sum = (a, b) => a + b;
const answer = sum(2, 4);
---
<!-- Example: All three examples are equivalent. -->
<Debug answer={sum(2, 4)} />
<Debug {{answer: sum(2, 4)}} />
<Debug {answer} />

¥Common Error Messages

以下是你可能在终端中看到的一些常见错误消息、它们可能意味着什么以及如何处理它们。请参阅我们的 完整的错误参考指南,了解你可能遇到的 Astro 错误的完整列表。

¥Here are some common error messages you might see in the terminal, what they might mean, and what to do about them. See our full error reference guide for a complete list of Astro errors you may encounter.

不能在模块外部使用 import 语句

Section titled 不能在模块外部使用 import 语句

¥Cannot use import statement outside a module

在 Astro 组件中,<script> 标签默认被提升并加载为 JS 模块。如果你已在标记中包含 is:inline 指令 或任何其他属性,则此默认行为将被删除。

¥In Astro components, <script> tags are hoisted and loaded as JS modules by default. If you have included the is:inline directive or any other attribute in your tag, this default behavior is removed.

解决方案:如果你已向 <script> 标记添加任何属性,则还必须添加 type="module" 属性才能使用 import 语句。

¥Solution: If you have added any attributes to your <script> tag, you must also add the type="module" attribute to be able to use import statements.

状态:预期的 Astro 行为,如预期的那样。

¥Status: Expected Astro behavior, as intended.

不确定这是你的问题吗?看看是否还有其他人举报了 这个问题

¥Not sure that this is your problem?\ Check to see if anyone else has reported this issue!

document(或 window)未定义

Section titled document(或 window)未定义

¥document (or window) is not defined

当尝试访问服务器上的 documentwindow 时,会出现此错误。

¥This error occurs when trying to access document or window on the server.

Astro 组件在服务器上运行,因此你无法在 frontmatter 中访问这些特定于浏览器的对象。

¥Astro components run on the server, so you can’t access these browser-specific objects within the frontmatter.

框架组件默认运行在服务器上,因此在渲染期间访问 documentwindow 时可能会出现此错误。

¥Framework components run on the server by default, so this error can occur when accessing document or window during rendering.

解决方案:确定调用 documentwindow 的代码。如果你没有直接使用 documentwindow 但仍然收到此错误,请检查你正在导入的任何包是否要在客户端上运行。

¥Solution: Determine the code that calls document or window. If you aren’t using document or window directly and still getting this error, check to see if any packages you’re importing are meant to run on the client.

  • 如果代码位于 Astro 组件中,请将其移至 frontmatter 之外的 <script> 标记中。这告诉 Astro 在客户端上运行此代码,其中 documentwindow 可用。

  • 如果代码位于框架组件中,请尝试在渲染后使用生命周期方法访问这些对象(例如 React 中的 useEffect()、Vue 中的 onMounted() 和 Svelte 中的 onMount())。通过使用 客户: 指令(如 client:load)来告诉框架组件水合客户端,以运行这些生命周期方法。你还可以通过添加 client:only 指令来阻止组件在服务器上渲染。

状态:预期的 Astro 行为,如预期的那样。

¥Status: Expected Astro behavior, as intended.

¥Expected a default export

当尝试导入或渲染无效组件或无法正常工作的组件时,可能会引发此错误。(出现此特定消息是由于 Astro 中导入 UI 组件的工作方式所致。)

¥This error can be thrown when trying to import or render an invalid component, or one that is not working properly. (This particular message occurs because of the way importing a UI component works in Astro.)

解决方案:尝试查找你正在导入和渲染的任何组件中的错误,并确保其正常工作。考虑打开 astro.new 中的 Astro 入门模板,并在最小的 Astro 项目中仅对你的组件进行故障排除。

¥Solution: Try looking for errors in any component you are importing and rendering, and make sure it’s working correctly. Consider opening an Astro starter template from astro.new and troubleshooting just your component in a minimal Astro project.

状态:预期的 Astro 行为,如预期的那样。

¥Status: Expected Astro behavior, as intended.

¥Refused to execute inline script

你可能会在浏览器控制台中看到记录以下错误:

¥You may see the following error logged in the browser console:

拒绝执行内联脚本,因为它违反了以下内容安全策略指令:…

¥Refused to execute inline script because it violates the following Content Security Policy directive: …

这意味着你网站的 内容安全政策 (CSP) 不允许运行 Astro 默认输出的内联 <script> 标签。

¥This means that your site’s Content Security Policy (CSP) disallows running inline <script> tags, which Astro outputs by default.

解决方案:更新你的 CSP 以包含 script-src: 'unsafe-inline' 以允许内联脚本运行。或者,你可以使用第三方集成(如 astro-shield)为你生成 CSP 标头。

¥Solution: Update your CSP to include script-src: 'unsafe-inline' to allow inline scripts to run. Alternatively, you can use a third-party integration such as astro-shield to generate the CSP headers for you.

¥Common gotchas

¥My component is not rendering

首先,检查你是否已在 .astro 组件脚本.mdx 文件 中导入了组件。

¥First, check to see that you have imported the component in your .astro component script or .mdx file.

然后检查你的导入声明:

¥Then check your import statement:

  • 你的导入链接到错误的位置吗?(检查你的导入路径。)

  • 你的导入与导入的组件同名吗?(检查你的组件名称并确认它是 遵循 .astro 语法。)

  • 你是否在导入中包含了扩展名?(检查你导入的文件是否包含扩展名。例如 .astro.md.vue.svelte。注意:只有 .js(x).ts(x) 文件不需要文件扩展名。)

¥My component is not interactive

如果你的组件正在渲染(见上文)但没有响应用户交互,那么你可能缺少 client:* 指令 来水合你的组件。

¥If your component is rendering (see above) but is not responding to user interaction, then you may be missing a client:* directive to hydrate your component.

默认情况下,UI 框架组件未在客户端中水合.如果未提供 client:* 指令,则其 HTML 将在没有 JavaScript 的情况下渲染到页面上。

¥By default, a UI Framework component is not hydrated in the client. If no client:* directive is provided, its HTML is rendered onto the page without JavaScript.

¥Cannot find package ‘X’

如果你在启动 Astro 时看到 "Cannot find package 'react'"(或类似)警告,则意味着你需要将该软件包安装到你的项目中。并非所有包管理器都会自动为你安装对等依赖。如果你使用的是 Node v16+ 并使用 npm,则无需担心此部分。

¥If you see a "Cannot find package 'react'" (or similar) warning when you start up Astro, that means that you need to install that package into your project. Not all package managers will install peer dependencies for you automatically. If you are on Node v16+ and using npm, you should not need to worry about this section.

例如,React 是 @astrojs/react 集成的对等依赖。这意味着你应该在集成的同时安装官方 reactreact-dom 软件包。然后集成将自动从这些包中提取。

¥React, for example, is a peer dependency of the @astrojs/react integration. That means that you should install the official react and react-dom packages alongside your integration. The integration will then pull from these packages automatically.

Terminal window
# Example: Install integrations and frameworks together
npm install @astrojs/react react react-dom

有关向 Astro 添加框架渲染器、CSS 工具和其他包的说明,请参阅 Astro 的集成指南

¥See Astro’s integration guide for instructions on adding framework renderers, CSS tools and other packages to Astro.

Astro.glob() - 未找到匹配项

Section titled Astro.glob() - 未找到匹配项

¥Astro.glob() - no matches found

使用 Astro.glob() 导入文件时,请确保使用正确的 glob 语法来匹配你需要的所有文件。

¥When using Astro.glob() to import files, be sure to use the correct glob syntax that will match all the files you need.

¥Filepaths

例如,使用 ../components/**/*.js in src/pages/index.astro 导入以下两个文件:

¥For example, use ../components/**/*.js in src/pages/index.astro to import both of the following files:

  • src/components/MyComponent.js

  • src/components/includes/MyOtherComponent.js

¥Supported Values

Astro.glob() 不支持动态变量和字符串插值。

¥Astro.glob() does not support dynamic variables and string interpolation.

这不是 Astro 中的错误。这是由于 Vite’s import.meta.glob() function 的限制,仅支持静态字符串字面量。

¥This is not a bug in Astro. It is due to a limitation of Vite’s import.meta.glob() function which only supports static string literals.

一种常见的解决方法是导入一组更大的文件,其中包括使用 Astro.glob() 所需的所有文件,然后过滤它们:

¥A common workaround is to instead import a larger set of files that includes all the files you need using Astro.glob(), then filter them:

src/components/featured.astro
---
const { postSlug } = Astro.props;
const pathToMyFeaturedPost = `src/pages/blog/${postSlug}.md`;
const posts = await Astro.glob('../pages/blog/*.md');
const myFeaturedPost = posts.find(post => post.file.includes(pathToMyFeaturedPost));
---
<p>
Take a look at my favorite post, <a href={myFeaturedPost.url}>{myFeaturedPost.frontmatter.title}</a>!
</p>

将 Astro 与 Yarn 2+ (Berry) 结合使用

Section titled 将 Astro 与 Yarn 2+ (Berry) 结合使用

¥Using Astro with Yarn 2+ (Berry)

Yarn 2+,又名 Berry,使用一种称为 Plug’n’Play (PnP) 的技术来存储和管理 Node 模块,可以在使用 create astro 初始化新的 Astro 项目或使用 Astro 时进行 造成问题。解决方法是将 .yarnrc.yml 中的 nodeLinker 属性 设置为 node-modules

¥Yarn 2+, a.k.a. Berry, uses a technique called Plug’n’Play (PnP) to store and manage Node modules, which can cause problems while initializing a new Astro project using create astro or while working with Astro. A workaround is to set the nodeLinker property in .yarnrc.yml to node-modules:

.yarnrc.yml
nodeLinker: "node-modules"

在 monorepo 中添加对 Astro 的依赖

Section titled 在 monorepo 中添加对 Astro 的依赖

¥Adding dependencies to Astro in a monorepo

在 monorepo 设置中使用 Astro 时,应将项目依赖添加到每个项目自己的 package.json 文件中。

¥When working with Astro in a monorepo setup, project dependencies should be added in each project’s own package.json file.

但是,你可能还想在 monorepo 的根目录中使用 Astro(例如 Nx 项目建议在根目录安装依赖)。在这种情况下,手动将 Astro 相关的依赖(例如 @astrojs/vueastro-component-lib)添加到 Astro 配置的 vite.ssr.noExternal 部分,以确保这些依赖已正确安装和打包:

¥However, you may also want to use Astro in the root of the monorepo (e.g. Nx projects recommend installing dependencies at the root). In this case, manually add Astro-related dependencies (e.g. @astrojs/vue, astro-component-lib) to the vite.ssr.noExternal part of Astro’s config to ensure that these dependencies are properly installed and bundled:

astro.config.mjs
import { defineConfig } from 'astro/config'
export default defineConfig({
vite: {
ssr: {
noExternal: [
'@astrojs/vue',
'astro-component-lib',
]
}
}
})

¥Using <head> in a component

在 Astro 中,使用 <head> 标签就像任何其他 HTML 标签一样:它不会移动到页面顶部或与现有的 <head> 合并。因此,你通常只想在整个页面中包含一个 <head> 标记。我们建议将单个 <head> 及其内容写入 布局组件 中。

¥In Astro, using a <head> tag works like any other HTML tag: it does not get moved to the top of the page or merged with the existing <head>. Because of this, you usually only want to include one <head> tag throughout a page. We recommend writing that single <head> and its contents in a layout component.

¥An unexpected <script> or <style> is included

你可能会注意到 HTML 源代码中包含导入组件的 <script><style> 标记,即使该组件未出现在最终输出中也是如此。例如,未显示的 有条件地渲染 组件会发生这种情况。

¥You may notice an imported component’s <script> or <style> tags included in your HTML source even if that component doesn’t appear in the final output. For example, this will occur with conditionally rendered components that are not displayed.

Astro 的构建过程适用于模块图:一旦组件包含在模板中,它的 <script><style> 标签就会被处理、优化和打包,无论它是否出现在最终输出中。当应用 is:inline 指令时,这不适用于脚本。

¥Astro’s build process works on the module graph: once a component is included in the template, its <script> and <style> tags are processed, optimized, and bundled, whether it appears in the final output or not. This does not apply to scripts when the is:inline directive is applied.

在 Markdown 中转义特殊字符

Section titled 在 Markdown 中转义特殊字符

¥Escaping special characters in Markdown

某些字符在 Markdown 中具有特殊含义。如果要显示它们,你可能需要使用不同的语法。为此,你可以对这些字符使用 HTML 实体

¥Certain characters have a special meaning in Markdown. You may need to use a different syntax if you want to display them. To do this, you can use HTML entities for these characters instead.

例如,要防止 < 被解释为 HTML 元素的开头,请编写 &lt;

¥For example, to prevent < being interpreted as the beginning of an HTML element, write &lt;.

¥Creating minimal reproductions

在对代码进行故障排除时,创建可以共享的问题的最小再现会很有帮助。这是一个较小的、简化的 Astro 项目,用于演示你的问题。在新项目中进行有效复制有助于确认这是一个可重复的问题,并且不是由你的个人环境或现有项目中的其他问题引起的。

¥When troubleshooting your code, it can be helpful to create a minimal reproduction of the issue that you can share. This is a smaller, simplified Astro project that demonstrates your issue. Having a working reproduction in a new project helps to confirm that this is a repeatable problem, and is not caused by something else in your personal environment or existing project.

当在我们的支持线程中寻求帮助时,共享最小复制品很有帮助,并且在向 Astro 提交错误报告时通常需要共享最小复制品。

¥Sharing a minimal reproduction is helpful when asking for help in our support threads and is often required when filing a bug report to Astro.

¥Create a StackBlitz via astro.new

你可以使用 astro.new 只需单击一下即可创建新的 Astro 项目。对于最小的复制,我们强烈建议从 StackBlitz 中运行的最小(空)示例开始,使用尽可能少的额外代码。

¥You can use astro.new to create a new Astro project with a single click. For minimal reproductions, we strongly recommend starting from the minimal (empty) example running in StackBlitz, with as little extra code as possible.

StackBlitz 将在本地环境之外的浏览器中运行此 Astro 项目。它还将为你提供一个可共享的链接,以便任何 Astro 维护人员或支持小组成员都可以在自己的本地环境之外查看你的最小复制品。这意味着每个人都在查看完全相同的项目,具有相同的配置和依赖。这使得其他人可以轻松地帮助你排除代码故障。如果问题可重现,你可以验证问题是否存在于 Astro 代码本身中,并且你可以放心地提交错误报告。

¥StackBlitz will run this Astro project in the browser, outside of your local environment. It will also provide you with a shareable link so that any Astro maintainer or support squad member can view your minimal reproduction outside of their own local environment. This means that everyone is viewing the exact same project, with the same configuration and dependencies. This makes it easy for someone else to help troubleshoot your code. If the issue is reproducible, it allows you to verify that the issue lies within the Astro code itself and you can feel confident submitting a bug report.

请注意,并非每个问题都可以在 StackBlitz 中重现。例如,你的问题可能取决于特定环境或包管理器,或者可能涉及 StackBlitz 不支持的 HTML 流。在这种情况下,使用 CLI 创建一个新的最小(空)Astro 项目,重现问题,并将其上传到 GitHub 存储库。不要共享 StackBlitz URL,而是提供最小复制品的 GitHub 存储库的链接。

¥Note that not every issue is reproducible in StackBlitz. For example, your issue might be dependent on a specific environment or package manager, or it may involve HTML Streaming, which isn’t supported in StackBlitz. In this case, create a new minimal (empty) Astro project using the CLI, reproduce the issue, and upload it to a GitHub repository. Instead of sharing a StackBlitz URL, provide a link to the GitHub repository of your minimal reproduction.

¥Minimal code

设置空项目后,请执行重现问题的步骤。这可以包括添加包、更改配置和编写代码。

¥Once your empty project is set up, go through the steps to reproduce the issue. This can include adding packages, changing configuration, and writing code.

你应该只添加重现问题所需的最少量代码。不要重现现有项目的其他元素,并删除与问题不直接相关的所有代码。

¥You should only add the minimum amount of code necessary to reproduce the issue. Do not reproduce other elements of your existing project, and remove all code that is not directly related to the issue.

¥Create an issue

如果你的问题可以重现,那么就该创建问题并提交错误报告了!

¥If your issue can be reproduced, then it is time to create an issue and file a bug report!

转到 GitHub 上相应的 Astro 存储库并打开一个新问题。大多数存储库都有一个问题模板,会提出问题或需要信息才能提交。请务必遵循这些模板,因为如果你不提供我们需要的信息,那么我们就必须向你询问…并且没有人正在解决你的问题!

¥Go to the appropriate Astro repository on GitHub and open a new issue. Most repositories have an issue template that will ask questions or require information in order to submit. It’s important that you follow these templates because if you don’t provide the information we need, then we have to ask you for it… and no one is working on your issue!

包含 StackBlitz(或 GitHub 存储库,如果需要)上你的最小复制品的链接。首先描述预期行为与实际行为,为问题提供背景信息。然后,包含有关如何在 Astro 项目中复制问题的清晰的分步说明。

¥Include the link to your minimal reproduction on StackBlitz (or GitHub repository, if necessary). Start with a description of the expected versus actual behavior to provide context for the issue. Then, include clear, step-by-step instructions on how to replicate the issue in an Astro project.

¥Need more?

欢迎在 Discord 上与我们聊天,并在 #support 论坛通道中解释你的问题。我们总是很乐意提供帮助!

¥Come and chat with us on Discord and explain your issue in the #support forum channel. We’re always happy to help!

访问当前的 Astro 中的未决问题 查看你是否遇到已知问题或提交错误报告。

¥Visit the current open Issues in Astro to see if you are encountering a known problem or file a bug report.

你还可以访问 RFC 讨论 查看是否发现了 Astro 的已知限制,并检查是否有与你的用例相关的当前提案。

¥You can also visit RFC Discussions to see whether you’ve found a known limitation of Astro, and check to see whether there are current proposals related to your use case.

Astro 中文网 - 粤ICP备13048890号