diff --git a/src/content/docs/zh-cn/reference/experimental-flags/fonts.mdx b/src/content/docs/zh-cn/reference/experimental-flags/fonts.mdx index 59bc6a7d02e1b..a1936e3a582fc 100644 --- a/src/content/docs/zh-cn/reference/experimental-flags/fonts.mdx +++ b/src/content/docs/zh-cn/reference/experimental-flags/fonts.mdx @@ -82,7 +82,7 @@ body { }); ``` - 更多可用的配置选项,例如定义 [回退字体](#fallbacks) 和 下载哪种 [`weights`](#weights) 以及 [`styles`](#styles),将会基于你所选定的提供商有所不同。 + 更多可用的配置选项,例如定义 [回退字体](#fallbacks) 和 下载哪种 [`weights`](#weights)、 [`styles`](#styles) 和 [`subsets`](#subsets),将会基于你所选定的提供商有所不同。 查看完整的 [配置参考](#字体配置参考),以了解更多。 @@ -152,13 +152,16 @@ body { ## 可用的远程字体提供商 -Astro 重新导出了大部分 [unifont](https://github.com/unjs/unifont/) 的字体提供商模块。以下为内置支持的提供商: +Astro 基于 [unifont](https://github.com/unjs/unifont/) 提供商,导出了一些内置的字体提供商。你也可以[创建自定义的 Astro 字体提供商](#创建自己的字体提供商)。 + +以下为内置支持的提供商: - [Adobe](https://fonts.adobe.com/) - [Bunny](https://fonts.bunny.net/) - [Fontshare](https://www.fontshare.com/) - [Fontsource](https://fontsource.org/) - [Google](https://fonts.google.com/) +- [Google Icons](https://fonts.google.com/icons) 要使用内置的远程提供商,请为你所选定的字体提供商选择合适的值,来配置 `provider`: @@ -167,9 +170,11 @@ Astro 重新导出了大部分 [unifont](https://github.com/unjs/unifont/) 的 ```js -provider: fontProviders.adobe({ id: process.env.ADOBE_ID }) +provider: fontProviders.adobe({ id: 'your-id' }) ``` +可以通过[在 Astro 配置文件中设置环境变量](/zh-cn/guides/environment-variables/#在-astro-配置文件中)传递你的 Adobe 字体提供商 ID。 + @@ -202,7 +207,7 @@ provider: fontProviders.fontsource() provider: fontProviders.google() ``` -另外,`google()` 字体提供商接受 [unifont Google `ProviderOption`](https://github.com/unjs/unifont/blob/main/src/providers/google.ts#L10-L26) 的所有可用选项: +另外,`google()` 字体提供商接受 [unifont Google provider](https://github.com/unjs/unifont/#options-1) 的所有可用选项: ```js provider: fontProviders.google({ @@ -214,9 +219,29 @@ provider: fontProviders.google({ - + + +

+ +

+ +```js +provider: fontProviders.googleicons() +``` -你也可以使用任意的 unifont 提供商 [创建自定义 Astro 字体提供商](#创建自己的字体提供商)。 +另外,`googleicons()` 字体提供商接受 [unifont Google Icons options](https://github.com/unjs/unifont/#options-2) 的所有可用选项: + +```js +provider: fontProviders.googleicons({ + glyphs: { + "Material Symbols Outlined": ["arrow_right", "favorite", "arrow_drop_down"] + } +}) +``` + +
+ + ## 用法示例 @@ -228,13 +253,14 @@ export default defineConfig({ fonts: [ { name: "Roboto", - cssVariable: "--font-roboto" + cssVariable: "--font-roboto", provider: fontProviders.google(), // 默认包含项: // weights: [400] , // styles: ["normal", "italics"], - // subsets: ["cyrillic-ext", "cyrillic", "greek-ext", "greek", "vietnamese", "latin-ext", "latin"], + // subsets: ["latin"], // fallbacks: ["sans-serif"], + // formats: ["woff2"], }, { name: "Inter", @@ -245,14 +271,16 @@ export default defineConfig({ // 指定实际应用的字体样式 styles: ["normal"], // 仅为页面上使用的字符下载字体文件 - subsets: ["cyrillic"], + subsets: ["latin", "cyrillic"], + // 下载更多字体格式 + formats: ["woff2", "woff"], }, { name: "JetBrains Mono", cssVariable: "--font-jetbrains-mono", provider: fontProviders.fontsource(), // 仅为页面上使用的字符下载字体文件 - subsets: ["latin"], + subsets: ["latin", "latin-ext"], // 使用与预期外观相匹配的回退字体系列 fallbacks: ["monospace"], }, @@ -311,7 +339,7 @@ import { Font } from 'astro:assets';

-**类型:** `boolean`
+**类型:** `boolean | { weight?: string | number; style?: string; subset?: string }[]`
**默认值:** `false`

@@ -325,6 +353,36 @@ import { Font } from 'astro:assets'; ``` +通过 `preload` 指令,浏览器将在页面加载期间立即开始下载所有可能的字体的链接。 + +#### 细粒度预加载 + +

+ +

+ +你可能并不总是希望预加载所有字体链接,因为这可能会阻塞其他重要资源的加载,或者下载当前页面不需要的字体。 + +为了更精细地控制哪些字体文件会被预加载,你可以提供一个对象数组,用来描述需要预加载的字体特征组合,例如字体的 `weight`(字重)、`style`(样式)或 `subset`(子集)。 + +下面的示例只会预加载只会预加载 `latin` 子集中,字重为 `400` 或样式为 `normal` 的字体文件: + +```astro title="src/components/Head.astro" {7-10} +--- +import { Font } from 'astro:assets'; +--- + + +``` + +对于可变字重(variable weight)的字体文件,只要其字重范围中包含了被请求的字重,就会被预加载。例如,字重范围为 `100 900` 的字体文件,在 `preload` 对象中指定了 `400` 时,就会被包含在内。 + ## 以编程方式访问字体数据 `getFontData()` 函数旨在通过编程方式获取更底层的字体数据,例如在 [API 路由](/zh-cn/guides/endpoints/#服务器端点api-路由) 中使用,或用于生成自定义的元标签。 @@ -394,7 +452,7 @@ export default defineConfig({

-**类型:** `AstroFontProvider | "local"` +**类型:** `FontProvider | "local"`

字体文件的来源。你可以使用 [内置提供商](#可用的远程字体提供商) 来编写你自己的 [自定义提供商](#创建自己的字体提供商),或者是通过将该项设置为 `"local"` 来使用本地字体文件: @@ -477,9 +535,9 @@ optimizedFallbacks: false ### 远程字体属性 -远程字体可使用进一步配置选项来进行配置。通过设置这些选项来自定义这些由 [字体提供商](#可用的远程字体提供商) 所加载的数据,例如仅下载特定的字重和字体样式。 +远程字体可使用进一步配置选项来进行配置。通过设置这些选项来自定义这些由 [字体提供商](#可用的远程字体提供商) 所加载的数据,例如仅下载特定的字重和字体样式。如需更精细的控制,可参考[详细远程字体配置](#细粒度远程字体配置)。 -在底层实现中,这些选项均由 [unifont](https://github.com/unjs/unifont/) 处理。部分属性可能不被某些字体提供商所支持,而不同提供商对同一属性的实现方式也可能不同。 +每个字体提供商负责处理这些配置项,因此以下属性的可用性和支持情况可能因提供商而异。 #### weights @@ -520,7 +578,7 @@ styles: ["normal", "oblique"]

**类型:** `string[]`
-**默认值:** `["cyrillic-ext", "cyrillic", "greek-ext", "greek", "vietnamese", "latin-ext", "latin"]` +**默认值:** `["latin"]`

定义 [字体子集](https://knaap.dev/posts/font-subsetting/),用以预加载。 @@ -529,6 +587,21 @@ styles: ["normal", "oblique"] subsets: ["latin"] ``` +#### formats + +

+ +**类型:** `("woff2" | "woff" | "otf" | "ttf" | "eot")[]`
+**默认值:** `["woff2"]` + +

+ +一个包含 [字体格式](https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/At-rules/@font-face/src#font_formats) 的数组: + +```js +formats: ["woff2", "woff"] +``` + #### display

@@ -756,84 +829,201 @@ export default defineConfig({ }); ``` +## 细粒度远程字体配置 + +

+ + +

+ +一个字体族(font family)通常由多种属性组合定义而成,例如字重(weights)和样式(styles)(例如:`weights: [500, 600]` 和 `styles: ["normal", "bold"]`)。但有时你可能只想下载这些属性的某些组合。 + +为了更精确地控制需要下载哪些字体文件,你可以 多次声明同一个字体(即具有相同的 `cssVariable`、`name` 和 `provider` 属性),但使用不同的属性组合。Astro 会合并这些结果,并且只下载所需的文件。例如,你可以仅下载常规样式的 `500` 和 `600` 字重,但只下载斜体的 `500` 字重: + +```js +// astro.config.mjs +import { defineConfig, fontProviders } from "astro/config" + +export default defineConfig({ + experimental: { + fonts: [ + { + name: "Roboto", + cssVariable: "--roboto", + provider: fontProviders.google(), + weights: [500, 600], + styles: ["normal"] + }, + { + name: "Roboto", + cssVariable: "--roboto", + provider: fontProviders.google(), + weights: [500], + styles: ["italic"] + } + ] + } +}) +``` + ## 创建自己的字体提供商 -如果你不想局限于使用任一的 [内置提供商](#可用的远程字体提供商)(例如:你想使用第三方 unifont 提供商,或是创建一些运用于私人仓库的内容),那么你便可以创建自己的字体提供商。 +如果你不想局限于使用任一的 [内置提供商](#可用的远程字体提供商)(例如,你想使用[第三方 unifont 提供商](#支持第三方-unifont-提供商),或为[私有注册表构建某些内容](#支持私有注册表)),那么你便可以创建自己的字体提供商。 -每一个 Astro 字体提供商都是由两个部分所构成:配置对象(config object)和实际实现(actual implementation)。 +实现自定义字体提供商的推荐方式是导出一个函数,该函数接收[配置](#config)作为参数,并返回一个 [`FontProvider` 对象](#字体提供商对象)。 - +### 字体提供商对象 -1. 使用 `defineAstroFontProvider()` 类型助手函数,创建一个函数用于返回字体提供商的配置对象所含的内容: +实验性字体 API 允许你以统一的方式访问字体。每个字体族需通过一个 Astro 字体提供商来获取对应的字型(font face)。 - - `entrypoint`:可以是 URL,一个相对于根目录的相对路径,或是一个包的导入。 - - `config`:一个可选的序列化对象,它会被传入 unifont 提供商。 +`FontProvider` 是一个对象,包含必需的 [`name`](#name-1) 和 [`resolveFont()`](#resolvefont) 属性,同时还可以选择性地提供 [`config`](#config)、[`init()`](#init) 以及 [`listFonts()`](#listfonts) 属性。 - +#### `name` - +

- ```ts title="provider/config.ts" - import { defineAstroFontProvider } from 'astro/config'; +**类型:** `string` +

- export function myProvider() { - return defineAstroFontProvider({ - entrypoint: new URL('./implementation.js', import.meta.url) - }); - }; - ``` +提供商的唯一名称,用于日志记录和标识。 -
+#### `resolveFont()` - +

- ```ts title="provider/config.ts" - import { defineAstroFontProvider } from 'astro/config'; +**类型:** `(options: ResolveFontOptions) => Awaitable<{ fonts: FontFaceData[] } | undefined>`
+

- interface Config { - // ... - }; +用于检索并返回基于给定选项的字型数据。 - export function myProvider(config: Config) { - return defineAstroFontProvider({ - entrypoint: new URL('./implementation.js', import.meta.url), - config - }); - }; - ``` +#### `config` -
+

- +**类型:** `Record`
+**默认值:** `undefined` +

-2. 创建第二个文件,用以导入 unifont `provider` 实现: +一个可序列化的对象,用于标识。 - ```ts title="implementation.ts" - import { defineFontProvider } from "unifont"; +#### `init()` - export const provider = defineFontProvider("my-provider", async (options, ctx) => { - // 获取/定义你的自定义字体 - // ... - }); - ``` +

- :::tip +**类型:** `(context: FontProviderInitContext) => Awaitable`
+**默认值:** `undefined` +

- 你可以翻阅 [unifont 提供商们的源码](https://github.com/unjs/unifont/blob/main/src/providers/),从而了解如何创建一个 unifont 提供商。 +可选的回调,用于执行任何初始化逻辑。其上下文包含一个 `storage` 对象,便于缓存。 - ::: +#### `listFonts()` -3. 向你的字体配置文件中,添加你自定义的提供商。 +

- ```js title="astro.config.mjs" ins="myProvider()" - fonts: [{ - provider: fontProviders.myProvider(), - name: "Custom Font", - cssVariable: "--font-custom" - }] - ``` +**类型:** `() => Awaitable`
+**默认值:** `undefined` +

-
+可选的回调,用于返回可用字体名称列表。 + +### 支持私有注册表 + +下面的示例定义了一个用于私有注册表的字体提供商: + +```ts title="font-provider.ts" +import type { FontProvider } from "astro"; +import { retrieveFonts, type Fonts } from "./utils.js", + +interface Config { + token: string; +} + +export function registryFontProvider(config: Config): FontProvider { + let data: Fonts = {} + + return { + name: "registry", + config, + init: async () => { + data = await retrieveFonts(token); + }, + listFonts: () => { + return Object.keys(data); + }, + resolveFont: ({ familyName, ...options }) => { + const fonts = data[familyName]; + if (fonts) { + return { fonts }; + } + return undefined; + }, + }; +} +``` + +你可以在 Astro 配置中注册此字体提供商: + +```ts title="astro.config.ts" +import { defineConfig } from "astro/config"; +import { registryFontProvider } from "./font-provider"; + +export default defineConfig({ + experimental: { + fonts: [{ + provider: registryFontProvider({ + token: "..." + }), + name: "Custom", + cssVariable: "--font-custom" + }] + } +}); +``` + +### 支持第三方 unifont 提供商 + +你可以定义一个 Astro 字体提供商,底层使用 unifont 提供商: + +```ts title="font-provider.ts" {3,5,6} +import type { FontProvider } from "astro"; +import type { InitializedProvider } from 'unifont'; +import { acmeProvider, type AcmeOptions } from '@acme/unifont-provider' + +function acmeFontProvider(config?: AcmeOptions): FontProvider { + const provider = acmeProvider(config); + let initializedProvider: InitializedProvider | undefined; + return { + name: provider._name, + config, + async init(context) { + initializedProvider = await provider(context); + }, + async resolveFont({ familyName, ...rest }) { + return await initializedProvider?.resolveFont(familyName, rest); + }, + async listFonts() { + return await initializedProvider?.listFonts?.(); + }, + }; +} +``` + +你可以在 Astro 配置中注册此字体提供商: + +```ts title="astro.config.ts" +import { defineConfig } from "astro/config"; +import { acmeFontProvider } from "./font-provider"; + +export default defineConfig({ + experimental: { + fonts: [{ + provider: acmeFontProvider({/* ... */}), + name: "Custom", + cssVariable: "--font-custom" + }] + } +}); +``` ## 缓存