Несколько JS файлов в Chrome Extension - как их загрузить?

Я написал расширение Chrome. Мой файл background.js довольно велик, поэтому я хочу разбить его на более мелкие части и при необходимости загрузить определенные методы (какая-то ленивая загрузка).

Я сделал это с Firefox:

// ( call for load specified lib )
var libPath = redExt.basePath + 'content/redExt/lib/' + redExt.browser + '/' + libName + '.js';
var service = Components.classes["@mozilla.org/moz/jssubscript-loader;1"].getService(Components.interfaces.mozIJSSubScriptLoader);
service.loadSubScript("chrome://" + libPath);
// ( executing loaded file )

Есть ли возможность сделать это аналогичным образом в браузерах на основе Webkit? Я нашел решения о том, как добавлять несколько JS файлов в соответствующие страницы (используя manifest.json), но не может найти способ включить JS файл только для расширения.

Ответы

Ответ 1

Найдено возможное решение. Theres простая реализация основного метода RequireJS, который использует трассировку обратного вызова JavaScript для поиска события для загрузки основного файла расширения, а binds выполняет его с расширением контекста. https://github.com/salsita/browser-require/blob/master/require.js

Кажется, что это работает, но это решение имеет несколько минусов:

  • отчеты об ошибках сообщаются в строке 1, столбец 1, потому что это решение вводит код непосредственно в func.call - отладка очень сложная.
  • Загруженные файлы JS не отображаются в консоли /chromebug
  • Если текущая вкладка использует HTTPS, Chrome будет запрещать сценарии evaling, особенно это из локального контекста (file:///), поэтому он иногда просто не работает как ожидалось

Ответ 2

Вы также можете сделать это очень простым способом, который описан здесь: https://developer.chrome.com/extensions/background_pages#manifest

{
  "name": "My extension",
  ...
  "background": {
    "scripts": [
      "lib/fileone.js",
      "lib/filetwo.js",
      "background.js"
    ]
  },
  ...
}

Вы не будете делать ленивую загрузку, но это позволит вам разбить код на несколько файлов и указать порядок, в котором они загружены на исходную страницу.

Ответ 3

Если вы хотите загрузить файл javascript в контексте своей фоновой страницы и хотите избежать использования eval, вы можете просто добавить тег script на свою домашнюю страницу DOM. Например, это работает, если ваши файлы присутствуют в папке lib вашего расширения:

function loadScript(scriptName, callback) {
    var scriptEl = document.createElement('script');
    scriptEl.src = chrome.extension.getURL('lib/' + scriptName + '.js');
    scriptEl.addEventListener('load', callback, false);
    document.head.appendChild(scriptEl);
}

Ответ 4

Возможно, вы попытаетесь использовать веб-работников. В background.js укажите:

var worker = new Worker('new-script.js');

Веб-рабочие могут создавать новых рабочих и даже иметь метод importScript ( "new- script.js" ).

Однако веб-работники могут быть очень ограниченными. Проверьте здесь за отличную статью о веб-работниках.

Я не знаю, будут ли они работать. Другой вариант использует XMLHTTPRequest (AJAX) для динамического извлечения script и eval его. Однако через соединение, отличное от HTTPS, это, вероятно, заблокировано из-за нападений "человек в середине". Кроме того, вы можете заставить Chrome анализировать script из нешифрованного соединения (НО НЕ ДЕЛАЙТЕ ЭТО), добавив это к manifest.json:

"content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'",
"permissions": ["http://badpractic.es/insecure.js"]

Смотрите Загрузите удаленную веб-страницу в фоновом режиме: Расширение Chrome для более подробного обсуждения метода AJAX.

Таким образом, ваши возможности кажутся ограниченными.

Это, конечно, загружает их все сразу:

{
  "name": "My extension",
  ...
  "background": {
    "scripts": ["background.js","background2.js","background3.js"] //and so on
  },
  ...
}

Ответ 5

То, что я сделал, - это не ленивая загрузка, но я загружаю некоторые файлы раньше других, когда нажимается значок расширения Chrome. В моем случае я хотел, чтобы мои файлы утилит были раньше других, использующих их:

chrome.browserAction.onClicked.addListener(function() {
  chrome.tabs.executeScript(null, {file: "src/utils/utilFunction1.js"});
  chrome.tabs.executeScript(null, {file: "src/utils/utilFunction2.js"});
  chrome.tabs.executeScript(null, {file: "src/main.js"});
  chrome.tabs.executeScript(null, {file: "src/otherFeature.js"});
});