SVeditor 文档
集成方式

ESM 包集成

在 React、Next.js 和 Vite 中通过 @wztlink1013/sveditor ESM 包接入 SVeditor(默认方式)。

ESM 包集成

通过 npm 安装 ESM 包是默认接入方式。 安装 @wztlink1013/sveditor,在 bundler 中 import,再用 SVeditor.create() 挂载。只有无法引入 bundler 时才考虑 UMD CDN。

包说明

包名何时安装
@wztlink1013/sveditor必选 — 编辑器运行时、UI、类型与样式
@wztlink1013/sveditor-collab-schema仅当服务端实现协作 API 时

使用协作 schema 时,两个包应保持在同一版本

1. 安装

若许可证包含私有 registry 访问权限,在项目根目录添加 .npmrc

@wztlink1013:registry=https://npm.pkg.github.com
//npm.pkg.github.com/:_authToken=${NPM_TOKEN}

安装锁定版本:

pnpm add @wztlink1013/sveditor@0.2.16

CI 与新环境请使用许可证附带的 Token。

2. 导入路径

导入用途
@wztlink1013/sveditorSVeditor.create()、类型、主题辅助函数
@wztlink1013/sveditor/style.css工具栏、编辑器 chrome、toast 样式
@wztlink1013/sveditor/global可选的 CDN 页面 window.SVeditor 类型

bundler 会自动解析 ESM 入口。应用代码请优先使用 import,不要用 require()

3. 最小用法

"use client";

import { SVeditor } from "@wztlink1013/sveditor";
import type { EditorOptions } from "@wztlink1013/sveditor";
import "@wztlink1013/sveditor/style.css";

const editor = SVeditor.create({
  el: "#editor",
  content: "<p>Hello</p>",
  editable: true,
} satisfies Omit<EditorOptions, "el">);
  • 必须导入 style.css,否则工具栏和布局会异常。
  • 卸载或跳转前调用 destroy()

4. Next.js App Router(SSR 安全)

ESM 包可能在模块加载时访问 document不要在 Server Component 中静态 import @wztlink1013/sveditor

方案 A — next/dynamicssr: false

将编辑器拆到仅客户端模块,再动态加载:

"use client";

import dynamic from "next/dynamic";

export const DocEditor = dynamic(
  () => import("./doc-editor.client").then((m) => m.DocEditor),
  { ssr: false },
);

doc-editor.client.tsx 内:

"use client";

import { useEffect, useMemo, useRef } from "react";
import { SVeditor } from "@wztlink1013/sveditor";
import type { EditorOptions } from "@wztlink1013/sveditor";
import "@wztlink1013/sveditor/style.css";

type EditorInitOptions = Omit<EditorOptions, "el">;

export function DocEditor({ options }: { options: EditorInitOptions }) {
  const containerRef = useRef<HTMLDivElement>(null);

  useEffect(() => {
    const el = containerRef.current;
    if (!el) return;
    const editor = SVeditor.create({ el, ...options });
    return () => editor.destroy();
  }, [options]);

  return <div ref={containerRef} className="min-h-[640px]" />;
}

方案 B — 在 useEffect 中动态 import()

"use client";

import { useEffect, useRef } from "react";
import type { EditorInstance } from "@wztlink1013/sveditor";
import "@wztlink1013/sveditor/style.css";

export function LazyEditor() {
  const containerRef = useRef<HTMLDivElement>(null);
  const instanceRef = useRef<EditorInstance | null>(null);

  useEffect(() => {
    const el = containerRef.current;
    if (!el) return;

    let cancelled = false;

    void import("@wztlink1013/sveditor").then(({ SVeditor }) => {
      if (cancelled) return;
      instanceRef.current = SVeditor.create({ el, content: "<p>Hello</p>" });
    });

    return () => {
      cancelled = true;
      instanceRef.current?.destroy();
      instanceRef.current = null;
    };
  }, []);

  return <div ref={containerRef} className="min-h-[640px]" />;
}

5. Vite / React SPA

挂载代码只在浏览器执行时,使用 useEffect 与稳定的 options

"use client";

import { useEffect, useMemo, useRef } from "react";
import { SVeditor } from "@wztlink1013/sveditor";
import type { EditorOptions } from "@wztlink1013/sveditor";
import "@wztlink1013/sveditor/style.css";

type EditorInitOptions = Omit<EditorOptions, "el">;

export function EditorPage() {
  const containerRef = useRef<HTMLDivElement>(null);
  const options = useMemo<EditorInitOptions>(
    () => ({ content: "<p>Hello</p>", editable: true }),
    [],
  );

  useEffect(() => {
    const el = containerRef.current;
    if (!el) return;
    const editor = SVeditor.create({ el, ...options });
    return () => editor.destroy();
  }, [options]);

  return <div ref={containerRef} className="min-h-[640px]" />;
}

完整生命周期见 快速开始

6. 样式与 PostCSS

直接导入 SDK 样式:

import "@wztlink1013/sveditor/style.css";

若 PostCSS 重新处理 node_modules CSS 并对 SDK 样式报错,请在 PostCSS 配置中排除 @wztlink1013/sveditor

7. TypeScript

import { SVeditor } from "@wztlink1013/sveditor";
import type {
  EditorOptions,
  EditorInstance,
  ExtensionOptions,
  AutoSaveOptions,
} from "@wztlink1013/sveditor";

8. 升级

  1. 修改 package.json 中的版本号。
  2. 重新安装依赖。
  3. 回归测试 extensionsOptions 及协作 schema(如适用)。

常见问题

现象处理
document is not defined使用 next/dynamic + ssr: false 或在 useEffect 中动态 import()
工具栏样式异常添加 import "@wztlink1013/sveditor/style.css"
每次输入丢焦点useMemo 稳定 options
安装鉴权失败检查 .npmrc 与许可证 Token
PostCSS 解析失败在 PostCSS 中排除 SDK CSS

下一步