拓冰建站拓冰建站
首页 / 资讯中心 / 正文

油猴脚本本地开发指南:从环境搭建到工程化实践

1. 从“安装即用”到“自己动手”为什么你需要本地开发油猴脚本如果你用过油猴Tampermonkey或者类似的用户脚本管理器大概率体验过那种“一键安装网页大变样”的爽快感。网上有海量的现成脚本帮你屏蔽广告、增强功能、自动填充几乎无所不能。但不知道你有没有遇到过这种情况找到一个心仪的脚本却发现某个小功能不符合你的习惯或者脚本因为网站改版而失效作者却迟迟没有更新又或者你脑子里冒出一个绝妙的点子想给某个常逛的网站加点“私货”却不知道从何下手。这时候“本地开发”就成了那把关键的钥匙。它意味着脚本文件不再是从某个远程服务器下载而是直接存放在你的电脑上由你亲手编写、调试和修改。听起来有点技术门槛别担心这个过程远比想象中简单。本地开发的核心优势在于“即时反馈”和“完全掌控”。你改一行代码刷新一下网页效果立竿见影。无需等待发布、无需担心版本脚本完全按照你的意志运行。最近像“taptap制造本地开发”这类热词的流行也反映了开发者社区对高效、可控的开发流程的追求。虽然它指向的是游戏模组等特定场景但其内核——在本地环境中快速迭代、测试创意——与我们进行油猴脚本开发是完全相通的。本地开发让你从一个脚本的使用者转变为创造者和定制者。接下来我会带你搭建一个最小化、无痛感的油猴脚本本地开发环境并分享一套我用了多年的高效工作流。2. 环境搭建五分钟搞定你的专属“脚本实验室”进行本地开发你只需要三样东西一个文本编辑器、一个脚本管理器、和一个本地HTTP服务器。别被“服务器”这个词吓到对于我们的需求它简单到只需一行命令。2.1 核心工具选型与安装1. 脚本管理器 (Script Manager)这是脚本的“大脑”和“执行器”。主流选择有两个Tampermonkey (油猴)最流行功能最全支持Chrome、Edge、Firefox等。对中文用户友好有详细的中文文档和庞大社区。Violentmonkey (暴力猴)另一个优秀的选择开源且轻量在一些细节和隐私策略上有所不同。我强烈建议新手选择Tampermonkey因为其调试工具和错误提示对初学者更友好。直接从浏览器的官方扩展商店如 Chrome Web Store、Edge Add-ons搜索安装即可。2. 代码编辑器 (Code Editor)这是你写脚本的“笔”。不要用系统自带的记事本因为它缺乏代码高亮、自动补全等关键功能。Visual Studio Code (VS Code)当前的首选免费、强大、插件生态极其丰富。安装后建议安装“JavaScript (ES6) code snippets”等插件来提升编码效率。Sublime Text / Atom也是优秀的轻量级选择。对于油猴脚本开发VS Code 的轻量、快速启动和强大的内置终端功能让它成为不二之选。3. 本地HTTP服务器 (Local HTTP Server)这是本地开发的关键一环。浏览器出于安全限制同源策略默认无法通过file://协议直接加载本地脚本文件中的某些资源如图片、字体甚至某些AJAX请求。通过一个简单的本地服务器让你的脚本通过http://localhost:xxxx这样的地址被访问就能完美绕过这些限制。搭建它简单到不可思议。打开你的 VS Code并确保安装了 Node.js一个JavaScript运行环境去官网下载LTS版本安装即可。然后在你存放脚本的文件夹里打开终端VS Code里按Ctrl或Cmd# 使用 npmNode.js 的包管理器全局安装一个叫 http-server 的微型服务器 npm install -g http-server安装完成后进入你的脚本项目目录运行http-server -p 8080你会看到类似http://localhost:8080和http://192.168.x.x:8080的输出。现在你的本地服务器就已经在 8080 端口运行了。保持这个终端窗口打开服务器就会一直工作。注意如果你不想安装 Node.js也有更轻量的方法。例如如果你使用 Python可以在项目目录运行python -m http.server 8080Python 3。选择哪种方式取决于你更熟悉哪种环境对于油猴脚本开发它们的效果完全一样。2.2 创建你的第一个本地脚本项目在你的电脑上找一个合适的位置新建一个文件夹例如my-tampermonkey-scripts。在这个文件夹里创建两个文件hello-world.user.js- 这是我们的油猴脚本本体。index.html- 这是一个简单的测试网页用于模拟真实环境非必须但推荐。现在用 VS Code 打开hello-world.user.js输入以下最基础的脚本元信息也称为“头信息”// UserScript // name 我的第一个本地脚本 // namespace http://tampermonkey.net/ // version 0.1 // description 这是一个本地开发的测试脚本 // author You // match https://www.example.com/* // grant none // /UserScript (function() { use strict; console.log(你好世界我的本地脚本生效了); // 你的代码将写在这里 })();让我解释一下这个头信息里关键的几项name: 脚本显示在油猴面板里的名字。match:这是最重要的指令之一它定义了脚本在哪些网址上运行。https://www.example.com/*是一个占位符意味着脚本会在所有以该域名开头的页面上运行。你可以设置多个match行来匹配多个站点。例如match https://*.github.com/*可以匹配 GitHub 的所有子域名。grant: 定义了脚本向浏览器申请的特殊权限。none表示不需要任何特殊权限。如果你需要操作浏览器存储如GM_setValue、发送跨域请求如GM_xmlhttpRequest就需要在这里声明例如grant GM_setValue。保存这个文件。接下来我们需要让 Tampermonkey 知道这个本地脚本的存在。3. 连接与调试建立开发与生效的桥梁有了脚本文件和本地服务器下一步就是让 Tampermonkey 加载它。这里有两种主流方法各有优劣。3.1 方法一使用本地文件路径最简单直接这是最快捷的上手方式。打开 Tampermonkey 的管理面板点击浏览器工具栏上的 Tampermonkey 图标选择“管理面板”。点击左上角的“”号添加新脚本。你会看到一个默认的编辑器。不要在这里写代码。直接按CtrlS(或CmdS) 保存它会创建一个新的、空的脚本。在这个新脚本的编辑界面完全清空编辑器里的所有内容。然后从你的文件管理器里把刚才创建的hello-world.user.js文件直接拖拽到 Tampermonkey 的这个编辑器中。拖拽后编辑器里应该显示了你脚本的全部代码。再次按CtrlS保存。现在你的本地脚本文件就和 Tampermonkey 关联起来了。此后你只需要在 VS Code 里修改并保存hello-world.user.js文件Tampermonkey 里的脚本内容会自动更新。你需要做的只是在网页上刷新一下就能看到修改后的效果。优点设置极其简单修改后自动同步需刷新页面无需处理服务器。缺点脚本的“源”在 Tampermonkey 内部严格来说它已经不是直接从本地文件运行了。对于需要严格本地资源如引用本地图片、库文件的复杂脚本可能不够灵活。3.2 方法二使用require加载远程脚本更接近生产环境这种方法更“专业”一些它模拟了线上脚本的加载方式非常适合需要分离库文件或模块化开发的场景。确保你的本地 HTTP 服务器正在运行http-server终端窗口开着。通过服务器访问你的脚本文件。假设你的项目文件夹在D:/projects/my-scripts并且运行在http://localhost:8080。那么你的脚本的访问地址就是http://localhost:8080/hello-world.user.js。在浏览器中打开这个地址你应该能看到脚本的源代码。在 Tampermonkey 管理面板新建一个脚本这次我们只写一个极简的头信息// UserScript // name 我的本地脚本远程加载版 // namespace http://tampermonkey.net/ // version 0.1 // description 通过本地服务器加载的主脚本 // author You // match https://www.example.com/* // require http://localhost:8080/hello-world.user.js // grant none // /UserScript // 这个文件本身可以是空的所有逻辑都在 require 的脚本里 // 或者你可以在这里写一些初始化和配置代码关键点是require http://localhost:8080/hello-world.user.js。这行指令告诉 Tampermonkey“去这个 URL 加载真正的脚本代码。”优点脚本逻辑完全保存在你的本地文件中Tampermonkey 只是一个加载器。可以方便地require其他本地库文件如 jQuery、Lodash 的本地副本。更符合脚本发布后的真实加载流程。缺点需要额外运行一个本地服务器。对于大多数个人开发和调试我推荐从方法一开始因为它最省心。当你需要更复杂的项目结构时再切换到方法二。3.3 利用浏览器开发者工具进行调试脚本生效后调试是开发的常态。油猴脚本运行在目标页面的上下文中因此你可以像调试普通网页 JavaScript 一样调试它。打开控制台在目标网页即match指定的网站上按F12打开开发者工具。查看源代码在“源代码”(Sources) 标签页中你通常能在左侧文件树找到类似Tampermonkey或userscript.html的目录里面就是你安装的所有脚本。找到你的脚本文件就可以设置断点、单步调试。查看日志你在脚本中用console.log()、console.error()打印的信息都会出现在“控制台”(Console) 标签页里。这是最常用的调试手段。油猴专属 API如果你使用了grant GM_*之类的 API它们的执行情况有时可以在 Tampermonkey 图标的下拉菜单中通过“检查安装的脚本”等选项看到更详细的信息。实操心得调试时经常遇到脚本因为页面结构变化而失效。一个有用的技巧是在脚本开头增加一个setTimeout延迟执行或者使用MutationObserver监听DOM变化确保你的脚本操作在目标元素加载完成后才执行。例如// 等待页面主体加载完成 window.addEventListener(load, function() { // 你的初始化代码 }); // 或者如果元素是动态加载的 const observer new MutationObserver(function(mutations) { if (document.querySelector(#my-target-element)) { // 找到元素了执行操作并停止观察 doSomething(); observer.disconnect(); } }); observer.observe(document.body, {childList: true, subtree: true});4. 脚本编写实战从修改页面到交互通信掌握了环境和调试我们来写点真正有用的功能。油猴脚本的能力边界其实很广小到修改样式大到与页面深度交互。4.1 基础操作修改DOM与样式假设我们想给某个新闻网站的文章正文增加一个“夜间模式”按钮。// UserScript // name 简易夜间模式 // match https://news.example.com/article/* // grant none // /UserScript (function() { use strict; // 1. 创建按钮 const nightModeBtn document.createElement(button); nightModeBtn.textContent 夜间模式; nightModeBtn.style.position fixed; nightModeBtn.style.top 20px; nightModeBtn.style.right 20px; nightModeBtn.style.zIndex 9999; nightModeBtn.style.padding 10px; nightModeBtn.style.background #333; nightModeBtn.style.color #fff; nightModeBtn.style.border none; nightModeBtn.style.borderRadius 5px; nightModeBtn.style.cursor pointer; // 2. 添加点击事件 nightModeBtn.addEventListener(click, function() { // 切换一个全局类名或直接修改样式 document.body.classList.toggle(tm-night-mode); // 或者直接操作 // if (document.body.style.background black) { // document.body.style.background ; // document.body.style.color ; // } else { // document.body.style.background black; // document.body.style.color #ccc; // } }); // 3. 将按钮添加到页面 document.body.appendChild(nightModeBtn); // 4. 可以附加一个简单的样式表来实现更精细的控制 const style document.createElement(style); style.textContent .tm-night-mode { background-color: #1a1a1a !important; color: #e0e0e0 !important; } .tm-night-mode a { color: #bb86fc !important; } ; document.head.appendChild(style); })();这个脚本展示了创建元素、添加事件、修改样式和注入CSS的基本流程。!important标志用于覆盖页面原有的高权重样式。4.2 使用油猴专属API增强功能油猴提供了一系列GM_*API让你能做一些普通JavaScript做不到的事情比如持久化存储、跨域请求等。使用前必须在grant中声明。示例保存和读取用户设置// UserScript // name 带记忆的夜间模式 // match https://news.example.com/article/* // grant GM_setValue // grant GM_getValue // /UserScript (function() { use strict; const STORAGE_KEY nightModeEnabled; // 读取保存的状态 const isNightMode GM_getValue(STORAGE_KEY, false); // 默认false const toggleBtn document.createElement(button); toggleBtn.textContent isNightMode ? ☀️ 日间模式 : 夜间模式; // ... 样式设置同上 ... toggleBtn.addEventListener(click, function() { const newMode !document.body.classList.toggle(tm-night-mode); // 保存新状态 GM_setValue(STORAGE_KEY, newMode); toggleBtn.textContent newMode ? ☀️ 日间模式 : 夜间模式; }); // 页面加载时应用保存的状态 if (isNightMode) { document.body.classList.add(tm-night-mode); } document.body.appendChild(toggleBtn); // ... 注入样式 ... })();GM_getValue和GM_setValue让脚本可以“记住”用户的选择即使关闭浏览器再打开也依然有效。数据存储在浏览器的扩展存储空间中。4.3 与页面原有脚本交互有时我们需要读取或调用页面全局作用域window下的变量或函数。这需要一些技巧因为油猴脚本默认运行在一个独立的“沙盒”环境中与页面脚本是隔离的。方法A使用unsafeWindowunsafeWindow是对页面原始window对象的引用。但使用时必须非常小心且需要在grant中声明。// grant unsafeWindow // ... const pageGlobalVar unsafeWindow.somePageVariable;警告unsafeWindow的使用存在安全性和兼容性风险且在某些模式下可能不可用。应作为最后的手段。方法B通过DOM事件或属性传递更安全的方式是通过DOM元素来通信。例如你可以将数据写入一个隐藏的input元素或者触发一个自定义事件。// 脚本A油猴脚本设置数据 document.body.setAttribute(data-my-script-data, JSON.stringify({key: value})); // 脚本B页面脚本或其他油猴脚本读取数据 const dataStr document.body.getAttribute(data-my-script-data); if (dataStr) { const data JSON.parse(dataStr); console.log(data.key); // value }方法C注入脚本标签最强大也是最彻底的方式是直接向页面注入一个script标签其中的代码将运行在页面的上下文中。function injectScript(code) { const script document.createElement(script); script.textContent code; document.documentElement.appendChild(script); script.remove(); // 执行后移除标签 } injectScript( // 这里的代码可以直接访问页面的 window 对象 console.log(页面标题, window.document.title); // 可以修改页面全局变量 window.myInjectedFunction function() { alert(来自油猴); }; );之后你的油猴脚本甚至可以通过window.myInjectedFunction来调用这个注入的函数前提是油猴脚本能访问到unsafeWindow或通过其他方式通信。这种方法功能强大但需要谨慎处理代码冲突和安全性。5. 工程化与项目管理让开发更高效可靠当脚本功能越来越复杂或者你开始维护多个脚本时一些工程化的实践能极大提升效率和代码质量。5.1 项目结构组织一个清晰的本地项目目录可能如下所示my-tampermonkey-scripts/ ├── scripts/ # 存放核心脚本文件 │ ├── core.user.js # 主脚本入口 │ ├── utils.js # 工具函数库需通过构建工具或require引入 │ └── styles.css # 样式文件 ├── libs/ # 存放第三方库如本地jQuery │ └── jquery-3.6.0.min.js ├── dist/ # 构建输出目录可选 ├── package.json # 项目配置如果使用npm └── README.md # 项目说明在core.user.js中你可以通过require来加载本地库和模块// require file:///D:/projects/my-tampermonkey-scripts/libs/jquery-3.6.0.min.js // require file:///D:/projects/my-tampermonkey-scripts/scripts/utils.js // resource customCSS file:///D:/projects/my-tampermonkey-scripts/scripts/styles.css注意file://协议的使用。这要求你在 Tampermonkey 的设置中允许对本地文件系统的访问Tampermonkey 设置 - 常规 - 配置模式 - 高级 - 在require中允许访问本地文件。5.2 使用现代JavaScript与构建工具你可以使用 ES6 语法如let/const、箭头函数、模板字符串、async/await编写脚本大部分现代浏览器都支持。如果你想使用更前沿的语法或TypeScript可以引入构建工具。例如使用esbuild这个极速的打包器在项目根目录初始化 npmnpm init -y安装 esbuildnpm install --save-dev esbuild在package.json中添加一个构建脚本scripts: { build: esbuild scripts/core.js --bundle --minify --outfiledist/core.user.js }将你的主脚本写成core.js使用模块化导入然后运行npm run build就会在dist目录生成压缩好的、浏览器兼容的core.user.js。你本地开发时调试core.js发布时使用构建产物。5.3 版本控制与发布使用 Git 管理你的脚本代码是绝对的最佳实践。每次做出有意义的功能增加或修复时进行一次提交。这不仅是备份更能清晰地追踪变更历史。对于发布如果你希望分享给他人可以将构建好的.user.js文件上传到 GitHub Gist、GitHub仓库或者专门的用户脚本平台如 Greasy Fork。在脚本头信息中可以通过updateURL和downloadURL指向你的脚本源地址这样用户安装后Tampermonkey 就能自动检查更新。// updateURL https://raw.githubusercontent.com/yourname/your-repo/main/dist/your-script.user.js // downloadURL https://raw.githubusercontent.com/yourname/your-repo/main/dist/your-script.user.js6. 常见问题排查与性能优化即使按照教程操作开发过程中也难免会遇到问题。这里汇总一些高频坑点和解决方案。6.1 脚本不生效的排查清单按照以下顺序检查99%的问题都能解决脚本是否启用去 Tampermonkey 管理面板确认脚本左侧的开关是绿色的启用状态。match或include规则是否正确这是最常见的原因。确保你访问的页面 URL 完全匹配规则。可以使用通配符*。在 Tampermonkey 仪表盘点击脚本名称在“安装”标签页可以清晰看到匹配的站点。页面是否完全加载如果你的脚本在DOMContentLoaded事件前执行并试图操作尚未存在的元素就会失败。将你的初始化代码包裹在window.addEventListener(load, ...)或setTimeout中。是否有 JavaScript 错误打开浏览器控制台F12查看是否有红色报错信息。油猴脚本的错误也会在这里显示。缓存问题尝试在 Tampermonkey 管理面板中禁用再启用脚本或者硬刷新网页CtrlF5或CmdShiftR。与其他脚本/扩展冲突尝试禁用其他脚本或浏览器扩展进行排查。grant声明了吗如果你使用了GM_*API 但没声明脚本可能会静默失败。6.2 性能与兼容性注意事项油猴脚本直接运行在用户访问的页面上性能不佳的脚本会拖慢整个浏览体验。避免频繁的DOM查询将document.querySelector的结果缓存到变量中而不是每次使用都重新查询。// 不好 for(let i0; i100; i) { document.querySelector(.my-item).style.color red; } // 好 const myItem document.querySelector(.my-item); for(let i0; i100; i) { myItem.style.color red; }使用事件委托如果要对大量动态生成的子元素添加事件监听应在它们的父元素上监听一个事件而不是为每个子元素单独绑定。// 假设 .list-container 是静态存在的父元素 document.querySelector(.list-container).addEventListener(click, function(event) { if (event.target.classList.contains(list-item)) { // 处理 .list-item 的点击事件 console.log(Item clicked:, event.target); } });注意MutationObserver的性能虽然它是监听DOM变化的利器但过于宽泛的监听如subtree: true, childList: true, attributes: true在复杂页面上可能带来性能开销。尽量将监听范围限制在目标区域。考虑使用requestIdleCallback或setTimeout分片对于非紧急的、耗时的操作可以利用浏览器空闲时间执行避免阻塞主线程。function processLargeArray(array) { let index 0; function doChunk() { const chunkSize 100; for (let i 0; i chunkSize index array.length; i) { // 处理 array[index] index; } if (index array.length) { // 下一帧继续 setTimeout(doChunk, 0); // 或者使用 requestIdleCallback // requestIdleCallback(doChunk); } } doChunk(); }6.3 安全与隐私红线这是开发者的责任。你的脚本拥有对页面很高的控制权务必遵守绝不收集、上传用户的个人隐私数据如密码、Cookie、表单内容。谨慎处理unsafeWindow避免被恶意页面利用。明确告知脚本功能在脚本描述中诚实说明脚本做了什么。尊重网站不要开发用于恶意刷量、攻击或干扰网站正常服务的脚本。注意许可证如果你使用了第三方代码遵守其许可证要求。本地开发油猴脚本是一个从消费者变为创造者的过程。它把你天马行空的想法和日常浏览的痛点连接起来。一开始可能只是为了改个颜色、加个按钮但随着你逐渐熟悉DOM操作、事件处理和浏览器API你会发现能做的事情越来越多。我自己的很多效率工具最初都只是一个几十行的油猴脚本。最关键的是动手开始从修改一个你经常访问的页面开始哪怕只是把某个碍眼的广告框隐藏掉那种“世界按照我的想法运行”的成就感就是最好的驱动力。
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门