# @ecopages/content-processor 中文文档

规范地址：https://npmcn.com/package/%40ecopages/content-processor/

版本：0\.7\.1
npm 元数据更新时间：2026-11-12T23:40:42.742Z
中文译文更新时间：2026-11-13T06:15:05.848Z
软件包许可：MIT

本文由上游 README 翻译，可能存在偏差，请结合原文核对 API、命令与配置。版权与许可归原作者所有。

原始 npm 页面：https://www.npmjs.com/package/%40ecopages/content-processor
原文对照：https://npmcn.com/package/%40ecopages/content-processor/?lang=original
源码仓库：https://github.com/ecopages/ecopages

## 关键信息（来自 npm 元数据）

- 包体积（解压后）：113 kB，33 个文件
- 模块格式：ES Module
- TypeScript 类型：包内自带
- Node.js 要求：^24\.22\.0 \|\| \>=26\.0\.0
- 运行依赖：6 个
- peer 依赖：@ecopages/core 0\.7\.1
- 首次发布：2026-07-14T14:34:30.474Z
- 最新版本发布：2026-11-12T23:40:42.376Z
- 近 30 天下载量：3319（2026-10-13 至 2026-11-11，npm 官方下载统计）
- 已发布版本数：46（近 12 个月 46 个）

## 中文简介

在构建时扫描 MDX 收藏并曝光打入的生态页面:内容/\* 网页和脚本的虚拟模块

## 安装

```sh
npm install @ecopages/content-processor
```

也可以使用：`pnpm add @ecopages/content-processor`、`yarn add @ecopages/content-processor`、`bun add @ecopages/content-processor`

## README

# @ coupages/content-处理器

Ecopages的构建时间内容收藏. 在构建时间扫描MDX(或其他已配置的扩展),验证前题,并曝光每个收藏作为打入的虚拟模块: `ecopages:content/<collection>`。 。 。 .

## 心理模式

捐款使用一个 `plugins(app)` 方法。 收集模块和类型生成于 `setup()`,而一个能解决收藏的建筑首先等待同代. `ecopages build` 向 `dist/server/` 并登记在 `server-modules.json`生产 `ecopages start` 从地图恢复,不调用 `setup()`。当编辑 MDX 文件时,开发仍然会重新生成收藏。 服务器解析器和浏览器解析器声明单独的环境,因此浏览器编译无法通过注册命令选择服务器执行.

1.  **申报收藏** 内 `eco.config.ts` ——内容目录,前题计划,和排序顺序.
2.  **构建时扫描** – 处理器验证前题并写入生成的模块 `.eco/cache/`无效的前题失败 `ecopages build`而不是第一个请求。 制作复制汇编的收集模块 `dist/server/`。 。 。 .
3.  **导入虚拟模块** ——使用页和版式 `ecopages:content/<collection>` 页:1 `entries`,元数据,以及MDX组件.
4.  **拥有你的前题** - 以任意 [标准Schema](https://standardschema.dev/)\-相容图书馆(佐德,瓦利博特,ArkType等). 处理器添加 `slug` 财务报告和审定财务报表 `segments` 从文件路径.

### 这个软件包拥有什么

| 层 | 拥有者 |
| :-- | :-- |
| 文件发现、 前题验证、 显示排序 | `@ecopages/content-processor` |
| 已生成 `ecopages:content/*` 模块`entries`, (中文(简体) ), `getComponent`, (...) (中文(简体) ) | `@ecopages/content-processor` |
| `ContentScanner` 用于发布应用程序脚本 `llms.txt` | `@ecopages/content-processor` |
| 路线`eco.page`),布局,元数据,URL形状 | 你的应用 |
| 面条、面包屑、花纹 | 你的应用程序——来自 `entries` 和前题字段,例如 `title`, (中文(简体) ), `group`,以及 `order` |

处理器在构建时会给您一个打入的列表和MDX组件. 以你对其它数据来源的同样方式 将它们连接到Ecopage的路径和UI中.

## 特征

