Vditor 3.10.9 编译报错:排查 diff-match-patch 类型与临时 ts-nocheck

Vditor 3.10.9 的 TypeScript 编译错误怎么排查

给 WordPress 前台投稿接入 Markdown 编辑器时,可以先在本地运行 Vditor 的源码示例,再处理实际集成。本文围绕 Vditor 3.10.9 的一组类型错误展开:Webpack 启动后报告 3 个错误,涉及撤销模块和 diff-match-patch 的类型声明。

源码没有修改也可能遇到编译失败。除了编辑器版本,还要核对包管理器、锁文件和实际安装的依赖版本。

Vditor 类型排障配图 1

终端最后一行通常只是构建结果摘要。看到“3 errors”后应向上查看完整日志,而不是只凭最后一行判断原因。

Vditor 类型排障配图 2

一、报错现场与完整日志

这组记录的环境显示 Node.js 22.14.0、Vditor 3.10.9 和 Webpack 5.98.0。这里保留完整日志用于对照;这些历史版本号不是给新项目的统一安装建议。

webpack 5.98.0 compiled with 3 errors in 32147 ms

错误日志:

Node.js v22.14.0
PS C:\Users\19928\Downloads\vditor-3.10.9 (2)\vditor-3.10.9> npm start

> vditor@3.10.9 start
> webpack serve --config webpack.start.js

