Как стать автором
Обновить

Разработка Chrome Extension вместе с Angular CLI

Время на прочтение 3 мин
Количество просмотров 4.6K
Разработкой расширений к Chrome я занимаюсь давно и за это время я прошел целый путь от Greasemonkey юзер-скриптов до полноценного Angular-приложения в оболочке chrome-extension. Моя задача в том, что я патчу некоторые уже работающие сайты, чтобы изменить их функционал и автоматизировать некоторые процессы на этих сайтах. Иногда моё приложение разрастается до больших масштабов и поддерживать plain-js расширение становится сложно (в приложении много настроек, CRUD функционала и тд). И тут на помощь приходит Angular.

В этой статье я расскажу вам как я подружил Chrome Extension и Angular CLI, и наладил процесс разработки, а также с какими трудностями я сталкивался и как их решал.
Создаем новую папку и инициализируем в ней новое приложение

mkdir new-project
cd new-project
ng new frontend --routing=true --skipGit=true --style=scss --skipTests=true

В стадии development Angular генерирует динамический html-файл, в котором происходит разработка, а хромовскому расширению нужно скармливать статичный html-файл, чтобы видеть результат работы. Конечно, можно отдельно собрать Ангуляровский проект и затем build-версию уже прописать в дополнение, но будет удобно, если это будет происходить автоматически.

После генерации нового приложения заходим в папку frontend и в файле package.json в раздел scripts добавляем новый скрипт для сборки нашего проекта

"developing": "ng build --watch --deploy-url /frontend/dist/frontend/ --base-href /frontend/dist/frontend/index.html?/"

Обратите внимание на deploy-url и base-href.

Затем в корне проекта создаем еще одну папку extension и в ней создадим файл extension.js, который будет являться background-скриптом для нашего расширения. Текущая структура проекта:

| new-project/
| | extension/
| | | extension.js
| | frontend/
| | | ...

Содержимое extension.js

const ANGULAR_HTML_URL = "../../frontend/dist/frontend/index.html";

chrome.browserAction.onClicked.addListener(function () {
    chrome.tabs.create({
        url: chrome.runtime.getURL(ANGULAR_HTML_URL)
    });
});

Это будет browserAction, который откроет новую вкладку с нашим ангуляр-приложением, которое в собранном виде будет уже храниться по этому пути.

Добавим manifest.json в наш проект
{
  "manifest_version": 2,
  "name": "Simple Chrome Ext",
  "description": "Simple Chrome Extension as an example",
  "version": "1.00",
  "author": "Bogdan",
  "content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'",
  "background": {
    "persistent": true,
    "scripts": ["/extension/extension.js"]
  },
  "browser_action": {
    "default_title": "Chrome ext"
  }
}


Теперь мы можем собрать наш проект в расширение. Заходим в chrome://extensions/, включаем режим разработчика и выбираем Загрузить распакованное расширение.

Результат
image

Удобство в том, что у нас есть почти hot-reloading. Мы запустили ng build с флагом watch и при изменении кода проект будет пересобираться и js-файлы будут подменяться. То есть, на странице расширения нам нужно всего лишь перезагрузить страницу и все обновления подхватятся. Это значительно ускоряет разработку дополнений.

Еще один момент, на котором я собаку съел, это что в конфигурации роутинга:

{
   useHash: true
}

а также вернемся выше, base-href при билде мы прописали как /frontend/dist/frontend/index.html?/ — обратите внимание на знак вопроса перед последним слэшем. Дело в том, что на некоторых системах, при переходе по ссылкам в ангуляровском приложении, все крашится без этого знака. Судя по всему, статический веб-сервер движка хрома воспринимал изменение URL как запрос к другому файлу (даже несмотря на useHash: true) и при обновлении страницы возвращал 404 ошибку. Только в таком сочетании мне удалось добиться стабильной работы на всех системах.

Вернемся к package.json нашего приложения и добавим еще один скрипт

"prod": "ng build --sourceMap false --prod true --deploy-url /frontend/dist/frontend/ --base-href /frontend/dist/frontend/index.html?/"

Это будет скрипт для сборки нашего приложения для production версии.

В Chrome Web Store постится zip-архив с расширением и чтобы упростить сборку я сделал скрипт для этих целей

update.sh
#!/bin/bash

rm -rf ./prod-build
mkdir -p prod-build/frontend

cd frontend
npm run prod
cd ..

cp -R ./frontend/dist ./prod-build/frontend
cp -R ./extension ./prod-build
cp ./manifest.json ./prod-build

zip -r prod-build{.zip,}
rm -rf ./prod-build

Исходный код можно посмотреть тут.

Итого: мы создали заготовку для разработки Angular Chrome Extension с правильным роутингом и удобным обновлением/сборкой приложения.

P.S.: чтобы избавиться от такого /frontend/dist/frontend/ пути, можно настроить environment и в продакшн сборке по-другому прописывать путь, но это уже не ключевой момент.
Теги:
Хабы:
+6
Комментарии 1
Комментарии Комментарии 1

Публикации

Истории

Работа

Ближайшие события

Московский туристический хакатон
Дата 23 марта – 7 апреля
Место
Москва Онлайн
Геймтон «DatsEdenSpace» от DatsTeam
Дата 5 – 6 апреля
Время 17:00 – 20:00
Место
Онлайн