-   **构建时间扫描** ——内容元数据在页面捆绑船前解决;MDX入门模块按服务器上每发子弹的要求加载.
-   **标准Schema验证** ——前题计划留在您的应用程序中;库通过标准Schema接口验证.
-   **输入的虚拟模块** —— 说 `ecopages:content/<collection>` 生成 `Entry` 类型.
-   **多个收藏** —docs, blog, changelog, 或任何您配置的按键收藏 .
-   **`ContentScanner`** ——在一次性构建脚本中再用相同的扫描/验证路径. 扫描器不写 `llms.txt`;应用程序脚本有.

在开发过程中,编辑到一个条目的 MDX 机构会使其编译的服务器收藏捆绑无效,即使其前题和生成的显示没有变化. 下一个请求重建了这个捆绑,使新的身体.

内容处理器拥有已编译的收藏文物及其无效生成. Core提供共享的服务器-模块构建路径;收集身份,源跟踪,并缓存寿命与内容处理器同住.

在一个收藏目录中共同设置非输入文件( 例如) `survey-form.config.ts`,帮助模块,或JSON数据)也使已编译的服务器集无效而无需重写生成的条目列表.

## 安装

```bash
bun add @ecopages/content-processor
```

同伴依赖 : `@ecopages/core`。 。 。 .

## 配置

将处理器注册到 `eco.config.ts`数字 :

```typescript
import { defineConfig } from '@ecopages/core/config';
import { contentProcessorPlugin } from '@ecopages/content-processor/plugin';
import { compareEntriesByField } from '@ecopages/content-processor';
import { blogFrontmatterSchema } from './src/content/blog-schema';
import { docsFrontmatterSchema } from './src/content/docs-schema';

export default defineConfig({
    processors: [
        contentProcessorPlugin({
            options: {
                collections: {
                    docs: {
                        contentDir: 'content/docs',
                        orderBy: compareEntriesByField('order'),
                        schema: docsFrontmatterSchema,
                        entryType: './src/content/docs-schema#DocsFrontmatter',
                    },
                    blog: {
                        contentDir: 'content/blog',
                        orderBy: compareEntriesByField('title'),
                        schema: blogFrontmatterSchema,
                        entryType: './src/content/blog-schema#BlogFrontmatter',
                        extensions: ['.mdx', '.md'],
                    },
                },
            },
        }),
    ],
});
```

### 收藏选项

| 选项 | 需求 | 说明 |
| :-- | :-- | :-- |
| `contentDir` | 对 | 相对于应用的目录 `srcDir`,比如说. `content/docs`。 。 。 . |
| `schema` | 对 | 前题的标准Schema验证器 . |
| `entryType` | 没有 | 用于生成的虚拟模块类型的前题类型 。 格式 : `./path/to/schema#TypeName`。处理器将其包装为 `ContentEntry<YourFrontmatter>`。 。 。 . |
| `orderBy` | 没有 | 显示排序的比较函数 。 默认 :\\\\ link 比较 EntertriesBySlug}. 对前题字段使用 QQlink 比较 EnterriesBy Field . |
| `extensions` | 没有 | 需要扫描的文件扩展名 。 默认 : `['.mdx']`多点扩展`.radiant.mdx`, (中文(简体) ), `.react.mdx`)与最长的顺序匹配;声明令无关. |
| `routePrefix` | 没有 | 条目的公共 URL 前缀, 例如 . `/docs`用于 `devPrewarm`。 。 。 . |
| `devPrewarm` | 没有 | 预温 : `'first'`, (中文(简体) ), `'all'`, (中文(简体) ), `{ slugs }`,或 `{ limit }`. HMR 已准备好的管道存在之后的 SSR 核心预温; 预温时间表只生成且不控制 HTML 缓存录入 . |

收藏密钥必须是 kebab 大小写 (`docs`, (中文(简体) ), `api-reference`) (中文(简体) ). 每个键变成 `ecopages:content/<key>`。 。 。 .

## 前事计划(应用程序)

在应用程序中定义策略和前题类型 。 Zod 4是一个常见的选择:

```typescript
// src/content/docs-schema.ts
import { z } from 'zod';

export const docsFrontmatterSchema = z.object({
    title: z.string(),
    description: z.string(),
    group: z.string().optional(),
    order: z.coerce.number().optional(),
});

export type DocsFrontmatter = z.infer<typeof docsFrontmatterSchema>;
```

