scite Zotero插件源码构建、安装与不生效排查
简介:面向科研文献管理与引文语境分析场景的Zotero插件源码包,适合经常使用Zotero、希望快速判断论文被支持、提及或质疑情况的研究者,也便于想学习Zotero插件开发的TypeScript开发者参考。安装后可在文献条目旁查看scite Smart Citation数据中的Supporting、Mentioning与Contrasting分类计数,并跳转至对应站点报告页,帮助在阅读与综述阶段快速把握引用态度。压缩包共31个文件、约1.24MB,以TypeScript源码和JSON配置为主,配合XUL界面文件、PNG/JPG截图、CSS样式、本地化属性文件及许可与说明文档,覆盖插件入口、条目面板与Zotero窗格扩展等模块。已有1166人学习下载。读者可从中了解Zotero插件的基本目录组织、清单与构建配置、界面注入方式及第三方引文数据接入思路,适合按模块阅读和二次开发参考。
1. 装插件前先对齐 Zotero 版本:一次「不兼容」的翻车
有位做文献综述的同行,把 scite zotero 插件的 .xpi 直接拖进 Zotero 窗口,弹窗只回了一句话:此插件与此版本的 Zotero 不兼容。他以为是下载坏了,重下三次、换浏览器两次,最后才发现是插件清单里写死的兼容区间和本机 Zotero 大版本对不上。这种翻车在 scite 这类插件上格外常见:它本体是个 TypeScript 工程,仓库里给的是源码,.xpi 得自己构建,构建时用的编译目标和 manifest 里的版本区间,共同决定了产物能落在哪一版 Zotero 上。装不好的表现不是功能少一点,而是条目面板里那块引文语境区域整块消失,你连报错都找不到地方看。下面按我实际走过的顺序,从环境清点、源码构建、安装启用,一路写到怎么验证它真的在干活。
2. 环境清单:Node、TypeScript 与 Zotero 版本怎么配
动手之前先把版本这件事定死。TypeScript 项目的特点是「源码能编译」和「产物能装进 Zotero」是两件事,前者由 Node 工具链决定,后者由 manifest 里的兼容声明决定,两边任意一边错位,你都会在最后一步被拦住,而且报错信息往往只有一行,不给上下文。我踩过的坑里,大半不是代码问题,是版本矩阵没对齐。
2.1 四个版本维度摊开看
先把要确认的东西列成一张表,照着填一遍,比出了事再回头翻要省事得多:
| 维度 | 我一般选什么 | 判断依据 | 配错的典型后果 |
|---|---|---|---|
| Zotero 客户端 | 7.x 分支(旧机器留 6.x) | manifest 里applications.zotero的区间 | 安装阶段直接被拒,拖都拖不进去 |
| Node.js | 当前 LTS(20 或 22) | package.json的engines字段 | npm ci直接报 engine 不匹配退出 |
| npm | 随 Node 自带即可 | 是否支持 lockfile v3 | 依赖树和 lock 文件对不上,构建产物缺模块 |
| TypeScript | 用 devDependencies 里声明的 | package.json里的版本约束 | 编译报语法错,或 target 降不到目标运行时 |
判断顺序我习惯反过来:先看本机 Zotero 是大版本几,再决定拉哪个分支的源码,最后才去装 Node。顺序颠倒的后果是,你装好了最新 Node、编译通过了,打包出来装不进去,白忙一轮。
2.2 Node 装哪一份:版本管理器优先
不建议直接用系统自带的 Node。macOS 上通过 Homebrew 装的 Node 会跟着系统包升级乱跳,某天npm run build突然报一堆ERR_REQUIRE_ESM,回头查半天发现是 Node 大版本被顺手升了。常见做法是用版本管理器隔离:
# 没有版本管理器的话,macOS 上先 brew install nvm,Linux 用发行版包管理器装 nvm install --lts # 装当前 LTS nvm use --lts # 当前 shell 切过去 node -v # 把输出记进构建记录,出问题好回溯 npm -v三行命令里,nvm install --lts装的是 LTS 线,不是 latest,这一点很关键:TypeScript 的编译链和打包插件对 latest 的支持往往滞后一两个大版本,用最新的反而容易撞上依赖包还没跟上的情况。node -v的输出建议直接抄进你的部署笔记,插件构建失败时,第一件要核对的就是「当时用的是哪个 Node」。
Windows 上对应的做法是装 nvm-windows,命令基本一致;如果机器上只能有一个 Node,那就选 LTS 的偶数版本,别选奇数版。
2.3 TypeScript 不要全局装
很多人习惯npm i -g typescript,然后用全局tsc编译。在这个项目里我不建议这么干,原因很实际:仓库的package.json里通常已经把 TypeScript 钉在某个小版本上,全局版本和它不一致时,tsc读的是全局那份,编出来的东西可能跟作者预期的不一样,而npm run build走的又是本地那份,两边结果对不上,排查起来极其难受。
正确姿势是依赖装进本地,用npx或 npm scripts 调用:
{ "compilerOptions": { "target": "ES2020", "module": "ESNext", "moduleResolution": "bundler", "strict": true, "sourceMap": true, "outDir": "build" }, "include": ["src/**/*.ts"] }这段tsconfig.json里真正影响能不能跑的是target。Zotero 7 的内核版本比较新,ES2020甚至更高都能吃下;如果你的机器还停在 Zotero 6,就要往下压到ES2018左右,否则运行时会报语法错误,而且报错位置在 Zotero 的错误控制台里,不在构建日志里,很容易被忽略。sourceMap建议打开,插件出问题时堆栈能映射回 .ts 源码,比对着编译后的 JS 猜要快得多。outDir要和打包脚本约定的目录一致,仓库里如果已经写了,以仓库为准,别自己另起一套。
提示:仓库自带的
tsconfig.json优先。只有当它缺target或outDir时才手工补,补完在提交记录里写一句为什么改,方便下次升级时判断要不要保留。
2.4 目录与数据位置的约定
工作目录和数据目录要分开,这一点在插件开发里格外重要,因为你会反复装、卸、重启:
mkdir -p ~/work/zotero-plugins # 源码都放这儿 cd ~/work/zotero-plugins # Zotero 的数据目录在「设置 → 高级 → 文件和文件夹 → 显示数据目录」里查 # profile 目录(prefs.js 所在)和上面那个不是同一个,别搞混数据目录里放的是文献库和附件,profile 目录里放的是prefs.js、插件安装记录和缓存。升级插件前要备份的是 profile,迁移文献库要备份的是数据目录,两件事经常被混为一谈。我一般的做法是:动手前把两个目录各复制一份到~/work/zotero-backup/下面,命名带日期,出事了直接整份换回来,比任何修复手段都快。
3. 从源码到 .xpi:TypeScript 项目构建全流程
这一步是把一堆 .ts 文件变成 Zotero 认得的安装包。流程本身不长,四条命令,但每一步都有容易走偏的地方,尤其是产物结构和 manifest 的兼容声明。
3.1 拉代码与目录认读
git clone <仓库地址> scite-zotero-plugin cd scite-zotero-plugin ls -la拉下来先别急着装依赖,花两分钟看清目录里有什么,能省掉后面一半的瞎猜。要认的文件是这几个:package.json里的scripts段决定了构建命令叫什么(有的项目叫build,有的拆成build和build:zip两步);manifest.json决定插件 id、名称和兼容区间;src/下是 TypeScript 源码;tsconfig.json决定编译目标。如果目录里同时存在manifest.json和src/manifest.json,说明构建过程会把后者复制到产物根目录,改配置要以源码里那份为准,改根目录那份下次构建就被覆盖了。
Zotero 7 之后插件走的是 manifest 驱动,不再需要bootstrap.js;如果你在源码里看到bootstrap.js且项目同时声明支持 7,那多半是为兼容 6 留的分支。这一点会影响你选哪个分支来构建。
3.2 npm install:lockfile 与镜像的取舍
# 仓库里有 package-lock.json 就优先用它,装出来的依赖树和作者一致 npm ci # 没有 lock 文件时退回普通安装 npm installnpm ci和npm install的差别不只是快慢:ci会严格按 lock 文件装,装完不改 lock,适合复现别人的构建环境;install会解析版本区间,可能装出比作者新的次版本,某些包的破坏性变更就藏在这种「小版本升级」里。我遇到过编译通过但产物运行时报undefined is not a function的情况,最后查出来就是一个工具包的次版本改了导出方式。
网络慢的时候可以换镜像源,但换完记得确认装出来的包没缺文件:
npm config get registry # 先看当前源 # 需要时临时指定,不要全局改死,免得影响别的项目 npm ci --registry=<你的镜像地址>装完看一眼node_modules的顶层目录数量,和package.json的依赖数量大致对得上就基本没问题。少了一大截,通常是网络中断被 npm 静默跳过了。
3.3 构建:一条命令与产物定位
npm run # 不带参数会列出所有可用脚本 npm run build # 常见的主构建命令 ls -lh build/ # 产物一般落在 build/ 或 dist/先跑npm run看脚本列表是个好习惯,有的项目把打包拆成build(只编译)和package(编译 + 打 zip),只跑前者拿不到 .xpi,你会对着一个满是 js 文件的目录发呆。真正的产物应该是单个 .xpi 文件,本质是个 zip 包,里面根目录直接躺着manifest.json。
拿到产物后建议先验一下内部结构,这一步能提前发现一半的安装失败:
# 看压缩包根目录是不是直接有 manifest.json unzip -l build/*.xpi | head -20如果输出的路径是scite-zotero-plugin/manifest.json而不是manifest.json,说明打包时把外层目录一起塞进去了,装的时候 Zotero 会报清单解析失败。手工重打一遍就行:
cd build/<解压出来的目录> && zip -r ../fixed.xpi . -x "*.DS_Store"命令里的.表示「打包当前目录的内容」而不是「打包当前目录」,这个区别就是上面那个问题的根源;-x用来排除 macOS 的隐藏文件,这类文件混进 xpi 有时会让校验失败。
3.4 改兼容区间:只有源码构建才有的这一步
如果你从源码构建,兼容区间是可以调的,这也是自建版本相对成品包唯一有实际价值的地方。打开manifest.json,只看这一段(片段,不是完整文件):
{ "applications": { "zotero": { "id": "<保持仓库里的原值,不要改>", "strict_min_version": "7.0", "strict_max_version": "7.*" } } }strict_min_version是这个插件能装的最低客户端版本,strict_max_version是上限,写成7.*表示 7 系列的任意小版本都放行。装不进去时,九成是这里和你的客户端版本对不上:比如你机器上是 7.0.x,而源码里写的是7.1,就会直接被拒。把下限调低、上限放宽,重新构建一次即可。
id这一项千万别动。插件 id 是它在你 profile 里的身份,改了之后等于换了一个新插件,旧的那份还在,两份同时启用会出现面板重复渲染甚至互相抢配置的情况。真需要并存两套(比如一个原版一个自改版),改 id 的同时也要把name改掉,否则插件列表里两个一模一样的名字,你自己都分不清哪个是哪个。
4. 把插件装进 Zotero:安装、启用与 scite 相关配置
构建出 .xpi 只算完成一半,安装和启用阶段的坑同样密集,尤其是「装进去了但不生效」这种既不报错也没提示的情况。
4.1 两条安装路径,先选对入口
图形界面安装是主路径。Zotero 7 里在「工具 → 插件」,点右上角齿轮,选「Install Plugin From File…」,挑你构建好的 .xpi;Zotero 6 的入口叫「工具 → 附加组件」,操作类似。装完必须重启客户端,不重启的话面板不会重新注册,你会以为没装上。
第二条路径是测试环境隔离,我强烈建议第一次装自构建插件时走这条:
# 启动时进入配置文件管理器,新建一个干净的测试 profile zotero -P-P参数会拉起配置文件管理器,新建一个空 profile 后启动,等于给你一块不受干扰的试验田。在你原有 profile 里反复装卸插件,残留的配置和缓存会互相污染,最后你分不清是插件的问题还是环境污染。测试 profile 里验证通过,再回到主 profile 装一次,两步走比一步到位靠谱。
4.2 启用后要检查的几项
插件装好、重启之后,先确认它在插件列表里是启用状态,然后去「设置 → 高级 → 配置编辑器」搜一下插件相关的键,看有没有成功写入。这一步的意义在于:如果配置项压根没写进去,说明插件加载时就在初始化阶段挂了,问题在代码或清单,不在你的操作。
接着确认数据来源。scite 这类引文语境插件的数据不是本地算出来的,要联网取,取值范围取决于账号权限——没登录和登录后看到的字段可能不一样,机构订阅和个人账号能看到的明细也不同。所以第一次启用后,先拿一篇确定被引过多次的期刊文章做测试,别拿刚发表、引用数为零的新文章试,那种情况下界面空白是正常的,很容易被误判成故障。
面板显示位置也值得调一下。条目面板的区块顺序可以在设置里拖动,把它放在摘要下面还是放在下面板,取决于你平时看文献的习惯;我一般放上面板靠下,滚两下就能看到,不用来回切标签页。
4.3 备份与升级保留
升级插件前,把 profile 里跟插件相关的部分备份出来:
# 升级前备份数据目录,命名带日期,回滚时直接换回 tar -czf ~/work/zotero-backup-$(date +%Y%m%d).tar.gz ~/Zotero真正的配置在 profile 目录的prefs.js里,不在数据目录。稳妥做法是两个都备:数据目录管文献,profile 管插件配置。升级时先卸载旧版、重启、再装新版,不要直接覆盖安装——覆盖安装在某些版本上会保留旧的注册信息,导致新版的部分功能不生效,表现是新版界面出来了但新逻辑没跑起来,最难查。
5. 排查:插件装了不生效的 5 个常见坑
下面五条都是我在不同机器上真实遇到过的,按「现象 → 原因 → 解决」写,遇到问题时对照着看,比从头读日志快。
5.1 插件列表里有,条目面板里没有区块
现象:插件管理里能看到它、状态是启用,但打开任意一条文献,侧栏里找不到引文语境那块区域。
原因:大概率是面板注册没生效,或者当前选中的条目类型不在插件支持范围内。附件、笔记、独立便签这些条目通常不会触发引文查询,界面上自然什么都不显示。
解决:先换一条正儿八经的期刊文章条目再看;还是没有,打开「工具 → 开发者 → 错误控制台」,重新选中条目,看有没有新抛出的异常。有异常基本就是面板注册代码在启动时失败了,通常是版本不匹配导致某个 API 不存在。
5.2 安装时被拒:此插件与此版本不兼容
现象:拖入或选择 .xpi 的瞬间弹窗被拦,插件根本没进列表。
原因:manifest.json里strict_min_version/strict_max_version的区间不覆盖你当前的客户端大版本。
解决:按 3.4 节改区间、重新构建、重装。如果你用的是别人构建好的包,那就只能去找对应大版本的构建产物,别硬改 zip 里的清单——手工改完再压缩,很容易破坏包结构,变成 5.3 那种情况。
5.3 装的时候报清单解析失败或装上后是空壳
现象:安装过程没报「不兼容」,但提示加载失败,或者装上了却完全没反应。
原因:xpi 内部结构错了,manifest.json不在压缩包根目录,而是被套了一层目录;也可能是混进了.DS_Store、__MACOSX这类文件。
解决:用unzip -l看结构,确认manifest.json直接在根;不对就按 3.3 节的方法进到目录内部重新打包,打包时排除隐藏文件。
5.4 区块出来了,但一直转圈或显示获取失败
现象:界面区域在,内容一直加载中,或者明确提示获取数据失败。
原因:网络出口到接口不通、请求被拦、或者请求超时设得太短。TypeScript 编译出来的代码跑在 Zotero 的运行时里,网络行为和浏览器不完全一样,某些在企业内网里能过浏览器的地址,在这里不一定通。
解决:先从调试输出日志里把实际请求的地址复制出来,单独用命令行打一遍,能通再回来调超时;不通就先解决网络可达性,别在插件里瞎改。
# 把日志里的请求地址粘到下面,只看状态码,不看内容 curl -sS -o /dev/null -w "%{http_code}\n" "<从日志里复制的地址>"-o /dev/null丢弃响应体,-w只打印状态码,这样输出干净,一眼能看出是 200 还是超时。返回 000 通常是连接层面就没通,返回 4xx 则是权限或参数问题,两种方向完全不同。
5.5 升级之后行为没变,像没升一样
现象:装了新版本,重启了,界面看着是新的,但某个修过的行为依旧。
原因:旧版没卸干净,或者 profile 里的缓存还在用旧数据。
解决:卸载 → 重启 → 确认插件列表里已经消失 → 再装新版 → 再重启。缓存目录在 profile 下,找不到就整个 profile 备份后重建一个测试用,验证通过再迁回主 profile。
6. 装完怎么算跑通:三个验证动作与一个日志习惯
装完不等于跑通。我给自己定了一套固定动作,每次装完插件都走一遍,三五分钟,能挡掉后面八成「以为好了其实没好」的尴尬。
6.1 三个动作,按顺序做
第一个动作:挑一篇引用数明显不为零的期刊文章,选中它,看条目面板里的引文语境区块。要看的不是「有没有内容」,而是「数字对不对得上」——支持、对比、提及三类加起来应该等于总数,对不上说明某类数据没取全,界面看着正常,实际是残缺的。
第二个动作:打开「帮助 → 调试输出日志」,清空,再重新选中一次条目,看有没有异常行刷出来。这一步能抓到那些不影响主流程、但会持续拖慢加载的错误。
第三个动作:断网,再点一次。合格的表现是给出一个明确的「获取失败」提示,界面结构还在;不合格的表现是整块区域消失、或者界面卡住不动。降级行为做得好不好,比正常路径更能说明这个插件在你这台机器上能不能长期用。
| 验证项 | 期望现象 | 不符时先查哪里 |
|---|---|---|
| 分类计数 | 三类之和等于总数 | 接口返回是否被截断 |
| 调试日志 | 无新增异常行 | 版本区间与 API 兼容性 |
| 断网降级 | 有提示、界面不崩 | 请求超时与错误处理逻辑 |
6.2 一个日志习惯
我现在的习惯是:每次装完插件,先把调试输出日志开着用半天,确认没有反复刷的错误再关。插件这种东西,出问题的时候往往不报错,只是安静地少显示一块,你不主动看日志根本发现不了。
从那以后我每次装 Zotero 插件,不管是谁构建的包,都强制走一遍「测试 profile 装 → 三个动作验 → 日志看半天 → 再进主 profile」这条线。麻烦是麻烦了点,但比在写论文的中途发现引文数据一直是空的要好得多。这套源码和构建脚本在项目页上都能拿到,按第 2 章到第 4 章的顺序走,第一遍基本能通。希望帮到你。
本文还有配套的精品资源,点击获取