mihail430899
@mihail430899
Вебмастер

Как включить импорт/экспорт внутри chrome.tabs.executeScript?

Делаю chrome плагин для своих нужд. Не эксперт в данной теме. Модульность для background.js и popup.js работает, там просто сую в html
<script type="module"...
и все ок, импорты/экспорты работают.

Но вот такой кейс, пример кода в background.js:
chrome.tabs.onUpdated.addListener((tabId, _, tab) => {
  if(tab.url.match(/^myRegexpHere$/) )
    chrome.tabs.executeScript(tabId, { file: 'background/something.js' })   
});


Так вот в этом something.js тоже вообще-то хотелось бы импорты юзать, ибо кода писать там много, не превращать же файл в портянку на 1000 строк.
  • Вопрос задан
  • 349 просмотров
Решения вопроса 1
mihail430899
@mihail430899 Автор вопроса
Вебмастер
Короче ответ на собственный же вопрос получился приличной портянкой. Текущее решение во второй части ответа, а в первой саммари из обсуждения на stackoverflow.

В общем вот вопрос на stackoverflow под которым собралось больше всего разных решений https://stackoverflow.com/questions/48104433/how-t...
Что я понял из этого всего:
  1. Самое лучшее - разобраться с Webpack и собирать код браузерного плагина через него. Возможно другой сборщик тоже прокатит, тот же Parcel.
  2. Можно обойтись без import/export, подключив несколько скриптов сверху вниз и используя в нижнем функции и переменные из верхних. Но мне кажется, что это не так уж и удобно для разработки. Императивный подход подобного мультиподключения для плагинов на mv2 (manifest.json v2) неудобен, т.к. надо один executeScript оборачивать другим. Декларативный чуть удобнее, но тогда надо все это лепить прямо в manifest.json, у этого тоже вижу свои минусы. Если делать плагин на mv3, там дела у императивщины лучше, т.к. вместо file в executeScript указывается массив files.
  3. Хак с промежуточным файлом в executeScript, который вставляет на веб-страницу уже собственно наш скрипт с бизнес-логикой (а еще в manifest.json нужно добавить скрипты в web_accessible_resources). Я попробовал, сработало, но выглядит это решение не очень изящно, а также оно было раскритиковано на stackoverflow. mv2 дает такое сделать, mv3 не пропускает столь грубый метод.
  4. Также возможно неплохая идея перенести расширение на manifest v3. Это и в целом правильно, и там на stackoverflow предложили вроде как неплохое решение для mv3, которое я тоже проверил - оно чуть лучше предыдущего, но все равно не очень, особенно если плагин большой.


Ну а так для удобной разработки большого плагина только вариант 1 (походу).

UPD: В итоге, после очередного перепрочтения инфы по указанной ссылке на stackoverflow, я додумался до варианта, который не иначе как мегакостылем не назовешь. Но он позволяет ограничиться одним промежуточным файлом, причем в 1 строчку, и через него подключать любое кол-во файлов, где уже свободно можно юзать импорты. А также этот способ не такой грубый, как вставка тега script напрямую на веб-страницу. В общем, мне даже понравилось.

Костыль использует 3 решения:
  1. Один executeScript вложенный в другой
  2. Использование globalThis
  3. Использование динамического импорта

А если конкретнее, то в background.js у меня вот что:
chrome.tabs.executeScript(tabId, { code: 'globalThis.path = "folder/your_content_script.js"'}, () => {
  chrome.tabs.executeScript(tabId, { file: 'folder/middle.js' })
})

middle.js это файл в 1 строчку:
(async () => await import(chrome.runtime.getURL(globalThis.path)))()

И всё, это работает! Чтобы в background.js каждый раз не писать вложенный executeScript, я сделал функцию хелпер:
function executeImportedScript(tabId, path) {
  chrome.tabs.executeScript(tabId, { code: `globalThis.path = '${path}'`}, () => {
    chrome.tabs.executeScript(tabId, { file: 'folder/middle.js' })
  })
}

И в нужном месте просто:
executeImportedScript(tabId, "folder/your_content_script.js")

Только в manifest.json в ключе web_accessible_resources должны присутствовать пути ко всем контент-скриптам + пути ко всем скриптам, из которых контент-скрипты что-то импортируют. И собственно это пока единственная проблема, которую я вижу у этого способа - разбухание manifest.json и web_accessible_resources в частности (для большого плагина).
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
profesor08
@profesor08 Куратор тега JavaScript
Подключи все скрипты сразу.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы