如何使用 Tiny-editor 快速部署一个协同编辑器

介绍

TinyEditor是一个框架无关的富文本编辑器,既可以在原生 JavaScript 项目中使用,也可以在 Vue、React 等前端框架中使用。 本篇文章带来的是如何使用 Tiny-editor 最新的协同编辑模块快速部署多人实时协作编辑。

快速开始

前端部署

安装 Tiny-editor

首先需要安装 Tiny-editor

css 复制代码
pnpm i @opentiny/fluent-editor

编写 Html 引入 Tiny-editor 和对应的样式

JavaScript

scss 复制代码
@import '@opentiny/fluent-editor/style.css';
HTML 复制代码
<div id="editor">
  <p>Hello TinyEditor!</p>
</div>
JavaScript 复制代码
import FluentEditor from '@opentiny/fluent-editor'

const editor = new FluentEditor('#editor', {
  theme: 'snow',
})

至此已经引入了 Tiny-editor 编辑器,接下来安装协同编辑模块。

安装协同编辑模块

安装额外依赖

css 复制代码
pnpm i quill-cursors y-protocols y-quill yjs y-indexeddb y-websocket

引入协同编辑模块

JavaScript 复制代码
import FluentEditor, { CollaborationModule } from '@opentiny/fluent-editor'
FluentEditor.register('modules/collaborative-editing', CollaborationModule, true)

编辑器基础配置:

JavaScript 复制代码
const editor = new FluentEditor('#editor', {
  theme: 'snow',
  modules: {
    'collaborative-editing': {
      provider: {
        type: 'websocket',
        options: {
          serverUrl: 'wss://demos.yjs.dev/ws',
          roomName: 'Tiny-Editor-Demo-juejin',
        },
      },
    },
  },
})

现在协同编辑已经可用。

更多配置

通过配置 'collaborative-editing' 模块,你可以控制协同编辑的核心行为,包括连接方式、用户状态显示以及光标样式等。

Provider 配置

Provider 是协同编辑的核心,它负责管理客户端和服务器之间的数据同步。TinyEditor 支持多种 Provider 类型,最常见的是 WebSocket ProviderWebRTC Provider

WebSocket Provider

这是最常用的连接方式,通过标准的 WebSocket 协议与后端服务器进行通信。

参数 类型 必填 默认值 说明
serverUrl string - WebSocket 服务器地址
roomName string - 房间名称
connect boolean true 是否自动连接
params Record<string, string> - 连接参数
protocols string[] - WebSocket 协议
resyncInterval number - 重新同步间隔(毫秒)
maxBackoffTime number - 最大退避时间

示例配置:

JavaScript 复制代码
const editor = new FluentEditor('#editor', {
  modules: {
    'collaborative-editing': {
      provider: {
        type: 'websocket',
        options: {
          serverUrl: 'wss://demos.yjs.dev/ws',
          roomName: 'my-unique-document-id',
        },
      },
    },
  },
});

WebRTC Provider

注意: 需要额外安装 WebRTC 依赖 pnpm i y-webrtc。使用这种方式采用点对点连接,不需要中心化的 WebSocket 服务器,更适合低延迟和对网络拓扑有特殊要求的场景。

参数 类型 必填 默认值 说明
type 'webrtc' - 提供者类型
roomName string - 房间名称
signaling string[] - 信令服务器列表
filterBcConns boolean - 是否过滤广播连接
maxConns number - 最大连接数
password string - 房间密码
peerOpts Record<string, unknown> - WebRTC 对等连接选项

示例配置:

JavaScript 复制代码
const editor = new FluentEditor('#editor', {
  modules: {
    'collaborative-editing': {
      provider: {
        type: 'webrtc',
        options: {
          roomName: 'tiny-editor-webrtc-demo',
          signaling: ['wss://signaling.yjs.dev'],
        },
      },
    },
  },
});

Awareness 配置

Awareness 模块负责同步用户的在线状态、光标位置和选区。通过配置,你可以自定义用户的显示信息。

Awareness 实现用户在线状态、光标位置等信息的实时同步。每个用户的在线状态、名称、颜色、光标位置等会自动广播给其他协作者,实现多人编辑时的身份和操作可视化。

参数 类型 必填 说明
state AwarenessState 用户状态信息
timeout number 用户状态超时时间(ms)

AwarenessState 结构

参数 类型 必填 默认值 说明
name string User ${id} 用户名称
color string #ff6b6b 用户颜色,用于光标和选区的颜色显示

示例配置:

JavaScript 复制代码
awareness: {
  state: {
    name: `user${Math.random().toString(36).substring(2, 8)}`,
    color: `#${Math.floor(Math.random() * 16777215).toString(16)}`
  },
  timeout: 30000,
}

Cursors 配置

cursors 默认开启,并且支持以下配置(详细配置可见 quill-cursors):

参数 类型 默认值 说明
template string - 光标模板
hideDelayMs number 5000 光标隐藏延迟时间
hideSpeedMs number 0 光标隐藏动画速度
selectionChangeSource string - 选择变化源
transformOnTextChange boolean true 文本变化时是否转换光标

