在多个用户脚本之间共享库

Sharing a library between multiple userscripts

我有一个被多个用户脚本使用的库脚本。这个库做了一些繁重的工作(即 CPU 密集型操作),所以我只想拥有该库的 1 个实例 运行ning.

这是一个最小的例子:

lib.js

let callbacks = [];

document.addEventListener('click', function(event){
    // pretend that something expensive happens in here

    for (callback of callbacks)
        callback();
});

script1.user.js

// @match foo.bar
// @require lib.js

callbacks.push(function(){
    console.log('Script 1: '+callbacks.length+' callback(s) registered');
});

script2.user.js

// @match foo.bar
// @require lib.js

callbacks.push(function(){
    console.log('Script 2: '+callbacks.length+' callback(s) registered');
});

使用此设置,单击鼠标后的输出为:

Script 1: 1 callback(s) registered
Script 2: 1 callback(s) registered

因为每个用户脚本都有自己的库实例。我该怎么做才能让它们使用相同的库实例,所以我得到这样的输出:

Script 1: 2 callback(s) registered
Script 2: 2 callback(s) registered

注:

最简单的方法是让库脚本将自身分配给 window 如果它不存在,标准单例样式。

lib.js

const win = typeof unsafeWindow === 'undefined' ? window : unsafeWindow;

if (!win.myLib) {
  win.myLib = {
    callbacks: []
    // assign other properties/methods as needed
  };

  document.addEventListener('click', function(){
    for (const callback of win.myLib.callbacks)
      callback();
  });
}

script1.user.js

// @require lib.js
const { myLib } = window;
myLibrary.callbacks.push(function(){
  console.log('Script 1: ' + myLib.callbacks.length + ' callback(s) registered');
});

script2.user.js

// @require lib.js
const { myLib } = window;
myLibrary.callbacks.push(function(){
  console.log('Script 2: ' + myLib.callbacks.length + ' callback(s) registered');
});

根据用户脚本管理器,在某些情况下您可能不得不使用 unsafeWindow