# @openpresentation/opf 中文文档

规范地址：https://npmcn.com/package/%40openpresentation/opf/

版本：0\.30\.0
npm 元数据更新时间：2026-11-02T02:29:00.613Z
中文译文更新时间：2026-11-02T02:56:44.563Z
软件包许可：MIT

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

原始 npm 页面：https://www.npmjs.com/package/%40openpresentation/opf
原文对照：https://npmcn.com/package/%40openpresentation/opf/?lang=original
项目主页：https://openpresentation.org/
源码仓库：https://github.com/OpenPresentation/opf

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

- 包体积（解压后）：15.6 MB，124 个文件
- 模块格式：ES Module
- TypeScript 类型：包内自带
- Node.js 要求：\>=22
- 运行依赖：5 个
- peer 依赖：@openpresentation/opf-pptx ^0\.30\.0，@openpresentation/opf-render ^0\.30\.0
- 首次发布：2026-05-05T22:26:36.950Z
- 最新版本发布：2026-11-02T02:29:00.259Z
- 已发布版本数：60（近 12 个月 60 个）

## 中文简介

规范开放演示格式模式、TypeScript类型、本地验证和组合；在Node中，文件API和CLI默认注册pptx。@openpresentation/ Gallery的画廊目录。

## 安装

```sh
npm install @openpresentation/opf
```

也可以使用：`pnpm add @openpresentation/opf`、`yarn add @openpresentation/opf`、`bun add @openpresentation/opf`

## README

# @openpresentation /消息

JavaScript和TypeScript的Canonical Open Presentation Format包。

发布OPF模式、目录预设、原始规范文件、生成的TypeScript类型、示例、文档和本地验证助手。模式是预稳定的(0。X -预计在1.0之前的小版本之间会有突破性的变化)。这个包不呈现PowerPoint文件，解析 `.pptx`，获取远程目录，调用托管api，提供遥测或使用AI。

规范的npm包仍然存在 `@openpresentation/opf`;一个单独的 `@openpresentation/opf-spec` 包不用于v0.2.0，因此现有的下游导入保持稳定。打包的npm工件包括包可寻址的OPF模式、目录、参考文件和一个可选的下游服务引用 `openapi.yaml` 下 `spec/`.

