Совместное использование библиотеки между несколькими пользовательскими сценариями - PullRequest
0 голосов
/ 28 мая 2018

У меня есть библиотечный скрипт, который используется несколькими скриптами пользователя.Эта библиотека выполняет некоторые тяжелые работы (т. Е. Операции с интенсивным использованием процессора), поэтому я хотел бы, чтобы работал только 1 экземпляр этой библиотеки.

Вот минимальный пример:

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

Примечание:

  • Оба пользовательских скрипта запускаются на одной странице
  • Пользовательские скрипты могут иметь или не иметь @grant none

1 Ответ

0 голосов
/ 28 мая 2018

Самый простой способ для сценария библиотеки - назначить себя окну , если его там еще нет , стандартный стиль синглтона.

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 в некоторых случаях.

...