Как импортировать модули ES6 в Content script для расширения Chrome
на хром 61 добавлена поддержка модулей в JavaScript. Прямо сейчас я запускаю Chrome 63.
Я пытаюсь выяснить, как использовать синтаксис импорта/экспорта в сценарии содержимого расширения Chrome для использования модулей.
на манифест.в JSON:
"content_scripts": [ {
"js": [
"content.js"
],
на my-script.js каталог контента.js
'use strict';
const injectFunction = () => window.alert('hello world');
export default injectFunction;
In содержание.js
'use strict';
import injectFunction from './my-script.js';
injectFunction();
я получаю эту ошибку: непойманные синтаксис ошибка: неожиданный идентификатор
если я изменю синтаксис импорта на import {injectFunction} from './my-script.js';
Я получаю эту ошибку: Uncaught SyntaxError: неожиданный токен {
есть ли проблема с использованием этого синтаксиса в содержании.JS в расширении Chrome, так как в HTML вы должны использовать <script type="module" src="script.js">
синтаксис, или я делаю что-то неправильно? Кажется странным, что Google игнорирует поддержку увеличение.
4 ответов
мне удалось найти решение.
прежде всего важно сказать, что сценарии контента не поддерживают модули с января 2018 года. Но вы можете заставить его работать, встраивая тег сценария модуля в страницу, которая ведет обратно к вашему расширению.
это в моем манифесте
"content_scripts": [ {
"js": [
"content.js"
]
}],
"web_accessible_resources": [
"main.js",
"my-script.js"
]
обратите внимание, что у меня есть два скрипта на веб-доступных ресурсов.
мой содержание.js содержит только этот логика:
'use strict';
const script = document.createElement('script');
script.setAttribute("type", "module");
script.setAttribute("src", chrome.extension.getURL('main.js'));
const head = document.head || document.getElementsByTagName("head")[0] || document.documentElement;
head.insertBefore(script, head.lastChild);
это вставит main.js на веб-страницу в качестве сценария модуля. Вся моя бизнес-логика теперь в основном.js и main, а также все скрипты, которые я буду импортировать, должны быть в web_accessible_resources в манифесте.
Это пример контент my-script.js:
'use strict';
const injectFunction = () => window.alert('hello world');
export {injectFunction};
и main.js это пример импорта скрипт:
'use strict';
import {injectFunction} from './my-script.js';
injectFunction();
это работает, никаких ошибок не выдается, и я счастливый:)
Я просто наткнулся на этот вопрос, пытаясь решить то же самое сам.
В любом случае, я думаю, что есть более простое решение для инъекции ваших собственных пользовательских модулей в ваш скрипт контент. Я смотрел, как вводится jQuery, и мне кажется, что вы можете сделать то же самое, создав жизнь (немедленно вызывается выражение функции) и объявляет его в вашем манифест.в JSON
Это что-то вроде это:
в манифесте.в JSON:
"content_scripts": [
{
"matches": ["https://*"],
"css": ["css/popup.css"],
"js": ["helpers/helpers.js"]
}],
тогда просто создайте IIFE в своих помощниках / помощниках.js:
var Helpers = (function() {
var getRandomArbitrary = function(min, max) {
return Math.floor(Math.random() * (max - min)) + min;
}
return {
getRandomArbitrary: getRandomArbitrary
}
})()
Теперь, вы можете свободно использовать свои вспомогательные функции в вашем скрипте содержание:
Helpers.getRandomArbitrary(0, 10) // voila!
Я думаю, что это здорово, если вы используете этот метод для рефакторинга некоторых ваших общих функций. Надеюсь, это поможет!
Короткий Ответ:
вы можете имитировать некоторые функции и преимущества import
/export
в расширениях браузера, создав следующий файл и перечислить его в самом начале manifest.json
:
let exportVars, importVarsFrom;
{
const modules = {};
exportVars = varsObj => ({
from(nameSpace) {
modules[nameSpace] || (modules[nameSpace] = {});
for (let [k,v] of Object.entries(varsObj)) {
modules[nameSpace][k] = v;
}
}
});
importVarsFrom = nameSpace => modules[nameSpace];
}
затем экспортируйте из одного файла/модуля следующим образом:
exportVars({ var1, var2, var3 }).from('my-utility');
импорт в другой файл / модуль, как это:
const { var1, var3: newNameForVar3 } = importVarsFrom('my-utility');
Обсуждение:
этот стратегия:
- позволяет модульный код в расширении браузера, так что вы можете разделить код на несколько файлов, но не имеют переменных столкновений из-за общей глобальной области между различными файлами,
- позволяет экспорт и импорт переменных из и в различные JavaScript-файлы/модули
- представляет только две глобальные переменные, а именно функции экспорта и импорта функции
- поддерживает полная функциональность расширения браузера в каждом файле (например,
chrome.runtime
, etc.) это устраняется, например, подходом в другом ответе (в настоящее время принятый ответ) с использованием встраивания тега скрипта модуля, - использует краткий синтаксис похож на true
import
иexport
функции в JavaScript - позволяет имя-интервал которые могут быть именами файлов экспортирующих модулей в подобно тому, как истинно
import
иexport
команды работают в JavaScript, но не должны быть (т. е. имена имен-пробелов могут быть чем угодно), и - позволяет переменной переименования при импорте аналогично how
import { fn as myFn }...
строительство.
для этого manifest.json
необходимо загрузить JavaScript следующим образом:
- файл, устанавливающий сначала функции экспорта / импорта (с именем
modules-start.js
в Примере ниже), - следующий экспорт файлов и
- импорт файлов последний.
конечно, у вас может быть файл, который импортирует и экспортирует. В этом случае просто убедитесь, что он указан после файлов, из которых он импортирует, но до файлов, в которые он экспортирует.
Пример Работающего
следующий код демонстрирует эту стратегию.
важно отметить, что весь код в каждой модуль / файл содержится в фигурных скобках. Единственным исключением является первая строка modules-start.js
который устанавливает функции экспорта и импорта в качестве глобальных переменных.
код в приведенном ниже фрагменте обязательно содержится в одном "месте". Однако в реальном проекте код можно разделить на отдельные файлы. Обратите внимание, однако, что даже в этом искусственном контексте здесь (т. е. в одном фрагменте кода ниже) эта стратегия позволяет различным разделам кода содержит быть модульным и все еще все еще Соединенным.
// modules-start.js:
let exportVars, importVarsFrom; // the only line NOT within curly braces
{
const modules = {};
exportVars = varsObj => ({
from(nameSpace) {
modules[nameSpace] || (modules[nameSpace] = {});
for (let [k,v] of Object.entries(varsObj)) {
modules[nameSpace][k] = v;
}
}
});
importVarsFrom = nameSpace => modules[nameSpace];
}
// *** All of the following is just demo code
// *** showing how to use this export/import functionality:
// my-general-utilities.js (an example file that exports):
{
const wontPolluteTheGlobalScope = 'f';
const myString = wontPolluteTheGlobalScope + 'oo';
const myFunction = (a, b) => a + b;
// the export statement:
exportVars({ myString, myFunction }).from('my-general-utilities');
}
// content.js (an example file that imports):
{
// the import statement:
const { myString, myFunction: sum } = importVarsFrom('my-general-utilities');
console.log(`The imported string is "${myString}".`);
console.log(`The renamed imported function shows that 2 + 3 = ${sum(2,3)}.`);
}
С этим примером, ваш manifest.json
должна перечислить файлы в следующем порядке:
{ ...
"content_scripts": [
{
"js": [
"modules-start.js",
"my-general-utilities.js",
"content.js"
]
}
], ...
}
экспорт в модуле объекта:
'use strict';
const injectFunction = () => window.alert('hello world');
export {injectFunction};
затем вы можете импортировать его имущества:
'use strict';
import {injectFunction} from './my-script.js';