**重要内容:** 不添加 `slug` 或者说 `segments` 你的计谋。 处理器从文件路径中获取并曝光它们 `ContentEntry<T>`数字 :

```typescript
import type { ContentEntry } from '@ecopages/content-processor';

type DocsEntry = ContentEntry<DocsFrontmatter>;
// DocsEntry includes: title, description, group?, order?, slug, segments
```

点 `entryType` 地点 **前题类型** (单位:千美元)`DocsFrontmatter`),不是手卷式输入类型.

## 类型脚本设置

在应用程序中添加一个导入 `modules.d.ts`数字 :

```typescript
import '@ecopages/content-processor/types';
```

也就是说 `ecopages:content/*`, (中文(简体) ), `/server`,以及 `/component` 立即解决进口问题. 收集的具体声明在编程/构建时间生成到 `node_modules/@types/ecopages-content-processor`,哪些类型脚本自动加载.

运行 `ecopages dev` 或者说 `ecopages build` 在等待精确的收集条目类型之前。 重新启动 TypeScript 服务器,如果生成的类型在更改了计划或收藏配置后看起来是 stale .

## 虚拟模块 API

每个收藏都曝光 `ecopages:content/<collection>` 元数据, `ecopages:content/<collection>/server` 仅用于服务器依赖性发现,以及 `ecopages:content/<collection>/component` 对于在服务器和浏览器上工作的懒惰的MDX组件加载器:

```typescript
import { entries, getEntry, getEntryBySegments } from 'ecopages:content/docs';
import { getComponent, getEntryDependencies } from 'ecopages:content/docs/server';
import { loadComponent } from 'ecopages:content/docs/component';
import type { Entry } from 'ecopages:content/docs';
```

| 导出 | 模块 | 说明 |
| :-- | :-- | :-- |
| `entries` | 条目 | 只读所有条目的列表,按 `orderBy`。 。 。 . |
| `getEntry(slug)` | 条目 | 通过联合弹道搜索,例如:. `'getting-started/intro'`投篮 `HttpError.NotFound` 当失踪. |
| `getEntryBySegments(segments)` | 条目 | 按段数组查询,例如:. `['getting-started', 'intro']`投篮 `HttpError.NotFound` 当失踪. |
| `getComponent(slug)` | 服务器 | `Promise` 用于输入的 MDX 组件(每发子弹装入液态)。 拒绝使用 `HttpError.NotFound` 当失踪. |
| `getEntryDependencies(slug)` | 服务器 | 回返 `{ components: [entry] }` 所以收集会走 MDX 身份。 不复制依赖包。 掷出 `HttpError.NotFound` 当失踪. |
| `loadComponent(slug)` | 组件 | `Promise` 用于条目的 MDX 组件。 服务器图:为交叉集成渲染所包裹的条目. 页面浏览器图:由浏览器编译的条目. 拒绝使用 `HttpError.NotFound` 当失踪. `loadComponent.collection` 是收藏名称,当HMR再次评价页面时,它保持不变。 与 `createLazyCollectionComponents()` 从 `@ecopages/react/lazy-collection-components` 当一个可水合反应页面生成组件时. |
| `Entry` | 条目 | **仅输入.** `ContentEntry<YourFrontmatter>` 前题字段加 `slug` 财务报告和审定财务报表 `segments`。 。 。 . |

`/component` 是一个有两项决议的规格。 服务器图形以相同的服务器模块备份它 `/server`,因此,一个导入它的页,每个弹片共享一个组件 `getComponent()`。在同样加载浏览器中的条目的Pages中使用它,例如可水合反应页面. `/component` 没有发现资产:需要该条目自己的资产返回的页面 `getEntryDependencies()` 从 `/server`。页面浏览器 Graph 将其与浏览器加载器相背并仍然拒绝 `/server`因此导入 `/component` 从未使服务器代码浏览器可访问 .

**重要内容:** `Entry` 仅存在于生成中 `.d.ts` 文件,不是运行时缓存模块。 将类型导入单独保存 `import type` 在被捆绑的页面文件中的行。 混合进口如 `import { entries, type Entry }` 会导致捆绑者治疗 `Entry` 作为运行时间导出并失败 `MISSING_EXPORT`。 。 。 .

