# @vizejs/plugin-sdk 中文文档

规范地址：https://npmcn.com/package/%40vizejs/plugin-sdk/

版本：0\.650\.0
npm 元数据更新时间：2026-11-02T19:32:06.620Z
中文译文更新时间：2026-11-02T21:21:56.469Z
软件包许可：MIT

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

原始 npm 页面：https://www.npmjs.com/package/%40vizejs/plugin-sdk
原文对照：https://npmcn.com/package/%40vizejs/plugin-sdk/?lang=original
项目主页：https://github.com/ubugeeei-prod/vize
源码仓库：https://github.com/ubugeeei-prod/vize

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

- 包体积（解压后）：77.8 kB，16 个文件
- 模块格式：ES Module
- TypeScript 类型：包内自带
- Node.js 要求：\>=22
- 运行依赖：0 个
- peer 依赖：@vizejs/native \>=0\.429\.0
- 首次发布：2026-09-27T04:46:38.236Z
- 最新版本发布：2026-11-02T19:32:06.241Z
- 已发布版本数：195（近 12 个月 195 个）

## 中文简介

确定性编写和独立执行的Vize JavaScript插件

## 安装

```sh
npm install @vizejs/plugin-sdk
```

也可以使用：`pnpm add @vizejs/plugin-sdk`、`yarn add @vizejs/plugin-sdk`、`bun add @vizejs/plugin-sdk`

## README

# @vizejs / plugin-sdk

编写同步规则、事实提供程序、本地模板转换和编译 输出钩子。安装 `@vizejs/native` **0.650.0或更新版本** 执行插件。 可选的本机对等体允许该包独立安装以进行创作； 它的帮助程序本身并不编译或检测Vue文件。需要Node 22或更新版本。

## 类型化访问者功能描述符

`@vizejs/plugin-sdk/visitor` 定义稳定版本的描述符边界 visitor-style插件。v1功能词汇表包括SFC、模板、 script, style, virtual TypeScript, diagnostics, lint， format和devtools trace 事件。每个声明的功能都需要一个匹配的同步回调，并且 TypeScript将回调负载缩小到该功能。

```ts
import {
  VISITOR_API_VERSION,
  defineVisitorPlugin,
  negotiateVisitorPlugin,
} from "@vizejs/plugin-sdk/visitor";

const observer = defineVisitorPlugin({
  apiVersion: VISITOR_API_VERSION,
  name: "virtual-ts-observer",
  version: "1.0.0",
  capabilities: ["virtual-ts", "diagnostics"] as const,
  cacheInputs: [],
  visitors: {
    "virtual-ts"(event) {
      console.log(event.payload.virtualFile, event.payload.mappings.length);
    },
    diagnostics(event) {
      console.log(event.payload.diagnostics.length);
    },
  },
});

negotiateVisitorPlugin(observer, {
  apiVersion: VISITOR_API_VERSION,
  capabilities: ["virtual-ts", "diagnostics"],
});
```

定义失败关闭未知或重复的功能，缺失或 未声明的回调函数、异步函数、保留的缓存输入名称和API 版本不匹配。 `runVisitorFixture` 冻结一个已编写的事件并强制执行 包测试的同步返回契约。

这个模块只创建不可变的描述符和作者fixture。事实并非如此 在本机编译器、过滤器或语言服务器中注册回调，以便导入 它不会给这些路径增加功。生产主机必须显式地协商 描述符并拥有取消、截止日期、隔离和事件构造。 虚拟TypeScript和devtools跟踪观察者使用单独的可选主机 entrypoints;导入该模块永远不会全局注册这两个回调。

## Lint规则和自动修复

