Я работаю над небольшим расширением для Chrome под названием Вам следует проверить (ysco) », которое будет показывать посетителям веб-сайта другие ресурсы, которые, по мнению читателей, дополняют текущий веб-сайт. Думайте об этом как о рекомендациях Amazon другие пользователи также покупали, но для любого URL-адреса, и эти рекомендации отправляются вручную пользователями расширения.

Этот проект состоит из двух важных частей: background_action, который для меня будет HTML-файлом, который запускает мой проект React, и content_script, который будет запускаться после завершения загрузки каждой новой страницы.

background_action отобразит пользовательский интерфейс для списка рекомендаций и для отправки новой рекомендации. content_script сделает запрос на получение любых рекомендаций, которые уже существуют для текущего URL-адреса, и обновит значок расширения, чтобы проинформировать пользователя о том, что другие читатели рекомендовали некоторые другие ресурсы.

Единственная проблема здесь в том, что create-react-app по умолчанию настроен на выдачу только одного вывода Webpack, который будет вашими последними объединенными ресурсами. На самом деле нам нужны два разных, несвязанных результата, когда мы запускаем npm run build для создания нашего производственного пакета. Один из них будет обычным проектом React, а другой будет нашим content_script, чтобы делать этот первоначальный запрос GET при каждой загрузке страницы.

Но зачем вам два отдельных пакета? Почему мы не можем просто использовать один пакет React и делать запрос GET при загрузке приложения?

Отличный вопрос! В качестве меры безопасности наш background_action код не будет выполняться до тех пор, пока пользователь не щелкнет значок расширения на панели инструментов, но мы хотим иметь возможность показывать пользователям, сколько рекомендаций есть, прежде чем им нужно будет что-либо щелкнуть, поэтому нам нужно используйте отдельный content_script.

Кроме того, просто примечание: на протяжении всего этого я предполагаю некоторое знакомство с основами расширения Chrome, такими как локальная загрузка распакованного расширения. Большая часть этого руководства будет посвящена извлечению проекта React, чтобы сделать наше расширение более надежным.

Круто, приступим.

Создание проекта и его расширение

К счастью, превратить новый проект React в расширение Chrome - это eeeeasy. Начнем с create-react-app.

$ create-react-app eject-test-extension
...
$ cd eject-test-extension

Круто, теперь нам просто нужно обновить manifest.json файл, чтобы сделать его более расширенным, если использовать технический термин.

{
  "name": "eject test",
  "version": "1.0",
  "description": "Build an Extension!",
  "manifest_version": 2,
  "browser_action": {
    "default_popup": "index.html",
    "default_title": "eject test"
  }
}

Идите вперед и замените все, что находится в public/manifest.json, приведенным выше фрагментом. Может быть, весь этот код, который уже есть в manifest.json, важен, но кто знает! Идите и замените все это.

Хорошо, нам также нужно немного обновить нашу команду сборки. Замените вашу build команду в package.json следующей:

INLINE_RUNTIME_CHUNK=false react-scripts build

Не стесняйтесь читать об этом больше здесь, если вам это интересно, но я не буду рассказывать об этом в этом руководстве. Короче говоря, проблемы с CSP.

Тестирование расширения React

Давайте удостоверимся, что все это примерно работает, и что мы можем загрузить приложение React в раскрывающемся списке расширения, когда пользователь нажимает значок расширения на панели инструментов.

Давайте создадим производственную сборку, которую мы будем загружать в Chrome локально и в Интернет-магазин, когда закончим.

$ npm run build

Круто, теперь у нас должна быть папка build в нашем проекте, которую git уже настроен на игнорирование. Чтобы добавить это как расширение локально, следуйте этим инструкциям, используя только что созданный каталог build в качестве пакета загрузки.

Если повезет, вы должны увидеть всплывающий значок расширения по умолчанию на панели инструментов Chrome, и щелчок по нему должен привести к запуску нашего работающего проекта React.

Конечно, это может выглядеть как мусор, но это наш мусор. Теперь давайте начнем извлекать проект React и приступить к настройке.

Извлечение проекта для настройки Webpack

