集成方式
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.16CI 与新环境请使用许可证附带的 Token。
2. 导入路径
| 导入 | 用途 |
|---|---|
@wztlink1013/sveditor | SVeditor.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/dynamic 且 ssr: 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. 升级
- 修改
package.json中的版本号。 - 重新安装依赖。
- 回归测试
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 |