跳转到内容

导入

Astro 无需配置即支持大多数静态资源。你可以在项目的任何地方使用 import 语句(包括 Astro frontmatter 脚本),Astro 将在最终构建中内置优化后的静态资源副本。在 CSS 和 <style> 标签中也可以使用 @import

下面的文件类型 Astro 开箱即用:

  • Astro 组件 (.astro)
  • Markdown (.md.markdown,等等)
  • JavaScript (.js.mjs)
  • TypeScript (.ts)
  • NPM 包
  • JSON (.json)
  • CSS (.css)
  • CSS 模块 (.module.css)
  • 图片和资源 (.svg.jpg.png,等等。)

此外,你可以扩展 Astro 以添加对不同 UI 框架的支持,如 React、Svelte 和 Vue 组件。你还可以安装 Astro MDX 集成并在项目中使用 .mdx 文件。

你可以将任何静态资源放在项目的 public/ 目录中,Astro 将直接将其复制到最终构建中,而不会对其进行任何处理。public/ 文件不会被 Astro 构建或打包,这意味着支持任何类型的文件。你可以在 HTML 模板中直接通过 URL 路径引用 public/ 文件。

Astro 使用 ESM,它是浏览器中支持的相同 importexport 语法。

import { getUser } from './user.js';

可以使用普通的 ESM importexport 语法来导入 JavaScript。它在 Node.js 和浏览器中和预期保持一致。

import { getUser } from './user';
import type { UserType } from './user';

Astro 内置对 TypeScript 的支持。你可以在 Astro 项目中直接导入 .ts.tsx 文件,甚至可以直接在 Astro 组件脚本和任意 hoisted script 标签 中编写 TypeScript 代码。

Astro 本身不进行任何类型检查。类型检查应该在 Astro 之外进行或由 IDE 或通过一个单独的脚本来处理。Astro VSCode 扩展 会自动为打开的文件中提供 TypeScript 提示和错误警告。或使用 astro check 命令 检查 Astro 文件的类型。

了解更多关于 Astro 中的 TypeScript 支持 的内容。

如果你安装了一个 NPM 包,你可以在 Astro 中导入它。

---
import { Icon } from 'astro-icon';
---

如果一个包使用了旧的格式发布,Astro 将尝试将包转换为 ESM,以便 import 语句可以正常工作。在某些情况下,你可能需要调整你的 vite 配置 以使其正常工作。

// 使用默认导入加载 JSON 对象
import json from './data.json';

Astro 支持直接在应用程序中导入 JSON 文件。导入文件会通过默认导入返回完整的 JSON 对象。

// 加载并将 'style.css' 注入到页面上。
import './style.css';

Astro 支持直接在应用程序中导入 CSS 文件。导入的样式没有暴露出口,但导入样式会自动将这些样式添加到页面中。它默认支持所有 CSS 文件,并且可以通过插件支持 CSS 编译语言,如 Sass & Less。

样式指南 中阅读有关高级 CSS 导入用例的更多信息,例如直接通过 URL 引用 CSS 文件,或将 CSS 作为字符串导入。
// 1. 将 './style.module.css' 转换为类名唯一、有范围的值。
// 2. 返回对象,并将原始类名映射到其最终范围值的。
import styles from './style.module.css';
// This example uses JSX, but you can use CSS Modules with any framework.
return <div className={styles.error}>Your Error Message</div>;

Astro 支持使用 [name].module.css 命名约定的 CSS 模块。像导入任何 CSS 文件一样,导入 CSS 会应用到页面。然而,CSS 模块默认导出特殊的 styles 对象,并将你的原始类名映射到唯一的标识符。

CSS 模块帮助你在前端强制执行组件样式隔离,并生成唯一的样式表类名。

import imgReference from './image.png'; // img === '/src/image.png'
import svgReference from './image.svg'; // svg === '/src/image.svg'
import txtReference from './words.txt'; // txt === '/src/words.txt'
// 这个例子使用 JSX,但你可以在任何框架下使用导入引用。
<img src={imgReference.src} alt="image description" />;

所有其他没有明确提到的资源可以通过 ESM 的 import 语句导入,并将返回最终构建中的资源引用连接。这对使用链接引用非 JS 资源很有用,比如创建一个带有 src 属性的图片元素指向该图片。

将图片放在 public/ 文件夹中也很有用,这在项目结构页面中有所解释。

有关附加 Vite 导入参数(例如 ?url?raw)的更多信息,请参阅 Vite 静态资源处理指南