```js
import * as native from "@vizejs/native";
import { definePlugin, applyFixes } from "@vizejs/plugin-sdk";

const rule = definePlugin({
  name: "team-rule",
  version: "1.0.0",
  visit: ["ui.bind"],
  demands: [],
  cacheInputs: [],
  rules: {
    check(ctx) {
      for (const node of ctx.nodes) {
        if (node.name === "disabled" && node.value === "true") {
          ctx.report(node, "Use a literal boolean attribute.", "disabled");
        }
      }
    },
  },
});
const output = native.lintWithPlugins(source, [rule], {
  filename: "Button.vue",
  cache: true,
  validateDeterminism: true,
});
const fixed = applyFixes(source, output.fixes);
```

报告为访问的L2节点命名。Rust分配它自己编写的UTF-8字节范围； 修复将替换整个范围。 `applyFixes` 保存其他资源； 重复删除相同的建议并自动拒绝冲突的编辑。 慎重地应用建议，然后重新运行编译器和筛选器。

规则接收不可变的批。 `ctx.facts(name)` 的组 静态 `demands` 列表;没有未声明的表越过边界。本地组 包括 `templateScopes` 以及注册的Croquis生产商 `bindings`， `undefined-refs`， `component-usages`， `reactivity`， `provide-inject` 和 `race-conditions` 和 `unused-bindings`。后者计算其注册 `bindings` 依赖。这个 `bindings` 和 `unused-bindings` 跨度是创建的 SFC UTF-8字节范围，由共享生成器映射，即使是重新排序分割 脚本。其他主要位置字段保留其Croquis分析框架： 未定义的引用/组件使用是相对于模板的；反应活性, 提供/注入和比赛位置是相对于脚本的（合并的正常/设置） 脚本（当两者都存在时）。报告和修复总是使用主机的SFC范围。公共组件接口页面有 `component-signature`， `prop-types`， `emit-types`， `slot-types`， `reactivity-classes` 和 `component-references`。每个接口值都保留了生产者的模式， 可空的未知数和类型依赖的完整性。签名的 `props_complete` 单独记录是否枚举了所有属性名。 只有源代码的SDK路由没有已解析的目录证明，因此它报告false 不从磁盘读取导入的文件。导入的类型 分析无法解决仍然明确的未知数。基本的Croquis事实要求 JavaScript或TypeScript脚本；其他脚本方言被明确拒绝。

插件访问需要内联HTML模板。撰写外国模板方言 外部模板块在回调之前被拒绝；SDK没有 假装它们的源是HTML，或者为预处理过程发明源映射。

TypeScript推断出每个原生组的精确映射键和深度只读值 从 `ctx.facts("prop-types")`，包括授权接口顺序和所有发出 过载。包导出 `FactGroups`， `FactKey`， `FactValue`， `FactEntry` 以及个体的本地契约。自定义提供程序组可以使用 `ctx.facts<MyFact>("design/labels")`； 未知组默认为 `unknown`.

## 事实上供应商

```js
import { defineFactProvider, definePlugin } from "@vizejs/plugin-sdk";
const labels = defineFactProvider({
  name: "design",
  version: "1",
  provides: ["design/labels"],
  visit: ["ui.element"],
  demands: ["bindings"],
  cacheInputs: [],
  provide(batch) {
    return { "design/labels": batch.nodes.map((node) => [node.id, node.name]) };
  },
});
const consumer = definePlugin({
  name: "labels",
  version: "1",
  demands: ["design/labels"],
  cacheInputs: [],
  rules: {
    check(ctx) {
      const labels = ctx.facts("design/labels");
    },
  },
});
native.lintWithPlugins(source, [consumer], { cache: true, factProviders: [labels] });
```

提供者将每个输出组声明为 `provider-name/group`，这是必需的。 事实和节点访问。主机计算依赖闭包并拒绝 在使用事实之前，循环、冲突、未声明的输出和格式错误的表。 每个表包含 `[stringOrNumericKey, jsonValue]` 具有唯一键的行。 提供程序依赖戳记自动输入消费者缓存键。

## 原生模板转换