## 页面使用量

定义全程或每入场路线 `eco.page`从虚拟模块中导入收藏清单和MDX组件 :

```typescript
import { eco } from '@ecopages/core';
import { entries, getEntryBySegments } from 'ecopages:content/docs';
import { getComponent, getEntryDependencies } from 'ecopages:content/docs/server';
import type { Entry } from 'ecopages:content/docs';

export default eco.page<{ entry: Entry }>({
    staticPaths: async () => ({
        paths: entries.map((post) => ({
            params: { slug: post.segments },
        })),
    }),
    staticProps: async ({ pathname }) => {
        const segments = Array.isArray(pathname.params.slug)
            ? pathname.params.slug
            : [pathname.params.slug];

        return {
            props: { entry: getEntryBySegments(segments) },
        };
    },
    dependencies: async ({ props }) => getEntryDependencies(props.entry.slug),
    metadata: ({ props: { entry } }) => ({
        title: entry.title,
        description: entry.description,
    }),
    render: async ({ entry }) => {
        const Content = await getComponent(entry.slug);
        return <Content />;
    },
});
```

返回时 `getEntryDependencies` 仅当页面本身没有相对资产时。 合并本地页面 `scripts`, (中文(简体) ), `stylesheets`,或 `modules` 与 `mergePageDependencies()` 所以每个文件都有所有权.

### 水相反应页面

当反应页必须将 MDX 组件保存在水合树上时, 请从中创建一个懒惰组件 `/component` 装填器并装入 `<Suspense>` 边界。 服务器在HTML中等待该条目并发送;水合物在浏览器装入该条目之前保留了HTML. `getEntryDependencies()` 仍然仅保留服务器,并从 Page 浏览器图形中剥离。 在开发中,Page模块的HMR使已经装入的条目在不使用悬存倒计时的情况下再次被加载,一个经过编辑的MDX文件在不重新装入文档的情况下重新发送该条目.

```tsx
import { Suspense } from 'react';
import { createLazyCollectionComponents } from '@ecopages/react/lazy-collection-components';
import { getEntry } from 'ecopages:content/docs';
import { loadComponent } from 'ecopages:content/docs/component';
import { getEntryDependencies } from 'ecopages:content/docs/server';

const docs = createLazyCollectionComponents(loadComponent);

export default eco.page({
    staticProps: async ({ pathname }) => ({ props: { entry: getEntry(pathname.params.slug) } }),
    dependencies: ({ props }) => getEntryDependencies(props.entry.slug),
    render: ({ entry }) => {
        const Content = docs.get(entry.slug);
        return (
            <Suspense fallback={null}>
                <Content />
            </Suspense>
        );
    },
});
```

将边界保留在页中的固定位置。 在客户端在条目之间的导航过程中,React将当前条目保留在屏幕上,直到下一个条目被加载,只要每个弹出时边界不被重挂.

未知弹出 `HttpError.NotFound`,所以包罗万象 匹配 `/docs/[...slug]` 仍然服务于应用404页,而不是500页.

内容 MDX 条目可能导入交互演示和样式而无需手写 `config.dependencies` 包装 MDX加载器发现了它们:

```mdx
import { WeatherApp } from '@/components/weather-app/weather-app';
import './weather-app.css';

# Weather app

<WeatherApp />
```

`getComponent()` 懒散地装入每发一发MDX模块,并返回带有加载器属性的默认组件 `config` 页:1 说对了 `getEntryDependencies()` 因此只有活动条目为页面浏览器图表提供内容.

`getEntryDependencies(slug)` 返回时 `{ components: [entry] }`它没有复制 `config.dependencies` 未设置 `ownerFile`相对 `scripts`, (中文(简体) ), `stylesheets`,以及 `modules` 在MDX模块上宣布的解析来自该组件的特性,而不是包罗万象的路径.

将 Page- 本地相对资产与 `mergePageDependencies()`。两袋副本的物体分布 `ownerFile` 进入对方的相对路径 :

