РЕДАКТИРОВАТЬ ниже все еще верно для простого vanilla require.js, но нашел обходной путь путем разветвления RequireJS
Github: https://github.com/jeroendelau/requirejs
Bower: установка bower requirejs-for-browser-extensions
ОРИГИНАЛЬНАЯ ПОЧТА
Внедрить его в скрипт контента - безусловно, самое сложное. И приведенные выше ответы являются неполными или неправильными.
Фон и всплывающее окно:
Пойдите с более ранним ответом @nafis, они будут работать
Сценарий содержания
Это очень сложный вопрос, и эта часть из описания API является ключевой:
Среда исполнения
Сценарии содержимого выполняются в специальной среде, называемой изолированным миром. Они имеют доступ к DOM страницы, в которую они внедрены, но не к каким-либо переменным или функциям JavaScript, созданным этой страницей. Каждый скрипт содержимого выглядит так, как будто на странице, на которой он запущен, нет другого JavaScript-кода. То же самое верно и в обратном: JavaScript, работающий на странице, не может вызывать какие-либо функции или обращаться к любым переменным, определенным скриптами содержимого.
Интуитивно это должно быть правильно
manifest.json
{
"name": "My extension",
...
"content_scripts": [
{
"matches": ["http://www.google.com/*"],
"css": ["mystyles.css"],
"js": ["requirejs.js", "myscript.js"]
}
],
...
"web_accessible_resources": [
"js/*"
],
...
}
myscript.js
require(["myFancyModule"], function (FM) {
...
});
ЭТО НЕ БУДЕТ РАБОТАТЬ
Проблема в том, что requirejs продолжит загрузку всех ваших зависимостей, введя теги <script>
в заголовок. Эти теги сценария выполняются в среде PAGE, а не в специальной среде EXTENSION. И это имеет значение.
- Зависимости не загружаются, так как requirejs не загружается на странице
окружающая среда
- Если владелец сайта уже добавил requirejs, это может привести к конфликту
- Вы можете принять решение внедрить require.js на страницу, как предлагает @Adam, но в этом случае ни одна из ваших расширенных функций
буду работать. хранение, обмен сообщениями, межсайтовый запрос - все это не
доступны
Таким образом, чтобы они работали, модули, загруженные requirejs, должны быть внедрены в среду расширений. Для изменения поведения загрузки можно использовать плагин requirejs.
Из-за того, как это работает, решение очень не элегантное, и оно мешает вам видеть сценарии в отладчике под сценариями. Но если вы в отчаянии, это сработает.
myscript.js
/**
* Inject the plugin straight into requirejs
*/
define("Injector", {
load: function (name, req, onload, config) {
//Load the script using XHR, from background
var oReq = new XMLHttpRequest();
oReq.addEventListener("load", function () {
//Find depenencies in the script, and prepend the
//Injector! plugin, forcing the load to go through this
//plugin.
var modified = getDeps(oReq.response)
//have requirejs load the module from text
//it will evaluate the define, and process dependencies
onload.fromText(modified);
});
oReq.open("GET", req.toUrl(name) + ".js");
oReq.send();
//Find dependencies and prepend Injector!
function getDeps(script)
{
//extract the define call, reduced to a single line
var defineCall = script.match(/define([\s\S])*?{/m)[0].split("\n").join("");
//extract dependenceis from the call
var depsMatch = defineCall.match(/\[([\s\S]*?)\]/);
//if there are dependencies, inject the injectors
if (depsMatch)
{
var deps = depsMatch[0];
var replaced = deps.replace(/(\'|\")([\s\S]*?)\1/g, '$1Injector!$2$1');
return script.replace(/define([\s\S]*?)\[[\s\S]*?\]/m, 'define$1' + replaced);
}
//no dependencies, return script
return script;
}
}
});
/**
* Call all your dependencies using the plugin
*/
require(["Injector!myFancyModule"], function (FM) {
chrome.storage.local.get({something});
});