```js
import { defineTransformPlugin } from "@vizejs/plugin-sdk";
const design = defineTransformPlugin({
  name: "design-system",
  version: "1",
  cacheInputs: [],
  transform(batch) {
    return batch.nodes
      .filter((node) =>
        node.attrs.some((attr) => attr.name === "class" && attr.value === "legacy-btn"),
      )
      .map((node) => ({
        kind: "replace-static-attribute",
        node: node.id,
        name: "class",
        value: "ds-button",
      }));
  },
});
const transformed = native.compileWithTransformPlugins(template, [design], {
  filename: "Button.vue",
  sourceMap: true,
  cache: true,
  cacheDir: ".vize-cache",
});
```

钩子在原生规范前的L2点运行。它可以取代现有的 静态HTML属性从主机的允许设置；动态属性, 结构编辑、模板载体和外部命名空间拒绝。值是 语义文本，而不是实体拼写。未知目标或重复编辑拒绝 整个响应。编译器将类型化编辑应用于它的真实竞技场和 发出代码和绘制的地图；不接受客户AST JSON。结果是 带有前缀标识符的模块。 `plugins` 包含每个插件的成本。

## 格式化程序和输出挂钩

```js
import { defineOutputPlugin } from "@vizejs/plugin-sdk";
const license = defineOutputPlugin({
  name: "license",
  version: "1",
  family: "output",
  cacheInputs: [],
  output() {
    return [{ placement: "prepend", comment: "Copyright Example" }];
  },
});
const compiled = native.compileWithOutputPlugins(template, [license], options);
const decorated = native.applyOutputPlugins(transformed.result, [license], { cache: true });
```

`family: "formatter"` 返回 `{start,end,text}` 使用UTF-8字节偏移量进行编辑。 只有保留已解析程序和注释的空白格式 接受。 `family: "output"` 附加或前置普通块注释； 源映射指令和可执行添加拒绝。主机已存在 映射锚定并保留源内容。每个管线键包含上述内容 输出。功能模式结果携带 `preamble` 分开 `code`.

## 决定论，缓存和成本

声明每个捕获的配置或环境输入 `cacheInputs`,甚至 当列表为空时。的名字开始 `@vize/` host-reserved。源, 文件名，原生构建，SDK运行时字节，插件版本/代码，静态需求， 访问和输入参与键。缓存的lint漏检总是审计两个 相同的批次。提供和转换审计失误。缓存的输出挂钩也总是审计； 默认情况下，非缓存输出挂钩审计。不同的验证输出在缓存之前拒绝。所有钩族 有有限的进程内缓存和选择加入吗 `cacheDir` 持久性。磁盘点击 在重用之前验证它们的模式、键和受主机限制的输出。

成本包括占用的主机工作时间和JavaScript调用时间，包括审计调用。 缓存命中不执行回调；它的 `jsNs` 批处理交叉字节为零。 确定性审计观察重复输出。可信回调可以隐藏 环境读取;他们的声明仍然是作者的责任。

## 隔离的回调源

```js
import {
  createSandboxRunner,
  SANDBOX_IMAGE,
  SandboxRuntimeError,
} from "@vizejs/plugin-sdk/sandbox";
const isolated = createSandboxRunner(
  {
    name: "isolated-rule",
    version: "1",
    cacheInputs: [],
    configuration: { message: "Use our design system" },
    rules: { check: "(ctx, config) => { ctx.report(ctx.nodes[0], config.message); }" },
  },
  { timeoutMs: 5000, maxBytes: 1048576 },
);
native.lintWithPlugins(source, [isolated], { cache: true });
```

安装Docker，启动它的守护进程并拉出导出的pinned `SANDBOX_IMAGE` 之前使用。回调源代码和显式JSON配置跨stdin；主人 闭包和导入则不然。每次调用都使用一个非根的只读容器 没有主机挂载、主机环境、外部网络或功能，有 内存/ CPU / PID /文件描述符的限制。主机限制请求/输出字节和 执行时间，然后确认容器移除。运行时检查和清理 每次最多增加5秒 `timeoutMs`.

