Несколько 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"});
});