```typescript
import { eco, mergePageDependencies } from '@ecopages/core';
import { getComponent, getEntryDependencies } from 'ecopages:content/posts/server';

export default eco.page({
    dependencies: async ({ props }) =>
        mergePageDependencies({ stylesheets: ['./post.css'] }, await getEntryDependencies(props.slug)),
    render: async ({ slug }) => {
        const Content = await getComponent(slug);
        return <Content />;
    },
});
```

## 导航( 负面)

导航是应用代码. 地图 `entries` 连接到使用前题和路径字段的链接

```typescript
import { entries } from 'ecopages:content/docs';

export const docsNav = entries.map((entry) => ({
    title: entry.title,
    href: `/docs/${entry.segments.join('/')}`,
}));
```

在您的应用程序中分组或排序, 例如: `group` 前题字段和一个 `order` 编号。 见 `apps/docs` (单位:千美元)`src/lib/content-nav.ts`和 `templates/docs-starter` (单位:千美元)`src/content-nav.ts`),用于带节和侧边栏的全版布局.

## 构建脚本

使用 `ContentScanner` 当一个脚本需要外页列表捆绑时:

```typescript
import { join } from 'node:path';
import { ContentScanner, compareEntriesByField } from '@ecopages/content-processor';
import { docsFrontmatterSchema } from '../src/content/docs-schema';

const scanner = new ContentScanner({
    contentRoot: join(srcDir, 'content/docs'),
    orderBy: compareEntriesByField('order'),
    schema: docsFrontmatterSchema,
});

const manifest = await scanner.getManifest();
const raw = await scanner.getRawContent('getting-started/intro');
```

## 软件包出口

| 导入 | 目的 |
| :-- | :-- |
| `@ecopages/content-processor` | `ContentScanner`,排序帮助者,共享类型. |
| `@ecopages/content-processor/plugin` | `contentProcessorPlugin()` 页:1 `eco.config.ts`。 。 。 . |
| `@ecopages/content-processor/types` | `ContentEntry`, (中文(简体) ), `ContentCollectionModule`, (中文(简体) ), `EntryComparator`。 。 。 . |
| `@ecopages/content-processor/mdx` | `remarkFrontmatter`, (中文(简体) ), `withContentMdxPlugins()`。 。 。 . |

## 出品文物

| 路径 | 目的 |
| :-- | :-- |
| `.eco/cache/ecopages-content-processor/<collection>.ts` | 生成收集模块(明显 + MDX 导入). |
| `.eco/cache/ecopages-content-processor/<collection>.browser.ts` | 浏览器安全 MDX 加载器 `/component` 中。 磁盘上此文件的相对导入解析 . |
| `.eco/.server-collections/<collection>/<collection>-<identity>.mjs` | 懒惰制造的服务器文物,为一个收藏品. |
| `node_modules/@types/ecopages-content-processor/virtual-module.d.ts` | 生成虚拟模块的TypeScript声明. |

不要手动编辑生成的文件 .

## 校验错误

无效的前题抛出 `SchemaError` 从 `@standard-schema/utils` 在扫描/构建过程中。 修复MDX前题 或放松应用程序中的计划 在开发中,错误出现在浏览器覆盖中,并保存了固定文件在不重启服务器的情况下恢复了收藏.

## Dev / 高频

开发中, 处理器将查看收藏文件以重生 `ecopages:content/*` 显示MDX改变时。 生成的服务器文物被懒散地建在第一个服务器导入上并被其内容衍生出的身份所再用;MDX在下个Page构建前编辑该文物无效. Collection MDX仍然是服务器源:Ecopages使服务器模块无效并运行了HMR,因此页面导入取出更新的MDX组件.

仅监视配置驱动显示再生 。 资产所有权(将跳过服务器无效)需要宣布的处理器能力. 内容处理器不主张 MDX 为资产,所以没有 `capabilities` 需要在 `eco.config.ts`。 。 。 .

## MDX 整合

内容文件为MDX组件. 确保您的 JSX 或 React 集成配置于 `eco.config.ts` 带有 `mdx` 选项,将收藏项编译为组件.

YAML 前题需要的内容收藏 `remark-frontmatter` 输入 **MDX 编译管道**。处理器在扫描时间验证前题(`vfile-matter`); MDX 提供时间需要注释插件这样 `---` 块不作为内容发布.