`SandboxRuntimeError.code` 区分 `runtime_unavailable`， `execution_stopped`， `execution_failed` 和 `cleanup_failed`。不可用的码头工人 或者缺失的图像拒绝执行；它永远不会将来宾作为受信任代码运行。 映像自己的文件系统仍然是可读的。Docker提供隔离； 此API不要求虚拟机隔离。

`definePlugin` 其他普通的帮助程序执行受信任的应用程序代码 在调用Node进程中同步执行，并且没有执行截止日期。 冻结批次和审计输出并不能隔离这些回调。测量 代理句柄保持峰值兼容性。 `@vizejs/extension-sdk` 是 单独版本的guest接口。

## 虚拟TypeScript访客

`defineVisitorPlugin` 描述符中只有 `virtual-ts` 能力可以是 为本机类型检查主机协商。普通的 `typeCheck` 入口点 仍然是plugin-free;呼叫者通过单独的访问者入口点选择加入。

```js
import { typeCheckWithVirtualTsVisitors } from "@vizejs/native";
import {
  VISITOR_API_VERSION,
  createVirtualTsVisitorHost,
  defineVisitorPlugin,
} from "@vizejs/plugin-sdk/visitor";

const observer = defineVisitorPlugin({
  apiVersion: VISITOR_API_VERSION,
  name: "virtual-ts-observer",
  version: "1",
  capabilities: ["virtual-ts"],
  cacheInputs: [],
  visitors: {
    "virtual-ts"({ payload }) {
      console.log(payload.virtualFile, payload.code, payload.mappings);
    },
  },
});

typeCheckWithVirtualTsVisitors(source, [createVirtualTsVisitorHost(observer)], {
  filename: "src/App.vue",
});
```

回调接收不可变生成的代码和源/生成的UTF-8字节 在构建实际类型检查投影之后的范围。返回一个值， 请求其他功能或伪造不完整的主机标识拒绝 调用。

## Devtools跟踪访问者

`devtools-trace` 描述符显式附加到请求本地 `@vizejs/devtools` 录音机。记录器序列化每个提交的跟踪事件 通过协商适配器；禁用的记录器不会调用已配置的 主机，而普通的录音机没有 `visitorHosts` 不要检查插件 描述符。

```js
import { createDevtoolsTraceRecorder } from "@vizejs/devtools";
import {
  VISITOR_API_VERSION,
  createDevtoolsTraceVisitorHost,
  defineVisitorPlugin,
} from "@vizejs/plugin-sdk/visitor";

const observer = defineVisitorPlugin({
  apiVersion: VISITOR_API_VERSION,
  name: "trace-observer",
  version: "1",
  capabilities: ["devtools-trace"],
  cacheInputs: [],
  visitors: {
    "devtools-trace"({ file, payload }) {
      console.log(file, payload.events);
    },
  },
});

const trace = createDevtoolsTraceRecorder({
  sessionId: "request-1",
  visitorHosts: [createDevtoolsTraceVisitorHost(observer)],
});
```

每个交付的事件都有一个确定的会话/序列ID，这是派生的阶段 从其跟踪类型中，将毫秒时间戳标准化为纳秒，以及 其余记录器字段为不可变的 `data`。访问者异常或非void Result在记录进入快照之前拒绝该记录。

## 常见问题

### @vizejs/plugin-sdk 是什么？

确定性编写和独立执行的Vize JavaScript插件

### 如何安装 @vizejs/plugin-sdk？

在项目目录运行 npm install @vizejs/plugin-sdk，或使用 pnpm add / yarn add / bun add。

### @vizejs/plugin-sdk 支持 TypeScript 吗？

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

### @vizejs/plugin-sdk 支持 ESM 还是 CommonJS？

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

### @vizejs/plugin-sdk 需要什么版本的 Node\.js？

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

### @vizejs/plugin-sdk 可以商用吗？

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

### @vizejs/plugin-sdk 还在维护吗？

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

