---
description: 执行完整启动构建，直接转换被 import 的 MDX，并在开发时保持生成元数据最新。
---

# Vite 8

`amamoMdx` 会为一个 Vite 插件实例延迟创建一个编译器。Vite 管理模块 transform 和文件系统
事件；编译器管理已校验记录、manifest 和生成的集合文件。

## 配置插件

```ts
// vite.config.ts
import { amamoMdx } from '@amamo/mdx/vite'
import { defineConfig } from 'vite'

import amamo from './amamo.config.mjs'

export default defineConfig({
  plugins: [amamoMdx(amamo)],
})
```

插件声明了 `enforce: 'pre'` 和 `sharedDuringBuild: true`。当 Vite 多环境构建启用共享插件时，
client 和 SSR 环境会使用同一个插件编译器，而不是分别编译整套内容。

## 导入文档

```tsx
import Post, { frontmatter } from './content/posts/hello.mdx'

export function Page() {
  return (
    <article>
      <h1>{frontmatter.title}</h1>
      <Post />
    </article>
  )
}
```

对于属于集合的文件，`transform` hook 会忽略传入的源码字符串，向编译器请求当前 JavaScript
模块。Vite 收到代码前，frontmatter 已通过校验，Markdown 媒体已被重写，启用的 Shiki 结果
也已注入。

## 生命周期

| Vite hook 或事件            | 编译器操作                             |
| --------------------------- | -------------------------------------- |
| `buildStart`                | 执行一次完整 `build()`。               |
| `transform`                 | 对属于集合的文件执行 `transform(id)`。 |
| 开发服务器 `add` / `change` | 转换路径并刷新生成产物。               |
| 开发服务器 `unlink`         | 删除已知记录并刷新生成产物。           |
| 开发 HTTP server `close`    | 移除 watcher handler 并释放编译器。    |

第一次启动调用会被共享，因此重复的 build hook 不会启动多次完整构建。之后的编译器操作仍会
串行执行。

## 开发期更新

当新增、修改或删除导致至少一个生成产物变化时，插件会在 Vite module graph 中找到并失效
`collections.mjs`，然后发送 full reload。目前还没有单文档级的 HMR 边界。

Watcher 编译失败会发送到 Vite logger 和错误 overlay。`AMAMO_MEDIA_MISSING` 这样的成功记录
warning 只保存在 `record.diagnostics` 中，插件不会打印它们。

## 生成的集合

应用代码可以导入生成注册表：

```ts
import { collections } from './.amamo-mdx/collections.mjs'

const published = collections.posts.filter((document) => !document.frontmatter.draft)
```

每个注册项都包含元数据和 `load: () => import(originalMdxPath)`。Vite 会让这个延迟 import
继续通过同一个插件。插件不读取 `index.json`；这个私有索引只供 Next loader 使用。

## 生产构建

`vite build` 执行同样的完整启动构建和逐 import transform。字节未变化的产物会保留修改时间，
让下游工具避免无效工作。

只有在可以接受重复原生/Shiki 工作时才设置 `cache: false`。与 Next 适配器不同，Vite 没有
持久化记录也能完成 transform。

## 当前限制

- 生成产物变化会触发 full reload。
- 插件不会打印 `IBuildResult`；需要报告时请使用直接[编译器 API](/zh-CN/compiler-api/)。
- 每次调用插件都会拥有独立编译器状态；同一份内容配置只注册一次插件。
