---
description: 在 Next 打包前构建持久化 MDX 缓存，再由 Turbopack 或 Webpack 共用的已校验 loader 读取。
---

# Next 16

Next 集成把编译和加载分开。配置包装器先构建内容集；bundler loader 再校验 `index.json`，
并从对应缓存记录返回编译模块。

## 要求

- 保持持久化缓存启用。`cache: false` 不会留下 loader 可读取的模块记录。
- 通过 Next import 的文件使用 `.mdx`。即使集合配置了其它后缀，内置 Turbopack 和 Webpack
  rule 仍固定为 `*.mdx`。
- 在[受支持的原生目标](/zh-CN/native-targets/)上运行 `next dev` 和 `next build`。

## 配置 Next

```ts
// next.config.ts
import { withAmamoMdx } from '@amamo/mdx/next'

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

export default withAmamoMdx(amamo)({
  reactStrictMode: true,
})
```

`withAmamoMdx(amamo)(nextConfig)` 返回异步 Next config 函数。之后由 Next 使用当前 phase 和
`{ defaultConfig }` 调用它；它不会立即返回已经解析的配置。

内层输入可以是配置对象、Promise 或配置函数：

```ts
import { withAmamoMdx } from '@amamo/mdx/next'

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

export default withAmamoMdx(amamo)(async (_phase, { defaultConfig }) => ({
  ...defaultConfig,
  images: {
    remotePatterns: [{ hostname: 'cdn.example.com', protocol: 'https' }],
  },
}))
```

包装器会 await 输入，保留其中的字段和已有 `webpack` callback，再加入自己的 Turbopack
与 Webpack rule。

## Phase 行为

| Phase                      | 准备工作                                            |
| -------------------------- | --------------------------------------------------- |
| `PHASE_DEVELOPMENT_SERVER` | 构建一次，然后启动编译器的递归 watcher。            |
| `PHASE_PRODUCTION_BUILD`   | 构建一次，不启动 watcher。                          |
| 其它 phase                 | 跳过构建和 watcher，但仍返回带 loader rule 的配置。 |

一次 wrapper 调用拥有一个延迟编译器和一个共享 build Promise。请在 Next config 中创建一次
wrapper，而不是为单个请求重复创建。

## Loader 流程

同一个 loader 会注册到：

- `turbopack.rules['*.mdx']`，并把输出声明为 JavaScript。
- Webpack 中 `test: /\.mdx$/` 的 module rule。

对于每个被 import 的源码路径，loader 会：

1. 读取 `<generatedDirectory>/index.json`。
2. 检查其中的配置指纹与 wrapper 当前的归一化配置一致。
3. 找到源码缓存键，并校验它是否为十六进制。
4. 读取对应 JSON 缓存记录。
5. 校验记录键并返回编译后的 `module` 字符串。

任何不一致都会以 `AMAMO_NEXT_CACHE_MISS` 拒绝，并要求执行协调构建。Loader 是只读的；解析、
Shiki、manifest 写入和缓存清理都由 wrapper 拥有的编译器完成。

## 导入 MDX

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

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

Turbopack 和 Webpack 读取相同的索引和记录格式。

## 开发期行为

在开发模式中，编译器会递归监听 `config.root`。属于集合的新增或修改会执行 `transform`，删除
已知记录会执行 `remove`。这会独立于 Next 的文件 watcher 刷新缓存和生成产物；两个 watcher
之间没有时序协调机制。

修改配置本身后请重启 `next dev`。调用 `withAmamoMdx(amamo)` 时，wrapper 的归一化配置、
指纹和 loader 选项就已经固定。

## 故障排查

| 现象                    | 检查项                                                                        |
| ----------------------- | ----------------------------------------------------------------------------- |
| `AMAMO_NEXT_CACHE_MISS` | 缓存已启用、启动构建已完成，并且 loader 使用同一个 `generatedDirectory`。     |
| 配置指纹不一致          | 修改配置后重启 Next；必要时删除旧生成产物。                                   |
| 自定义后缀没有被转换    | 改为 `.mdx` 或自行提供 Next loader；内置 rule 是固定的。                      |
| 原生绑定不可用          | 在[受支持目标](/zh-CN/native-targets/)上重新安装，而不是复制 `node_modules`。 |
