При портировании Chrome-расширения на Firefox многие разработчики сталкиваются с неочевидными отличиями: разный API namespace, обязательная подпись через AMO и особенности Content Script. На основе нашего опыта более 10 лет и более 50 успешных проектов мы предлагаем разработку Firefox Add-on под ключ с учётом этих нюансов. Более 90% API совпадает, но детали решают.
Firefox Add-ons основаны на WebExtensions API — той же спецификации, что и Chrome Extensions. Большинство Chrome-расширений можно перенести на Firefox с минимальными правками. Но есть различия в деталях: поддержка API, процедура подписи, движок расширений.
Отличия Firefox от Chrome и сложности портирования
| Аспект | Firefox | Chrome |
|---|---|---|
| API namespace | browser.* (Promise) + chrome.* |
chrome.* (Callback) |
| Manifest | MV2 и MV3 (MV3 добавлен в Firefox 109+) | Только MV3 (MV2 устарел) |
| Background | Persistent background page (MV2) или SW (MV3) | Только Service Worker |
| Подпись | Обязательна через AMO | Не требуется |
browser_style |
Поддерживается | Не поддерживается |
Переход с chrome.* на browser.* — первый подводный камень. Firefox использует нативные Promise, тогда как Chrome полагается на callback'и. Без webextension-polyfill код не будет одинаково работать в обоих браузерах. Content Script в Firefox изолированы через Xray wrapper — прямой доступ к объектам страницы невозможен, приходится использовать window.postMessage. Также обязательная подпись на AMO замедляет release cycle, если не настроить CI с API-ключами.
Почему стоит использовать webextension-polyfill?
Полифил позволяет писать код один раз, используя browser.* API с Promise, и он будет работать в Chrome. Это сокращает объём кода в 3 раза по сравнению с дублированием для каждого браузера. Однако требуется тестирование: некоторые Chrome-специфичные функции могут не иметь аналогов.
Manifest V2: наиболее стабильный вариант для Firefox
{
"manifest_version": 2,
"name": "My Firefox Add-on",
"version": "1.0.0",
"description": "Описание дополнения",
"permissions": [
"storage",
"tabs",
"activeTab",
"https://*.example.com/*"
],
"background": {
"scripts": ["background.js"],
"persistent": false
},
"browser_action": {
"default_popup": "popup.html",
"default_icon": {
"48": "icons/icon48.png",
"96": "icons/icon96.png"
}
},
"content_scripts": [
{
"matches": ["https://*.target-site.com/*"],
"js": ["content.js"]
}
],
"options_ui": {
"page": "options.html",
"open_in_tab": false
}
} Что такое Xray wrapper и как с ним работать?
Xray wrapper — это механизм изоляции Content Script в Firefox. Он предотвращает прямой доступ к JavaScript-объектам страницы, что повышает безопасность, но усложняет взаимодействие. Для связи между скриптом и страницей используйте window.postMessage или CustomEvent. Пример:
// Content script -> Page script
window.postMessage({ source: 'myExtension', type: 'REQUEST_DATA' }, '*');
// Page script обработчик
window.addEventListener('message', (e) => {
if (e.data?.source === 'myExtension' && e.data?.type === 'REQUEST_DATA') {
window.postMessage({
source: 'myPage',
type: 'RESPONSE_DATA',
payload: window.__MY_APP_STATE__,
}, '*');
}
}); Promise-based API и Content Script
Firefox поддерживает нативные Promise в browser.*. Полифил webextension-polyfill делает код совместимым с Chrome:
import browser from 'webextension-polyfill'; // Firefox — нативные промисы
const tabs = await browser.tabs.query({ active: true, currentWindow: true });
const tab = tabs[0];
// Выполнить скрипт (MV2)
await browser.tabs.executeScript(tab.id, {
code: 'document.body.style.background = "yellow"',
});
// Хранилище
await browser.storage.local.set({ key: 'value' });
const result = await browser.storage.local.get('key');
В Firefox Content Scripts работают в изолированном мире (Xray wrapper) — они не имеют доступа к JavaScript-объектам страницы напрямую. Для взаимодействия со страницей нужен window.postMessage или CustomEvent.
Публикация, подпись и тестирование через CI
Firefox требует подписи от Mozilla для любого расширения, распространяемого не через AMO. Используйте web-ext — официальный CLI от Mozilla — и настройте подпись в CI (например, GitHub Actions):
npm install -g web-ext
# Разработка с hot reload
web-ext run --source-dir ./dist --firefox-binary "/path/to/firefox"
# Сборка
web-ext build --source-dir ./dist --artifacts-dir ./artifacts
# Подпись (нужны AMO API ключи)
web-ext sign \
--source-dir ./dist \
--api-key $AMO_JWT_ISSUER \
--api-secret $AMO_JWT_SECRET
Для получения API ключей: addons.mozilla.org/developers/addon/api/key/. Без подписи расширение можно установить только через about:debugging:
- Открыть
about:debugging#/runtime/this-firefox - «Загрузить временное дополнение»
- Выбрать
manifest.json - Работает до перезапуска браузера
Для корпоративного деплоя без AMO — использовать policies.json в Firefox Enterprise.
Дополнительно: поддержка контейнеров
Firefox поддерживает Containers — изолированные контексты с разными куки. Доступ через API:const containers = await browser.contextualIdentities.query({}); // { cookieStoreId, name, color, icon }
// Открыть вкладку в конкретном контейнере
await browser.tabs.create({
url: 'https://example.com',
cookieStoreId: 'firefox-container-1',
});
Как мы разрабатываем Firefox Add-on?
Наши инженеры с 10+ летним опытом и более чем 50 успешными проектами проходят через стандартный процесс: аудит требований, проектирование архитектуры, реализация с использованием TypeScript и React или vanilla JS, тестирование в нескольких версиях Firefox (включая Developer Edition и Nightly), автоматическая подпись через CI и публикация на AMO. Результат — полностью готовое к использованию расширение с документацией. Благодаря использованию webextension-polyfill разработка идёт в 2 раза быстрее по сравнению с раздельной реализацией, а объём кода сокращается на 60%.
Что входит в разработку Firefox Add-on
| Компонент | Описание |
|---|---|
| Исходный код | Полный код расширения (MV2 или MV3) |
| Интеграция с AMO | Подпись и публикация в магазине |
| Документация | Инструкция по установке и настройке |
| Гарантия совместимости | Поддержка последних версий Firefox |
| Поддержка | 30 дней после сдачи |
Сроки и стоимость
Firefox Add-on, адаптированный из Chrome-расширения, с подписью и публикацией на AMO — 2–3 рабочих дня дополнительно к готовому Chrome-расширению. Разработка нового дополнения с нуля — 4–8 дней в зависимости от функциональности. Стоимость рассчитывается индивидуально и зависит от сложности — свяжитесь с нами для точной оценки.
Закажите разработку Firefox Add-on: получите консультацию наших специалистов уже сегодня. Мы гарантируем совместимость с последними версиями Firefox и полную документацию. Свяжитесь с нами, чтобы обсудить детали вашего проекта — мы предоставим предварительную оценку в течение 24 часов.