存储库: [https://github.com/OpenPresentation/opf](https://github.com/OpenPresentation/opf)

## 文件命名

使用 `*.opf.json` 下载完整的开放演示格式文件，例如 `deck.opf.json`.

OPF文档是纯JSON，而 `.opf.json` Suffix使其对编辑器、验证器、代理和存储库工具可见。避免裸露的 `*.opf` 因为该扩展已经被其他文档和项目格式所使用。

## 安装

```sh
pnpm add @openpresentation/opf
# or: npm install @openpresentation/opf
# or: yarn add @openpresentation/opf
```

要求Node 22或更高版本(`engines.node` `>=22`)，从0.12.1之后的版本。声明了0.10.0到0.12.1版本 `24.x`因此，npm在Node 22或26上静默地安装了一个匹配（RR-20）的旧版本。早期发布的版本保留了它们记录的运行时需求。

## 使用

对大多数应用程序代码使用通用的根API：

```ts
import { presentation, validate, embed } from "@openpresentation/opf";
import { gallery } from "@openpresentation/gallery";

import type { Presentation } from "@openpresentation/opf";

const deck: Presentation = {
  name: "Quarterly Review",
  slides: [{ title: "Quarterly Review", items: ["Revenue", "Product", "Hiring"] }],
};

console.log(presentation.$id);
// Register the catalogs your host trusts; core ships no records. In Node, validate, stats, paginate, embed and edit
// register the gallery (@openpresentation/gallery, a dependency of core) when a call names none.
const catalogs = [gallery];
console.log(validate({ ...deck, design: { theme: "classic" } }, { catalogs }).valid);
// Save with every record the deck uses embedded, so it renders the same with no catalog registered.
const saved = embed({ ...deck, design: { theme: "classic" } }, { catalogs }).document;
console.log(Object.keys(saved.catalogs.default.themes)); // ["classic"]
console.log(Object.keys(gallery.tones));
```

在Node（以及Bun和Deno）中，根目录添加文件： `convert` 将一个文件转换为另一个文件（将一个甲板转换为PDF， PNG， SVG或PPTX，将PowerPoint文件转换为甲板，将一个甲板形式转换为另一个甲板，或没有输出路径的字节）， `open` 读取一个甲板文件或导入一个 `.pptx`, `save` 写一个。相同的导入在每个运行时都有效，所以一个命名空间导入涵盖了一个应用程序：

```ts
import * as opf from "@openpresentation/opf";

await opf.convert("deck.opf.md", "deck.pdf");
const deck = await opf.open("deck.opf.md");
deck.slides.push({ title: "Q4" });
await opf.save(deck, "deck.opf.md");
const { files } = await opf.convert(deck, { format: "pptx" }); // bytes, nothing written
```

绘图和ppt通过可选的同伴 `@openpresentation/opf-render` 和 `@openpresentation/opf-pptx`，哪个核心在调用第一次需要它们时加载；NPM不会为你安装它们。根有条件导出（OPF 0.18删除） `/node`): `node`， `bun` 和 `deno` 得到这个完整的构建，然后 `browser`， `worker`， `workerd` 和 `default` 获得具有相同名称和相同类型的浏览器安全构建，其中 `open`， `save` 和 `convert` 拒绝与 `OPFApiError` 代码 `node-only`． 其他所有子路径都在浏览器中运行。 `parseSlideSelection(3 | "1-3" | [1, 3], total)` 在两者中读取幻灯片选择。看到 [OPF文件在Node](https://npmcn.com/package/docs/node.md).

在Cloudflare Workers、Vercel Edge和其他拒绝从字符串生成代码的主机上， `validate` 运行在构建时编译的验证器，而不是用Ajv编译模式。这个 `workerd`， `worker` 和 `edge-light` 条件选择它们，所以Worker不需要别名，也不需要选项；为在工作线程（以及严格的Content-Security-Policy下的页面）导入上运行的Node绑定的代码 `@openpresentation/opf/precompiled` 一次。结论和发现是相同的，并且CI通道在实际中运行包 `workerd` 运行时。看到 [边缘运行时](https://npmcn.com/package/docs/node.md#edge-runtimes-validators-that-never-compile-code).

当你只需要一个表面时，使用聚焦导入：

```ts
import { presentation, audience } from "@openpresentation/opf/schemas";
import { specFileEntries } from "@openpresentation/opf/spec-files";
import { validate, assertValid, validationRules } from "@openpresentation/opf/validator";
import type { Presentation, Audience, Tone } from "@openpresentation/opf/types";
```

根条目保存应用程序级API：模式、目录引用及其解析(`resolveReference`， `embed`， `copySlides`， `updateFromCatalog`)、验证、变量、分页、数据助手、字体策略、 `stats`， `resolveSlideContext` 和 `resolveSlideVariables`． 发动机组成和绘制 `context.slide` 从 `resolveSlideContext(deck, index, { slideNumber, slideCount })`：带滑动范围的内置滑块 `{{slide.number}}`， `{{slide.section}}` 和 `{{deck.slideCount}}` 代入相同的数 `options` 带(`resolveSlideVariables(slide, { slideNumber, slideCount })` 单独做替换)页眉和页脚文本由 `layoutFurniture`，它会记录每张幻灯片的编号 `FurnitureTextPart.fields`． 看到 [模板和变量](https://npmcn.com/package/docs/templates-and-variables.md#slide-scoped-built-ins)． 它不携带目录记录：pptx。画廊目录是包 `@openpresentation/gallery` （`gallery`， `catalogDisplay`的布局预览 `@openpresentation/gallery/previews`)，在自己的版本行上发布的core依赖，当调用没有目录时，Node构建会注册它（OPF 0.19删除） `@openpresentation/opf/catalog` 和 `defaultCatalog`，没有别名)。解析引用的每个入口点都使用 `{ catalogs }`、主机注册的目录；第一个是省略的文档的默认值 `catalogs.default`． 看到 [目录和默认目录](https://npmcn.com/package/docs/default-catalog.md).

布局引擎的名称不在根目录上。 `composeSlide`， `fitText`， `layoutQuote` 另一个 `layoutX`/`fitX` 功能，编号，脚注和引用，颜色对比，代码语法，模式填充，度量趋势，图表选项，脚本字体和文本方向来自 `@openpresentation/opf/composition`;符号字体表来自 `@openpresentation/opf/symbol-font-encodings`.

### 事实，幻灯片上下文和字体处理

`stats(presentation, options?)` 报告关于桥牌的中立事实（结构、文字、注释、图像、图表、表格、数据集、引用、变量、资产、字体），而不进行构图、测量或验证；看到 [统计指南](https://npmcn.com/package/docs/stats.md). `resolveSlideContext(presentation, index, { fonts, catalogs })` 将一张幻灯片的画布、布局、主题和字体系列（幻灯片设计，然后是甲板设计，然后是主题，然后是引擎默认值）解析为 `ComposeSlideOptions` 那 `composeSlide` 带一个 `unresolved-reference` 每个引用的诊断无法解析(`strictReferences: true` 抛出 `OPFUnresolvedReferenceError` 相反)。甲板级动词take `{ fonts }`谁的手柄？ `textMeasurement` 是主机的实际字体绘制文本的宽度(`paginate(deck, { fonts })`);渲染器的字体加载器返回一个扩展它的更丰富句柄。 `composeSlide` 它本身是发动机水平的 `textMeasurement` 和 `fontFamilies` （`{ heading, body, code, accent? }`直接)。

### 内容转换

`@openpresentation/opf/convert` 在文本、列表、引用、度量、代码、时间线、图表、表格和一组度量块之间转换一个有效负载(`convertContent`， `contentConversionTargets`)、嵌套列表项、分组块、在内容和幻灯片设计之间移动图像，以及拆分或合并幻灯片(`splitSlide`， `splitSlideOnOverflow`， `mergeSlides`， `unpaginate`）. 每个函数都是纯粹的，从不虚构内容、报告 `lossless` 和 `loss`，有理由拒绝并验证其输出。看到 [转换指南](https://npmcn.com/package/docs/conversions.md)． 在变更日志中列出它之前的版本中不会。

### 标记和轮廓

`@openpresentation/opf/markdown` 读取和写入一个甲板Markdown在一个小文档方言（YAML前端问题）， `---` 之间的幻灯片, `#` 标题, `##` 副标题、列表、引用、表格、图片、 `chart`， `metric` 和 `timeline` 围栏, `Note:` 演讲者笔记)。 `fromMarkdown(markdown, { split, defaults, validate })` 返回 `{ presentation, valid, findings, counts }` 与发现（共享） `Finding` 格式)，其中载有划线和列划线； `toMarkdown(presentation, { unsupported })` 编写任何有效的deck，将该方言没有语法的内容嵌入到YAML中（或将其放入） `report.loss`)，它写入的Markdown会转换回同一套牌。确定性和离线。阅读前面的事项与 `yaml` 包中。看到 [减价指南](https://npmcn.com/package/docs/markdown.md)． 在变更日志中列出它之前的版本中不会。

### 读写任何形式的牌组

`parse(text, { format, filename, catalogs })` 和 `stringify(presentation, { format | filename })` (根和 `@openpresentation/opf/deck`)读取和写入JSON (canonical)， YAML或Markdown格式的deck。格式为 `format` 选项，否则为文件名(`.opf.md` 减价, `.yaml` 和 `.yml` 是YAML，其他都是JSON；一个普通 `.md` 不是套牌，更不是内容。 `parse` 返回表示并抛出 `OPFValidationError` 对于语法、模式或引用错误；错误的 `report.findings` 在文本中按行和列定位(`opf/json-syntax`， `yaml/<rule>` 或者 `markdown/<rule>` 语法错误)。警告不要抛出： `validate(text)` 返回完整的报表。两者都在浏览器中运行；文件是Node构建的任务（如上）。

### OPF为YAML

`@openpresentation/opf/yaml` 以YAML（相同数据的创作形式）的形式读写一个deck （JSON保持规范）。 `fromYaml(text, { aliases, validate })` 读取严格的json兼容的YAML 1.2(一个文档，根处的映射，没有自定义标记，重复的键或非有限的数字；锚定，别名和合并键只能与 `aliases: true`)和返回 `{ presentation, valid, findings, counts, schemaValid, checks }`: `validate` 甲板报告，每一个发现（共享） `Finding` 格式，YAML语法错误为 `yaml/<rule>` 发现)位于YAML的行和列。 `toYaml(presentation, { schemaComment })` 写入规范的YAML（模式键顺序、块样式、引用的模糊字符串），读取回同一套牌，并抛出 `OPFYamlError` 无效的。 `parseYamlData` 和 `scanYamlComments` 是帮助者。看到 [YAML指南](https://npmcn.com/package/docs/yaml.md).

### 源代码编辑：模式字段查询，文本寻址和语法恢复

源代码编辑器（CLI和代理）的两个浏览器安全子路径。 `@openpresentation/opf/schema` 从JSON模式中读取文档的字段模型： `describeField(path, document?)` 返回类型、描述、枚举值、默认值、示例、父节点是否需要 `oneOf` 变异(和 `primary`（表单模板应该使用），排名 `children` 一个对象（首先需要，然后是策展） `COMMON_KEYS` 顺序，然后按字母顺序；提升区域, `extensions` 和 `$schema` 是 `advanced`)，数组的项模式(`itemInfo`)或地图(`entryInfo`)， `requiredChildren` 和 `freeText`, `{ known: false }` 对于模式没有描述的路径； `catalogKindAt(path, document?)` 将参考字段指向的目录命名为(`layouts`， `themes`， `colorSchemes`， `fontSchemes`， `narratives`， `audiences`， `purposes`， `tones`) `schemaCatalogKinds` （也可以导出），核心端元数据由模式名称和JSON指针键；发布的模式不携带供应商关键字，并在严格的ajax下编译，因此新的引用字段是其中的一个条目，不需要更改编辑器。它所基于的导航帮助器也被导出(`resolveSchema`， `schemaVariants`， `activeSchema`， `schemaAtPath`， `createSchemaValue`， `listSchemaFields`， `splitOpfPath`）。 `@openpresentation/opf/source` 将文本转换为位置和返回： `locate(text, format, pointer, { part })` 是JSON、YAML或Markdown (`value`， `key`， `entry`， `open` 或者 `colon`;最近的祖先 `exact: false` 节点缺失时；按其查找结果使用的相同范围来定位标记下滑幻灯片字段 `layout=` 选项注释的标记，后面的文本 `#` 或者 `-` )， `pathAt(text, format, offset)` 插入符号下的路径， `scanMarkdown(text)` 带有方言词汇的Markdown deck（前部内容，幻灯片，选项注释，围栏，注释）的区域(`SLIDE_OPTION_KEYS`， `BLOCK_OPTION_KEYS`， `FENCE_KINDS`， `METRIC_KEYS`), `analyzeJsonSyntax(text, { limit })` 每个JSON语法错误的根本原因，一次，按位置顺序（最多五个），包括范围，消息，提示和修复它的修复程序(`Insert comma`， `Add { }`， `Remove "design"`， `Insert }`， `Use double quotes`,……); `validate(text)` 报告相同的原因 `opf/json-syntax` 发现。看到 [验证](https://npmcn.com/package/docs/validate.md).

### 验证(0.14.0)

`validate(input, options?)` 是一个检查器，从根和从 `@openpresentation/opf/validator`. `input` 是经过解析的表示或严格的JSON文本；结果是 `ValidationReport` 谁的 `findings` (共享 `Finding` 格式, `spec/schemas/finding.schema.json`每个人都有一个马厩 `opf/<rule>` Id，严重程度，六个类别之一： `format` （JSON语法，重复键，模式） `references` （目录参考，资产，引文，数据集）， `policy` (主机 `contracts`)， `accessibility` （对比，Alt文本，阅读顺序，链接）， `layout` （溢出，字体大小，图像分辨率，字体）和 `content` （占位符、空幻灯片、非数字图表单元格）。 `valid` 意味着没有严重的发现 `error`，默认情况下只有 `format`， `references` 和 `policy` 发现可以有。文本输入添加行和列； `only`， `ignore` 和 `severity` 挑选和推广规则或类别；作文是懒惰的，所以 `validate(deck, { only: ["format"] })` 成本与模式检查的成本相同。只读且确定性：不获取远程资源。看到 [验证指南](https://npmcn.com/package/docs/validate.md)． 干净的报告不证明布局、字体或本机导出保真度。

`describeFinding(finding, { document })` 和 `explain(ruleId)` 把发现用通俗易懂的语言表达出来。 `describeFinding` (从 `@openpresentation/opf/source`)返回 `{ message, next }` 对于任何发现：反引号中的字段有什么问题，接下来可能会发生什么(“你的意思是？” `center`？”)，根据调查结果本身的数据和文件编写；每一个 `opf/*` 规则有它的文本。 `explain` （也在包的根目录上）返回规则的摘要、基本原理、 `fix` 还有一个小的before/after `example`． 看到 [明文文本和 `explain`](https://npmcn.com/package/docs/validate.md#plain-words-text-and-explain).

### 补丁，diff，合并和格式化（0.12.0）

在0.12.0添加（未在0.11.4或更早版本中添加）： `@openpresentation/opf/patch` 是CLI和编辑器共享的RFC 6902实现(`applyPatch`， `applyPatchWithInverse`， `invertPatch`（严格的指针帮助器，可选的结果模式验证）； `@openpresentation/opf/diff` 有 `diff` （幻灯片匹配的id，内容和相似性，移动，可读的报告和JSON补丁）和 `merge` （三向合并与冲突对象，永远不会放弃一方）； `@openpresentation/opf/format` 有 `format` （规范键顺序和布局，幂等）。看到 [该指南](https://npmcn.com/package/docs/patch-diff-merge-format.md).

### id，文档散列和补丁范围（CE-04, CE-05）

`@openpresentation/opf/ids` (所有的都放在包的根上，指针和哈希部分也放在上面 `/patch`)使编辑可寻址和可检查。 `assignIds(document, { generate? })` 填补缺失 `id` 幻灯片和内容有效载荷的确定性(`{ document, patch, assigned }`;现有的id永远不会改变)。在数组中，指针标记 `@intro` 元素的名称 `id` 是 `intro`,所以 `/slides/@intro/blocks/@kpi/text` 幸存重新排序: `applyPatch` 和 `readPointer` 解决它, `resolveIdPointer` 和 `toIdPointer` 转换指针， `resolveIdPatch` 和 `toIdPatch` 一整块。 `documentHash(document)` 是 `sha256:` 和SHA-256的键排序JSON（纯JavaScript，在Node，浏览器和edge运行时相同）； `applyPatch(document, patch, { expectHash })` 和 `edit(deck, patch, { expectHash })` 只应用于获取哈希值的文档，否则抛出 `OPFPatchHashError` 什么也改变不了。 `touches(patch, document?)` 返回指针（索引和id形式）、id、幻灯片id和补丁读取和写入的类型，用于冲突检测和权限检查。看到 [该指南](https://npmcn.com/package/docs/patch-diff-merge-format.md#ids-id-addressed-paths-hashes-and-patch-scope).

### 布局预览

`@openpresentation/gallery/previews` 提供预渲染的SVG缩略图 幻灯片布局目录在pptx.画廊。每个预览都是一个自包含的SVG 大小为16:9的容器，颜色和布局已经渲染。

```tsx
import { getLayoutPreview } from "@openpresentation/gallery/previews";

export function LayoutThumbnail({ slug }: { slug: string }) {
  const html = getLayoutPreview(slug);
  if (!html) return null;
  return (
    <div
      className="aspect-[16/9] overflow-hidden rounded-lg border border-border bg-card"
      dangerouslySetInnerHTML={{ __html: html }}
    />
  );
}
```

预览源存在于 [`packages/gallery`](https://npmcn.com/package/%40openpresentation/gallery) 检查所读取的存储库的。

### 例子甲板

`@openpresentation/opf/examples` 船每 `.opf.json` 文件从 `examples/` 在上游回购中，已经针对表示进行了解析和验证 构建时的模式。

```ts
import {
  examples,
  galleries,
  getExample,
  getExamplesByGallery,
} from "@openpresentation/opf/examples";

const compliance = getExample("compliance-readiness-review");
const businessDecks = getExamplesByGallery("business-functions");

console.log(`${examples.length} example decks across ${galleries.length} galleries`);
```

每一个 `ExampleRecord` 包括已解析的 `Presentation` 对象及其 repo-相对路径，顶级类别(`gallery`， `technical`，……)，以及 如适用，廊塞。

### 文档页面

`@openpresentation/opf/docs` 运顶层 `docs/*.md` 参考页面 （`schema-reference`， `catalog-schema-reference`， `content-payloads`， `content-item-design-overrides`， `examples`）. 子目录等 `docs/migrations` 和 `docs/plans` 是故意排除的吗 在固定的NPM发布中快速发布。

```ts
import { docs, getDoc } from "@openpresentation/opf/docs";

for (const doc of docs) {
  console.log(`${doc.title} — ${doc.file}`);
}

const schemaRef = getDoc("schema-reference");
console.log(schemaRef?.markdown.slice(0, 200));
```

### 上游的自述

`@openpresentation/opf/repo-readme` 暴露上游的原始降价 `OpenPresentation/opf` 自述文件。在此版本固定在此发布。使用它 当你想在另一个网站或应用程序中镜像规范的README时 不需要进行网络获取。

```ts
import { repoReadme } from "@openpresentation/opf/repo-readme";

console.log(repoReadme.split("\n").slice(0, 3).join("\n"));
```

验证报告包含 `findings`． 一个严重的发现 `error` 是一个 结构性问题 `valid` 虚假的; `warning` 和 `info` 发现是 咨询的，如 `narrative`， `design` 或者 `layout` 解析的引用 地方(`opf/unresolved-reference`)或缺少Alt文本。引用解析 在文件所嵌入的记录中(`catalogs.custom`， `catalogs.default`,名叫 组)，然后在主机注册的目录中 `{ catalogs }`.

```ts
const report = validate(deck, { catalogs: [gallery] });
if (!report.valid) console.error(report.findings.filter((finding) => finding.severity === "error"));
for (const finding of report.findings) console.warn(finding.ruleId, finding.path, finding.message);
```

本地验证目录记录：

```ts
import { validateCatalogRecord } from "@openpresentation/opf";
import { gallery } from "@openpresentation/gallery";

for (const [id, record] of Object.entries(gallery.audiences)) {
  // A published record file carries its $schema and id; the gallery keys records by id without them.
  const result = validateCatalogRecord("audiences", { $schema: "https://openpresentation.org/schema/opf-audience/v1", id, ...record });
  if (!result.valid) {
    console.error(result.findings);
  }
}
```

原始规范JSON发布于 `spec/`：

```ts
import presentationSchema from "@openpresentation/opf/spec/schemas/opf.schema.json" with {
  type: "json",
};
```

原始规范清单显示了应该从npm而不是GitHub解析的文件的类型化包路径。 `openapi.yaml` 是选择通过HTTP公开OPF的下游服务的参考契约；OpenPresentation不承载该API。

```ts
import { specFileEntries } from "@openpresentation/opf/spec-files";

const openApi = specFileEntries.find((entry) => entry.path === "openapi.yaml");
console.log(openApi?.packagePath);
```

核心船没有目录记录文件（RR-78）：记录是 `@openpresentation/gallery`’s，和pptx。库为每个已发布的记录文件提供服务 `https://www.pptx.gallery/<kind>/<id>.json`． 文件从来没有指向他们。主机转而注册目录：

```js
import { gallery } from "@openpresentation/gallery";
validate(deck, { catalogs: [gallery] });
```

## 开发

```sh
pnpm --filter @openpresentation/opf typecheck
pnpm --filter @openpresentation/opf test
pnpm --filter @openpresentation/opf pack:dry-run
```

`src/generated/` 和 `dist/` 是从根目录生成的 `spec/` 目录和被git有意忽略。

## 常见问题

### @openpresentation/opf 是什么？

规范开放演示格式模式、TypeScript类型、本地验证和组合；在Node中，文件API和CLI默认注册pptx。@openpresentation/ Gallery的画廊目录。

### 如何安装 @openpresentation/opf？

在项目目录运行 npm install @openpresentation/opf，或使用 pnpm add / yarn add / bun add。

### @openpresentation/opf 支持 TypeScript 吗？

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

### @openpresentation/opf 支持 ESM 还是 CommonJS？

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

### @openpresentation/opf 需要什么版本的 Node\.js？

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

### @openpresentation/opf 可以商用吗？

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

### @openpresentation/opf 还在维护吗？

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

