如何编写Greasemonkey4.11脚本修改JS源码适配Firefox78私有字段?
问题
老旧的Firefox 78不支持JavaScript「私有字段(private fields)」,但部分现代网站的JavaScript代码未做兼容降级就使用该特性。例如以下代码:
if (o.userAgentDataBuilder) { const v = new class NavigatorUAData { #p; constructor({p, ua}) { this.#p = p;
运行时会触发错误:
Uncaught SyntaxError: private fields are not currently supported
已能通过Greasemonkey修改页面HTML,但不清楚如何修改JavaScript源码。请问能否编写Greasemonkey 4.11用户脚本,将JavaScript私有字段转为非私有字段,使这类现代JS代码能在Firefox78中正常运行?
解决方案
核心思路:通过Greasemonkey拦截页面加载的JavaScript文件,将代码中以
#开头的私有字段替换为常规非私有属性,再把修改后的代码注入页面执行,同时阻止原脚本的默认加载逻辑。具体脚本实现:
以下是适配Firefox 78的Greasemonkey 4.11用户脚本:// ==UserScript== // @name 私有字段转非私有兼容脚本 // @namespace private-field-polyfill // @match *://*/* // @grant GM.xmlHttpRequest // @grant GM.addElement // @run-at document-start // @connect * // ==/UserScript== // 拦截所有外部脚本加载 document.addEventListener('beforescriptexecute', function(e) { const targetScript = e.target; // 跳过内联脚本(如需处理内联可扩展逻辑) if (!targetScript.src) return; // 阻止原脚本执行 e.preventDefault(); // 请求获取原脚本内容 GM.xmlHttpRequest({ method: 'GET', url: targetScript.src, onload: function(res) { let modifiedCode = res.responseText; // 替换类中的私有字段定义(如 #p; → this.p;) modifiedCode = modifiedCode.replace(/^\s*#(\w+);/gm, ' this.$1;'); // 替换类中对私有字段的引用(如 this.#p → this.p) modifiedCode = modifiedCode.replace(/this\.#(\w+)/g, 'this.$1'); // 创建新脚本注入页面 const newScript = GM.addElement(document.head, 'script', { textContent: modifiedCode, type: 'text/javascript' }); newScript.dispatchEvent(new Event('load')); } }); });注意事项:
- 脚本设置
document-start运行时机,确保在页面脚本加载前完成拦截。 - 当前正则仅处理基础私有字段场景,若遇到私有方法、私有访问器等复杂语法,需要扩展正则规则。
- 部分网站存在CORS限制时,
@connect *可允许跨域请求脚本内容。 - 内联脚本的处理需额外逻辑,可在
DOMContentLoaded后遍历页面内联脚本进行替换,但要注意执行顺序问题。
- 脚本设置
内容的提问来源于stack exchange,提问作者Pro Backup
相关产品推荐
相关产品推荐

