vite-plugin-monkey初使用
以往我想写一个用户脚本,我会在Tampermonkey提供的编辑页面编写脚本并进行测试。但是这并不方便,例如当我一个脚本拥有许多功能,在开发时将所有代码编于一个文件可并不是一个好的行为:它会导致编辑器卡顿、代码过长而难以定位函数、可读性下降。并且包括Tampermonkey在内的一系列插件并没有提供一个完好的开发环境。
于是我找到了vite-plugin-monkey,它是一个Vite插件。(Vite 是一个新一代的前端构建工具,旨在提供快速的开发体验。)它使我的开发体验好了不少,因为我可以在完整的IDE内进行开发, 并且我能够使用TypeScript语言(TS是JavaScript的超集,提供了一系列更好的功能),享受IDE带来的错误检测、自动补全。更重要的是,我可以将我编写的用户脚本的各个功能写在不同的ts文件当中,这方便了我的开发过程,使我的程序模块化了。这是好的。除此之外,我还可以方便地使用特殊变量及GM函数(GreaseMonkey API),只要这样就行了:
import {unsafeWindow, GM_xmlhttpRequest} from "$";
在我使用插件unplugin-auto-import后,这一切都变得神秘起来。
美中不足的是,他可能并没有一个绝妙的体验。 它提供一个用户脚本,内容如下:
;((entrySrc) => {
window.GM;
const key = `__monkeyWindow-` + new URL(entrySrc).origin;
document[key] = window;
console.log(`[vite-plugin-monkey] mount monkeyWindow to document`);
if (typeof GM_addElement === "function") {
GM_addElement(document.head, "script", {
type: "module",
src: entrySrc
});
} else {
const script = document.createElement("script");
script.type = "module";
if (window.trustedTypes) {
const policy = window.trustedTypes.createPolicy(key, {
createScriptURL: (input) => input
});
const trustedScriptURL = policy.createScriptURL(entrySrc);
script.src = trustedScriptURL;
} else {
script.src = entrySrc;
}
document.head.append(script);
}
console.log(`[vite-plugin-monkey] mount entry module to document.head`);
})("http://127.0.0.1:5173/__vite-plugin-monkey.entry.js");
然而, 受限于浏览器加载策略和诸如CSP一类的东西,__vite-plugin-monkey.entry.js并没有加载进来。这导致我可能需要手动更新脚本,这十分甚至九分地麻烦。
好在,我找到了一种解决方法:使用Violentmonkey,即“暴力猴”,它可以监控外部修改,当检测到外部修改时重新获取用户脚本,当然也可以选择重载页面;当我修改本地文件时,Vite会自动构建新的用户脚本(使用bunx vite build --watch),这有一种HMR(Hot Module Replacement,热模块替换)的美感。即使有时检测外部修改失败了,这对比以前手动加载也方便得多。
题外话,当我尝试监听window.history时出了点问题,不过我发现我只要unsafeWindow.document.querySelector('#app').__vue__.$router.afterHooks.push(<Function>)就可以了。