feat(web): 富文本编辑器换成 Vditor,不再自研轮子
CI / backend (push) Canceled after 0s

上一版我自己写了 textarea + 正则工具栏,看着能用,一到粘贴图片、
中文输入法、撤销栈就露馅——这几样正是成熟组件积累的部分。按要求改成品。

- 编辑器开关 def: RichTextEditor = Vditor 4.0.1(MIT,ir 模式)
  * 运行时资源自托管:web/scripts/vendor-vditor.mjs 把 lute/i18n/icons
    同步到 public/vditor,predev/prebuild 自动执行,不走 unpkg CDN
    (内网会一直卡在加载)
- 只读渲染换 markdown-it + dompurify,删掉自写的正则渲染器
- 附件直链的令牌只在内存里存在:落库前 stripAttachmentTokens,
  渲染/装载前补回(<img> 带不了 Authorization 头,raw?token= 是必要折中)
- Vditor 不会替我们插入 upload.handler 的返回值(只当提示语 tip.show),
  所以上传完自己 insertMD

验证:pytest 70 passed;e2e richtext 13 项、smoke 7、tickets 8、
knowledge 7 全绿;tsc 0 错;主包 299 kB/gzip 75 kB,Vditor 独立
chunk 385 kB 按需加载。
This commit is contained in:
dadao
2026-10-29 02:30:10 +08:00
parent 7a7ea932a4
commit fbdf54cb4c
18 changed files with 630 additions and 419 deletions
+48
View File
@@ -0,0 +1,48 @@
/**
* 把 Vditor 的运行时资源同步到 public/vditor。
*
* 为什么不用它的默认 CDN:Vditor 会按需去 `unpkg.com/vditor@<版本>` 拉 lute(3.7 MB
* 的 Markdown 引擎)、语言包和图标。内网、离线、或者被墙的环境下,编辑器会一直停在
* 加载状态,而失败信息只有控制台一行 404。
*
* 这里只复制真正需要的几样,`public/vditor` 不进版本库(见 .gitignore),
* 由 `predev` / `prebuild` 自动生成,升级 Vditor 后自然跟着更新。
*/
import { copyFileSync, existsSync, mkdirSync } from "node:fs";
import { dirname, join } from "node:path";
import { fileURLToPath } from "node:url";
const here = dirname(fileURLToPath(import.meta.url));
const webRoot = join(here, "..");
const source = join(webRoot, "node_modules", "vditor", "dist");
const target = join(webRoot, "public", "vditor", "dist");
const files = [
"js/lute/lute.min.js",
"js/i18n/zh_CN.js",
"js/i18n/en_US.js",
"js/icons/ant.js",
"js/icons/material.js",
];
if (!existsSync(source)) {
console.error("[vendor-vditor] 没找到 node_modules/vditor,先跑一次 npm install");
process.exit(1);
}
let copied = 0;
for (const rel of files) {
const from = join(source, rel);
if (!existsSync(from)) {
console.warn(`[vendor-vditor] 跳过(包里没有): ${rel}`);
continue;
}
const to = join(target, rel);
mkdirSync(dirname(to), { recursive: true });
copyFileSync(from, to);
copied += 1;
}
console.log(`[vendor-vditor] 已同步 ${copied} 个文件到 public/vditor/dist`);