使用 `@ecopages/content-processor/mdx` 用于编辑 MDX 的集成 :

```typescript
import { withContentMdxPlugins } from '@ecopages/content-processor/mdx';
import remarkGfm from 'remark-gfm';

ecopagesJsxPlugin({
    mdx: {
        ...withContentMdxPlugins({
            remarkPlugins: [remarkGfm],
            rehypePlugins: [/* app-specific rehype plugins */],
        }),
    },
});

reactPlugin({
    mdx: {
        ...withContentMdxPlugins(),
    },
});
```

`withContentMdxPlugins()` 预支 `remarkFrontmatter`。当您需要更细的控制时,直接导入:

```typescript
import { remarkFrontmatter } from '@ecopages/content-processor/mdx';
```

App 特定演示文稿插件(语法突出显示, GFM, 表格包装) 留在您的应用中—— 例如 `src/mdx/plugins.ts`。 。 。 .

## 内容输入所有权

编译 MDX 条目的集成也拥有其渲染: 由 `mdx.extensions: ['.react.mdx']` 在React集成上是一个React组件,必须通过React拥有的路由(例如: `[...slug].react.tsx` {\\fn黑体\\fs22\\bord1\\shad0\\3aHBE\\4aH00\\fscx67\\fscy66\\2cHFFFFFF\\3cH808080}你还好吧? 从 JSX (Radiant) 或 Kita 渲染树上调用它.

生成的 `getComponent()` 保留该所有权的时间:直接在自己车道上引用一个条目,而受支持的外国儿童通过自己的整合使车道排队。 如果没有交接跑出时间,它随入道而抛出,拥有集成,活性集成. 当两个集成为同一集编译 MDX 时, 声明脱节 `mdx.extensions` 每个集成件——因为React MDX加载器从所申报的扩展中取出其过滤器,仅限 `.react.mdx` 使用 React 编译文件. `mdx.extensions` 替换 `compilerOptions.mdxExtensions` 而不是与它合并.

## 常见问题

### @ecopages/content-processor 是什么？

在构建时扫描 MDX 收藏并曝光打入的生态页面:内容/\* 网页和脚本的虚拟模块

### 如何安装 @ecopages/content-processor？

在项目目录运行 npm install @ecopages/content-processor，或使用 pnpm add / yarn add / bun add。它还需要宿主项目提供 peer 依赖：@ecopages/core（0\.7\.1）。npm 7 及以上与 pnpm 8 及以上默认会自动安装必需的 peer 依赖，Yarn 需要手动安装。

### @ecopages/content-processor 支持 TypeScript 吗？

支持。包内自带 TypeScript 类型声明（package\.json 声明了 types 入口），安装后即可获得类型提示，无需再安装 @types 包。

### @ecopages/content-processor 支持 ESM 还是 CommonJS？

以 ES Module 形式发布，推荐使用 import 引入。在 CommonJS 项目中，Node\.js 20\.19\+ / 22\.12\+ 可以直接 require\(\) 不含顶层 await 的 ES Module，更早的版本需要改用动态 import\(\)。

### @ecopages/content-processor 需要什么版本的 Node\.js？

package\.json 的 engines 字段要求 Node\.js ^24\.22\.0 \|\| \>=26\.0\.0。版本不符时 npm 默认只给出警告，开启 engine-strict 后会拒绝安装。

### @ecopages/content-processor 可以商用吗？

@ecopages/content-processor 使用 MIT 许可。宽松许可：允许商业使用、修改和再分发，通常只需在分发时保留原版权与许可声明。以上为概括，不构成法律意见，请以许可原文为准。

### @ecopages/content-processor 的下载量有多少？

根据 npm 官方下载统计，@ecopages/content-processor 在 2026/10/13 – 2026/11/11 这 30 天内被下载 3,319 次，日均约 111 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入，适合横向比较热度，不能直接等同于使用人数。

### @ecopages/content-processor 还在维护吗？

最新版本 0\.7\.1 发布于 2026/11/13（今天）；至今共发布 46 个版本，其中过去 12 个月发布了 46 个；首次发布于 2026/07/14。发布频率只是参考信号：功能稳定的工具可能很少需要更新，建议结合源码仓库的 issue 和提交记录判断。