注意光标模板内的类名不可变

示例配置:

JavaScript 复制代码
const CURSOR_CLASSES = {
  SELECTION_CLASS: 'ql-cursor-selections',
  CARET_CONTAINER_CLASS: 'ql-cursor-caret-container',
  CARET_CLASS: 'ql-cursor-caret',
  FLAG_CLASS: 'ql-cursor-flag',
  NAME_CLASS: 'ql-cursor-name',
}

cursors: {
  template: `
    <span class="${CURSOR_CLASSES.SELECTION_CLASS}"></span>
    <span class="${CURSOR_CLASSES.CARET_CONTAINER_CLASS}">
      <span class="${CURSOR_CLASSES.CARET_CLASS}"></span>
    </span>
    <div class="${CURSOR_CLASSES.FLAG_CLASS}">
      <small class="${CURSOR_CLASSES.NAME_CLASS}"></small>
    </div>
  `,
  hideDelayMs: 300,
  hideSpeedMs: 300,
  transformOnTextChange: true,
}

事件回调

回调函数 参数 说明
onConnect 成功连接到协作服务器时触发
onDisconnect 与协作服务器连接断开时触发
onSyncChange isSynced: boolean 文档同步状态变化时触发,true 表示已同步

自部署后端

TinyEditor 的协同编辑后端服务已为你准备好 Docker 镜像,只需简单几步即可快速部署,无需复杂的本地环境配置。

1. 准备 Docker 环境

确保你的机器上已安装 DockerDocker Compose

2. 拉取镜像并配置

在你的项目根目录下,创建一个 docker-compose.yml 文件和一个 .env 文件。

docker-compose.yml 此文件定义了两个服务:mongodb(用于数据持久化)和 websocket-server(协同编辑后端服务)。

YAML 复制代码
services:
  mongodb:
    image: mongo:latest
    container_name: yjs-mongodb
    restart: always
    ports:
      - '27017:27017'
    environment:
      MONGO_INITDB_ROOT_USERNAME: admin
      MONGO_INITDB_ROOT_PASSWORD: admin!123
    volumes:
      - mongodb_data:/data/db

  websocket-server:
    image: yinlin124/collaborative-editor-backend:latest
    container_name: yjs-websocket-server
    restart: always
    ports:
      - '${PORT:-1234}:${PORT:-1234}'
    env_file:
      - .env
    depends_on:
      - mongodb

volumes:
  mongodb_data:

.env 此文件用于配置服务参数,例如端口和数据库连接信息。

ini 复制代码
HOST=0.0.0.0
# 注意:此处的 PORT 必须与前端配置中的 serverUrl 端口一致
PORT=1234
MONGODB_URL=mongodb://admin:admin!123@mongodb:27017/?authSource=admin
MONGODB_DB=tinyeditor
MONGODB_COLLECTION=documents
GC=true
变量名 必需 默认值 说明
HOST - 服务器监听地址
PORT - WebSocket 服务端口
MONGODB_URL - MongoDB 连接字符串
MONGODB_DB - MongoDB 数据库名称
MONGODB_COLLECTION - MongoDB 集合名称
GC true 是否启用 Yjs 垃圾回收

3. 一键启动服务

在项目根目录下运行 docker-compose 命令,Docker 会自动下载镜像、创建容器并启动服务。

Bash

复制代码
docker compose up -d

后端启动后将前端编辑器配置中的 serverUrl 改成对应的服务器 IP:port


更多需求

如果你有自定义持久化或者自定义 provider 等需求可查看文档:opentiny.github.io/tiny-editor...,有任何问题也可到仓库提 issue。

相关推荐
华玥作者2 小时前
[特殊字符] VitePress 对接 Algolia AI 问答(DocSearch + AI Search)完整实战(下)
前端·人工智能·ai
Mr Xu_2 小时前
告别冗长 switch-case:Vue 项目中基于映射表的优雅路由数据匹配方案
前端·javascript·vue.js
前端摸鱼匠2 小时前
Vue 3 的toRefs保持响应性:讲解toRefs在解构响应式对象时的作用
前端·javascript·vue.js·前端框架·ecmascript
lang201509283 小时前
JSR-340 :高性能Web开发新标准
java·前端·servlet
好家伙VCC3 小时前
### WebRTC技术:实时通信的革新与实现####webRTC(Web Real-TimeComm
java·前端·python·webrtc
未来之窗软件服务4 小时前
未来之窗昭和仙君(六十五)Vue与跨地区多部门开发—东方仙盟练气
前端·javascript·vue.js·仙盟创梦ide·东方仙盟·昭和仙君
嘿起屁儿整4 小时前
面试点(网络层面)
前端·网络
VT.馒头4 小时前
【力扣】2721. 并行执行异步函数
前端·javascript·算法·leetcode·typescript
phltxy5 小时前
Vue 核心特性实战指南:指令、样式绑定、计算属性与侦听器
前端·javascript·vue.js
Byron07076 小时前
Vue 中使用 Tiptap 富文本编辑器的完整指南
前端·javascript·vue.js