Как я уже сказал выше, нам нужно настроить Webpack для поддержки нескольких выходов, чего мы не сможем сделать без выброса проекта React. Если вы не знаете, что это, по сути, это означает раскрытие всей конфигурации Webpack, которую create-react-app использует внутренне. Подробнее об этом можно прочитать здесь.

$ npm run eject

По завершении этого процесса у вас будет пара новых каталогов в проекте, но нас интересуют только два файла: config/webpack.config.js и config/paths.js.

Обновление до paths.js будет самым простым, так что давайте сделаем это в первую очередь. В этом файле вы увидите, что модуль экспортирует объект путей к файлам, и мы хотим добавить новый объект для нашего src/background.js файла, который позже станет нашим content_script.

Единственное, что мы добавляем, это строку 20 в приведенном выше фрагменте, потому что мы можем использовать ее позже в процессе сборки.

Следующим шагом является обновление webpack.config.js для обработки нескольких выходов. Мы можем добиться этого, если Webpack вернет совершенно новую конфигурацию вместе с конфигурацией, используемой для части проекта React.

Так выглядит конфиг при создании; именно так npm run eject был создан файл. В строке 132 вы увидите, что модуль экспортирует объект конфигурации. Единственное изменение, которое нам нужно сделать, - вместо этого сохранить весь объект конфигурации в переменной и создать другой объект конфигурации для background.js, а затем вернуть оба объекта в массив.

Вы можете найти копию обновленного webpack.config.jsfile здесь. Но самое интересное на самом деле вот в чем:

Обратите внимание, что мы используем тот backgroundScript путь, который мы создали ранее. Мы сообщаем Webpack, что хотим начать объединение всего, что находится в нашем background.js файле и импортировано в него (это свойство entry), и в итоге получить файл с именем background.js в каталоге сборки. Единственный плагин, который мы хотим использовать, - это минификация (но все это может быть изменено вами, в зависимости от ваших потребностей).

Кстати, нам нужно установить плагин минификации:

$ yarn add babel-minify-webpack-plugin

Теперь, когда мы создаем проект, Webpack должен вывести обычные связанные файлы React, а также файл с именем background.js, который будет построен из background.js в папке src. Но мы скоро это проверим.

Последнее, что нам нужно сделать, это обновить наш manifest.json файл, чтобы он действительно использовал background.js файл, который мы собираемся создать.

Все, что мы добавили здесь, это свойство content_scripts, которое говорит, что на любой странице, URL-адрес которой совпадает с http://*/* или https://*/*, браузер должен запускать наш background.js файл.

Тестирование конечного продукта

Давайте создадим background.js файл в нашем src каталоге, если вы еще этого не сделали. В рамках этого давайте напишем что-нибудь простое для тестирования.

alert('this is a test'); // in src/background.js

И теперь мы можем перестроить проект.

$ npm run build

И как только это будет завершено, мы должны увидеть background.js файл в нашем build каталоге вместе с обычными связанными файлами для проекта React! Если вы не видите файл background.js, убедитесь, что файл конфигурации соответствует указанному выше.

Примечание. Вы можете получить легкую ошибку при доступе к некоторому ресурсу на undefined. Это просто потому, что create-react-app пытается сообщить статистику по связанным файлам на основе конфигурации и жестко запрограммирован так, чтобы ожидать только один объект конфигурации, но теперь мы используем два.

Давайте сейчас перезагрузим наше распакованное расширение, чтобы Chrome получил обновленную версию расширения.

И теперь мы можем это проверить. Теоретически мы должны ожидать появления предупреждения всякий раз, когда мы переходим на новую страницу, и мы по-прежнему можем щелкнуть значок нашего расширения на панели инструментов, чтобы открыть всплывающее окно, в котором запущен наш проект React.

Ууууууу. При перезагрузке страницы наш content_script запускается, а наш browser_action все еще выполняет связанный проект React. Мы добились успеха в том, что намеревались сделать!

Последние мысли

С этого момента настройка довольно проста, потому что основная сантехника проекта уже на месте. Вы можете добавить еще content_scripts, если хотите, вы, вероятно, просто захотите создать и вернуть другой объект конфигурации в webpack.config.js, точно так же, как мы это делали раньше.

Если вы обнаружите, что какая-то часть этого неясна или неверна, дайте мне знать, чтобы я мог ее обновить :)