Ожидается, что разработчики JavaScript, которые разработали / будут когда-либо разрабатывать расширения для Chrome.

tl;dr

Здесь работает минимальный пример.



Оглавление

  1. Почему?
  2. Фоновый скрипт
  3. Скрипт содержания
  4. Заключение

Почему?

Статические файлы, такие как CSS и JavaScript, всегда сталкиваются с определенной проблемой: «Как связать множество зависимостей в один файл».

Для JavaScript, как вы знаете, существует множество связующего ПО, например Browserify, RequireJS и Webpack могут разрешать метод require или ключевое слово import и объединять файлы JavaScript (иногда AltJS) в один вывод.

Благодаря поддержке браузерами ES2015 (так называемого ES6) ключевое слово «import» можно использовать без использования упомянутого выше промежуточного программного обеспечения, только когда вы добавляете type="module" в свой тег <script>.

<script type="module" src="your-script.js"></script>


Хорошо, тогда можем ли мы использовать импорт модулей при разработке расширения Chrome, с которым manifest.json загружает JavaScript?

Фоновый скрипт

Поскольку фоновый скрипт расширения Chrome загружается из поля background.scripts из manifest.json, невозможно добавить атрибут «модуль» в качестве тега <script>. Так что давайте вместо этого используем поле background.page в качестве точки входа в ваши файлы JavaScript.

{
    "background": {
        "page": "src/html/background.html"
    }
}

тогда src/html/background.html выглядит как

<script type="module" src="src/js/background.js"></script>

Работает нормально 👍

Скрипт содержимого

С другой стороны, Content Script должен загружаться автоматически, когда content_scripts указаны в manifest.json, необходимы какие-то хаки.

Если ключевое слово import просто появляется в одном из content_scripts, появляется следующее сообщение об ошибке.

Uncaught SyntaxError: Unexpected identifier

Это потому, что он загружен без атрибута type="module". Мы каким-то образом отбрасываем наш JavaScript тегом <script> с type="module", по крайней мере, его точкой входа.

Идея состоит в том, чтобы использовать динамический импорт, который эквивалентен добавлению type="module" к динамически импортируемому скрипту.



Content_script будет выглядеть как

(async () => {
  const src = chrome.extension.getURL('src/js/main.js');
  const contentScript = await import(src);
  contentScript.main();
})();

После импорта с помощью динамического импорта ключевое слово import можно использовать так же, как оно загружено с type="module".

ПРИМЕЧАНИЕ. Поскольку import(src) выполняется в контексте средства визуализации страницы, который находится вне расширения Chrome, вам может потребоваться сделать src доступным с веб-сайта с помощью директивы web_accessible_resources в вашем manifest.json.

src/js/main.js может быть так

import User from "./my-models/User";
export function main() {
  // Do what you want
  const user = new User({name: "otiai10"});
  console.log(user);
}

В качестве альтернативы, внедрение тега сценария с помощью content_script (представленного в этом потоке) может отбросить другие файлы JavaScript с type="module", но, поскольку это внешний сценарий для жизненного цикла расширения Chrome, пространство имен chrome может быть исключено, и для этого потребуется некоторый взлом для использования chrome, например внедрение зависимости.

Заключение

Таким образом, использовать import для расширения Chrome не так уж и сложно. Но все же у нас есть проблемы, которые обычно решаются с помощью Webpack.

  1. Как решить node_modules и подзависимости внутри них?
  2. В некоторых случаях все еще требуется минификация / ускользание / транспиляция AltJS.

Мы можем получить больше преимуществ, используя такое промежуточное программное обеспечение с хорошо структурированными функциями. Я решил пока оставить нативные import ключевые слова.