别名可以用于创建简洁的导入。

别名有助于改善在项目中大量使用绝对或相对引用的体验。

src/pages/about/company.astro
---
import Button from '../../components/controls/Button.astro';
import logoUrl from '../../assets/logo.png?url';
---

在这个示例中,开发者需要理解 src/pages/about/company.astro, src/components/controls/Button.astrosrc/assets/logo.png 间的关系。如果移动了 company.astro 文件,那么这些导入也都需要更新。

你可以在 tsconfig.json 中添加导入别名。

tsconfig.json
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"@components/*": ["src/components/*"],
"@assets/*": ["src/assets/*"]
}
}
}

在这个配置更改完之后,开发服务器会自动重启。然后,你可以在项目中的任何地方使用这些别名进行导入:

src/pages/about/company.astro
---
import Button from '@components/controls/Button.astro';
import logoUrl from '@assets/logo.png?url';
---

VS Code 或其他编辑器会自动集成这些别名。

Astro.glob() 是一种一次性导入多个文件的方法。

Astro.glob() 只接受一个参数:一个相对的 glob 模式 匹配你想要导入的本地文件。它是异步的,并返回每个匹配文件的导出数组。

src/components/my-component.astro
---
// 导入`./src/pages/post/` 中所有以 `.md` 结尾的文件
const posts = await Astro.glob('../pages/post/*.md');
---
<!-- 把前 5 篇博客文章渲染成 <article> -->
<div>
{posts.slice(0, 4).map((post) => (
<article>
<h2>{post.frontmatter.title}</h2>
<p>{post.frontmatter.description}</p>
<a href={post.url}>Read more</a>
</article>
))}
</div>

使用 Astro.glob 导入的 Astro 组件的类型为 AstroInstance。你可以使用其 default 属性渲染每个组件实例:

src/pages/component-library.astro
---
// 导入`./src/components/` 中所有以 `.astro` 结尾的文件
const components = await Astro.glob('../components/*.astro');
---
<!-- 展示所有组件-->
{components.map((component) => (
<div>
<component.default size={24} />
</div>
))}

glob 模式是一个支持特殊通配符的文件路径。用于一次引用项目中的多个文件。

例如,glob 模式 ./pages/**/*.{md,mdx} 从 pages 子目录开始,查找其所有子目录(/**),并匹配以 .md.mdx 结尾的任何文件名(.{md,mdx})。

要与 Astro.glob() 一起使用,glob 模式必须是字符串字面量,并且不能包含任何变量。有关解决方法,请参阅故障排除指南

此外,glob 模式必须以以下之一开头:

  • ./(从当前目录开始)
  • ../(从父目录开始)
  • /(从项目根目录开始)

阅读更多关于 glob 模式语法

Astro.glob() vs getCollection()

段落标题 Astro.glob() vs getCollection()

内容集合 提供用于加载多个文件的 getCollection() API 代替 Astro.glob()。如果你的内容文件 (例如 Markdown, MDX, Markdoc) 位于src/content/ 目录内的集合中,使用 getCollection() 查询集合并返回内容条目。

// 加载并初始化所请求的 WASM 文件
const wasm = await WebAssembly.instantiateStreaming(fetch('/example.wasm'));

Astro 支持使用浏览器的 WebAssembly API 直接在应用程序中 WASM 文件。

我们鼓励 Astro 用户尽可能避免使用 Node.js 内置模块(fspath 等)。Astro 兼容多个运行时使用 适配器。这包括 DenoCloudflare Workers,它们不支持 Node 内置模块,例如 fs

我们致力于为常用的 Node.js 内置模块提供 Astro 化的替代品,不过现在还没有实现。因此,如果你真的需要,我们不会阻止你使用这些内置模块。Astro 支持使用较新 node: 前缀来支持 Node.js 内置模块。例如,如果你想读取一个文件,你可以这样做:

src/components/MyComponent.astro
---
// 示例:从 Node.js 中导入内置模块 "fs/promises"
import fs from 'node:fs/promises';
const url = new URL('../../package.json', import.meta.url);
const json = await fs.readFile(url, 'utf-8');
const data = JSON.parse(json);
---
<span>Version: {data.version}</span>

使用 Vite 和兼容的 Rollup 插件,你可以导入 Astro 原生不支持的文件类型。在 Vite 文档的 查找插件 部分了解你需要的插件。

贡献

你有什么想法?

社区