<i>   Proxy created: /api  -> http://localhost:8080
<i>   Proxy rewrite rule created: "^/api" ~> ""
<i>   Proxy created: /ld246  -> https://ld246.com
<i>   Proxy rewrite rule created: "^/ld246" ~> ""
<i>  Project is running at:
<i>  Loopback: http://localhost:9001/, http://[::1]:9001/
<i>  On Your Network (IPv4): http://192.168.23.1:9001/
<i>  Content not from webpack is served from 'C:\Users\19928\Downloads\vditor-3.10.9 (2)\vditor-3.10.9' directory
<i>  wait until bundle finished: /
assets by path js/ 20.1 MiB 386 assets
assets by path ../../dist/ 34.1 KiB 110 assets
assets by path images/ 69.6 KiB
  assets by path images/emoji/*.png 52.9 KiB 16 assets
  + 3 assets
assets by path *.js 3.66 MiB
  asset comment.js 1.1 MiB  (name: comment.js)
  + 3 assets
assets by path ./*.html 19.9 KiB
  asset ./render.html 6.73 KiB
  + 3 assets
assets by path css/content-theme/*.css 12.9 KiB
  asset css/content-theme/ant-design.css 4.77 KiB
  + 3 assets
asset types/index.d.ts 26.1 KiB
runtime modules 110 KiB 52 modules
modules by path ./src/ 644 KiB
  modules by path ./src/ts/ 575 KiB 108 modules
  modules by path ./src/*.ts 24.8 KiB 2 modules
  modules by path ./src/assets/less/*.less 44.6 KiB 2 modules
modules by path ./node_modules/ 193 KiB
  modules by path ./node_modules/webpack-dev-server/client/ 86.9 KiB 8 modules
  modules by path ./node_modules/webpack/hot/*.js 5.2 KiB 4 modules
  + 5 modules
modules by path ./demo/*.js 15.1 KiB
  ./demo/index.js 2.9 KiB
  ./demo/render.js 2.77 KiB
  ./demo/jest-puppeteer.js 4.6 KiB
  ./demo/comment.js 4.83 KiB

ERROR in C:\Users\19928\Downloads\vditor-3.10.9 (2)\vditor-3.10.9\src\ts\undo\index.ts
./src/ts/undo/index.ts 20:17-48
 ERROR in C:\Users\19928\Downloads\vditor-3.10.9 (2)\vditor-3.10.9\src\ts\undo\index.ts(20,18)
      TS2749: 'DiffMatchPatch.diff_match_patch' refers to a value, but is being used as a type here. Did you mean 'typeof DiffMatchPatch.diff_match_patch'?
 @ ./src/index.ts 42:0-39 473:31-35
 @ ./demo/comment.js 1:0-34 94:20-26

ERROR in C:\Users\19928\Downloads\vditor-3.10.9 (2)\vditor-3.10.9\src\ts\undo\index.ts
./src/ts/undo/index.ts 139:35-40
 ERROR in C:\Users\19928\Downloads\vditor-3.10.9 (2)\vditor-3.10.9\src\ts\undo\index.ts(139,36)
      TS7006: Parameter 'patch' implicitly has an 'any' type.
 @ ./src/index.ts 42:0-39 473:31-35
 @ ./demo/comment.js 1:0-34 94:20-26

ERROR in C:\Users\19928\Downloads\vditor-3.10.9 (2)\vditor-3.10.9\src\ts\undo\index.ts
./src/ts/undo/index.ts 140:37-41
 ERROR in C:\Users\19928\Downloads\vditor-3.10.9 (2)\vditor-3.10.9\src\ts\undo\index.ts(140,38)
      TS7006: Parameter 'diff' implicitly has an 'any' type.
 @ ./src/index.ts 42:0-39 473:31-35
 @ ./demo/comment.js 1:0-34 94:20-26

3 errors have detailed information that is not shown.
Use 'stats.errorDetails: true' resp. '--stats-error-details' to show it.

webpack 5.98.0 compiled with 3 errors in 32147 ms
终端中的构建输出与类型错误
终端中的构建输出与类型错误

构建过程能生成部分资源,仍可能因为类型检查失败而返回错误。终端或浏览器暂时没有新的输出,不表示没有诊断信息。

Vditor 类型排障配图 4
  • TS2749 位于 src/ts/undo/index.ts 的第 20 行,第 18 列。
  • TS7006 分别位于第 139 行和第 140 行,提示 patch、diff 参数被隐式推断为 any。
  • 日志还包含模块引用链,以及启用更详细错误输出的提示。
开发服务器显示的三个编译错误
开发服务器显示的三个编译错误

这三项都是编译阶段的 TypeScript 诊断,现有日志不能归因于 CDN。定位文件是:

vditor-3.10.9\src\ts\undo\index.ts
Vditor 类型排障配图 6

二、先明确 @ts-nocheck 的作用

没有写 @ts-nocheck 是正常状态,不能据此判断代码作者是否“偷懒”。TypeScript 默认会检查类型;当源码使用方式和依赖声明不匹配时,报错是在提示需要继续排查。

Vditor 类型排障配图 7

如果只想暂时观察后续构建结果,可以在上述文件的最开头添加:

//@ts-nocheck

这是历史排障时使用的临时做法。TypeScript 3.7 起,位于 TypeScript 文件顶部的 @ts-nocheck 可以关闭该文件的语义检查。它可能让构建继续,但不会修正依赖声明,也不会证明撤销、重做或编辑器运行正常。具体作用见 TypeScript 官方说明。

Vditor 类型排障配图 8

这个注释的范围是整份文件,不只屏蔽眼前的三条错误。需要验证真正修复时,应先移除临时添加的注释,再运行类型检查;不要把“没有报错”和“类型已经正确”混为一谈。

三、核对源码、锁文件和实际安装版本

在 Vditor 3.10.9 源码目录中记录环境和解析到的类型包。下面按 Windows PowerShell 编写,与上面的错误日志对应:

node --version
npm --version
node -p "require('./package.json').version"
npm ls typescript diff-match-patch @types/diff-match-patch --depth=0
node -p "require.resolve('@types/diff-match-patch/package.json')"
Get-Content .\node_modules\@types\diff-match-patch\index.d.ts

核对 v3.10.9 的 package.json 和 同一 tag 的 pnpm-lock.yaml,可以看到:

  • package.json 对 @types/diff-match-patch 声明的范围是 ^1.0.32,锁文件实际固定为 1.0.32。
  • TypeScript 的声明范围是 ^4.9.5,锁文件实际固定为 4.9.5。
  • diff-match-patch 运行库的锁定版本为 1.0.5。

版本范围和已经安装的精确版本是两回事。只查看 package.json,或者在没有匹配锁文件的情况下重新安装,不能证明环境与这个 tag 一致。使用 npm 也不会按 pnpm-lock.yaml 还原依赖。若项目已有可信且匹配的 package-lock.json,可按 npm 的 npm ci 说明重建;若选择沿用该 tag 的 pnpm 锁文件,应使用兼容的 pnpm,并按 frozen-lockfile 方式安装。不同包管理器的恢复路径不要混用,也不要把删除锁文件当成第一步。

四、这组三个错误怎样形成

v3.10.9 撤销模块源码把 dmp 声明为 DiffMatchPatch.diff_match_patch,并在后续调用 patch_deepCopy 后遍历 patch 与 diff。@types/diff-match-patch 1.0.32 中 diff_match_patch 是导出的 class,符合这处类型写法。

在 1.0.36 的声明里,模块改为 export = diff_match_patch,diff_match_patch.diff_match_patch 是静态值成员。继续把这一成员直接写在类型位置,就会得到 TS2749;dmp 的类型异常又会影响后续回调参数的推断,产生另外两条 TS7006。

对完整 v3.10.9 src 目录进行隔离静态验证时,TypeScript 4.9.5 搭配声明包 1.0.36,准确复现了第 20、139、140 行的这三条错误;改用 tag 锁定的 1.0.32 后,同一份源码通过 tsc --noEmit。这个结果说明依赖声明变化足以造成该现象。原记录没有附当时的锁文件和 npm ls 输出,因此不能反向断言当时一定安装了 1.0.36。

也不要机械采用诊断文字里的 typeof 建议:typeof 取得值的类型,这里可能得到构造器类型,而 dmp 保存的是构造出来的实例。换类型写法之前,需要同时核对实例、构造器以及 patch 相关方法的声明,不能只把第一条错误隐藏起来。可参考 TypeScript 的 typeof 类型操作符说明。

五、针对 3.10.9 的可复核修复路径

先保留当前 package.json、锁文件和日志,最好在工作副本或版本分支中处理。若继续使用 npm,且目标就是复现这个历史 tag 的类型组合,可以精确固定下面两个开发依赖。此命令会更新 package.json 和 npm 锁文件;--ignore-scripts 用于这一步只调整依赖而不执行安装脚本:

# 在已备份的 Vditor v3.10.9 工作副本中执行,保留现有锁文件供对照。
# 适用于继续使用 npm 的历史排障路径;不是对所有 Vditor 版本的通用降级建议。
npm install --save-dev --save-exact --ignore-scripts @types/diff-match-patch@1.0.32 typescript@4.9.5
npm ls typescript diff-match-patch @types/diff-match-patch --depth=0
node .\node_modules\typescript\bin\tsc --noEmit --project tsconfig.json

这条路径只针对本文确认的 Vditor 3.10.9 类型问题,不是推荐所有项目降级类型包。安装后仍要确认 diff-match-patch 的实际版本与预期一致,并检查其他依赖的冲突。若要保留较新的声明包,需要按其真实导出结构适配源码,再单独验证所有 patch 方法,不能混用本文的旧声明结论。

在已经固定 1.0.32 的前提下,还可以把构造器写得更明确。v3.10.9 这里原本带有局部 @ts-ignore;以下小补丁保留 dmp 的实例类型,直接调用声明里导出的构造器,并移除这条局部抑制:

--- a/src/ts/undo/index.ts
+++ b/src/ts/undo/index.ts
@@ -24,8 +24,7 @@
 
     constructor() {
         this.resetStack();
-        // @ts-ignore
-        this.dmp = new DiffMatchPatch();
+        this.dmp = new DiffMatchPatch.diff_match_patch();
     }
 
     public clearStack(vditor: IVditor) {

这是可选的源码清理。恢复官方锁定的声明版本后,未打该补丁的完整源码也已通过静态检查;打补丁后的完整源码同样通过。Vditor 代码采用 MIT 许可证,分发源码或其重要部分时应保留相应版权与许可文本。

六、修复后怎么验收

先删掉临时添加的整文件 @ts-nocheck,再检查类型。确认脚本与依赖适合本地环境后,分别检查构建和演示页面:

# 先移除 src/ts/undo/index.ts 文件顶部为排障添加的 //@ts-nocheck。
# 使用已经安装的项目 TypeScript,避免 npx 临时拉取另一版本。
node .\node_modules\typescript\bin\tsc --noEmit --project tsconfig.json
# 核对项目脚本、依赖和本地环境后,再分别验证构建与演示。
npm run build
npm run start
  1. 静态检查应真实通过,而不是依靠整文件抑制。
  2. 构建与启动各自成功;演示地址以本次终端输出为准,不照抄历史日志的端口。
  3. 在所见即所得、即时渲染和分屏预览模式中分别输入内容,测试撤销、重做、连续操作和模式切换。
  4. 检查浏览器控制台和资源请求。若之后出现 CDN 加载问题,再按具体网络错误另行处理。
  5. 保留最终锁文件,让同一组合可以复现。

本文修复验证覆盖完整 v3.10.9 src 的 TypeScript 静态检查,以及 diff-match-patch 1.0.5 的隔离文本 patch 正向应用与反向应用;没有运行 Vditor 的安装生命周期、Webpack 构建、开发服务器或浏览器端编辑器。因此不能据此宣称所有 UI 功能都已验收。最终接入 WordPress 时,还应完成上面的浏览器操作检查。

这类问题的处理顺序很简单:先读完整日志,确认实际依赖版本,再按准确的类型声明修复。临时绕过可以帮助继续排查,但最终应回到可检查、可复现的依赖和源码组合。

Vditor 类型排障配图 9
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享
评论 抢沙发

请登录后发表评论

    暂无评论内容