Представьте: вы написали расширение для Chrome — оно работает безупречно. Потом портируете на Firefox — и половина API ведёт себя иначе. На одном из проектов для финансового агрегатора browser.storage.local в Firefox возвращал undefined без ошибки, из-за чего слетали все пользовательские настройки. Пришлось переписать 40% кода. Каждый браузер — это два дня дополнительной отладки. Мы выработали системный подход: одна кодовая база, WebExtension API, полифилы и условная сборка. Единая кодовая база позволяет сократить бюджет на 40–60% по сравнению с раздельной разработкой для каждого браузера. Экономия времени в 3-4 раза — это сокращение бюджета на 30–50%. Стоимость разработки варьируется от 150 000 до 350 000 рублей в зависимости от функциональности. Получите консультацию по вашему проекту — мы поможем выбрать оптимальный стек и оценить стоимость.
Как мы решаем проблему совместимости API?
Полифил webextension-polyfill
Mozilla разработала webextension-polyfill — он преобразует chrome.* (Callback) в browser.* (Promise) и сглаживает различия между браузерами. Согласно спецификации WebExtensions, установка одной командой:
npm install webextension-polyfill import browser from 'webextension-polyfill'; const tabs = await browser.tabs.query({ active: true, currentWindow: true }); await browser.storage.local.set({ data: 'value' }); const result = await browser.storage.local.get('data'); Полифил сокращает время на адаптацию в 3-4 раза по сравнению с ручной обёрткой — это подтверждено на практике в проектах финансового и e-commerce секторов.
Совместимость API по браузерам
| API | Chrome | Firefox | Edge | Opera | Safari |
|---|---|---|---|---|---|
storage.local |
MV2/3 | MV2/3 | MV2/3 | MV2/3 | 14+ |
storage.sync |
✓ | ✓ | ✓ | ✓ | 15+ |
tabs |
✓ | ✓ | ✓ | ✓ | 14+ |
scripting (MV3) |
✓ | 101+ | ✓ | 92+ | 15.4+ |
declarativeNetRequest |
✓ | 113+ | ✓ | 92+ | 15.4+ |
sidePanel |
114+ | — | — | — | — |
webRequest |
MV2 only | ✓ | MV2 only | MV2 only | — |
Различия есть — например, sidePanel доступен только в Chrome 114+. Для таких случаев мы применяем условные пути и fallback-реализации. Общий принцип: полифил покрывает 90% типовых операций, остальное — ручная адаптация, которая надёжнее, чем множащиеся обёртки.
Почему мы используем раздельные манифесты?
Chrome с MV3 требует service_worker, Firefox с MV2 — background.scripts. Поддерживать оба манифеста параллельно — стандартная практика для максимального охвата. Мы собираем итоговый манифест скриптом из manifest.base.json + целевые настройки под каждый браузер:
// scripts/build.js const fs = require('fs'); const target = process.env.TARGET_BROWSER; const manifests = { chrome: { manifest_version: 3, background: { service_worker: 'background.js' }, action: { default_popup: 'popup.html' }, }, firefox: { manifest_version: 2, background: { scripts: ['background.js'], persistent: false }, browser_action: { default_popup: 'popup.html' }, browser_specific_settings: { gecko: { id: '[email protected]', strict_min_version: '109.0' }, }, }, safari: { manifest_version: 3, background: { service_worker: 'background.js' }, action: { default_popup: 'popup.html' }, browser_specific_settings: { safari: { strict_min_version: '15.4' }, }, }, }; const base = JSON.parse(fs.readFileSync('./manifest.base.json', 'utf8')); const merged = { ...base, ...manifests[target] }; fs.writeFileSync('./dist/manifest.json', JSON.stringify(merged, null, 2)); Сравнение манифестов MV2 и MV3
| Аспект | MV2 | MV3 |
|---|---|---|
| Background | background.scripts + Browser Action | Service Worker + Action |
API webRequest | Полная поддержка | Только declarativeNetRequest |
API tabs | Полная | С ограничениями (не в service worker) |
| Безопасность | Выполнение произвольного кода | Запрещено eval(), ограничены remote scripts |
| Установка | Ручная или автоматическая | Требуется подпись и обновления via store |
Выбор MV2 или MV3 зависит от целевых браузеров и функциональности. Например, для расширения, активно использующего webRequest, в Chrome всё ещё приходится тянуть MV2, хотя Firefox уже работает с MV3 через declarativeNetRequest. Мы помогаем определить оптимальную стратегию.
Как избежать ошибок при работе с сообщениями?
Строгая типизация сообщений между контекстами — залог отсутствия silent-багов. Мы используем дискриминированный union на TypeScript:
// shared/messages.ts export type Message = | { type: 'GET_PAGE_DATA'; url: string } | { type: 'SET_BADGE'; count: number; color?: string } | { type: 'OPEN_OPTIONS' } | { type: 'EXTRACT_TEXT'; selector: string }; export type MessageResponse<T extends Message> = T extends { type: 'GET_PAGE_DATA' } ? { title: string; meta: Record<string, string> } : T extends { type: 'EXTRACT_TEXT' } ? { text: string } : void; export async function sendMessage<T extends Message>( message: T ): Promise<MessageResponse<T>> { return browser.runtime.sendMessage(message) as Promise<MessageResponse<T>>; } export function onMessage<T extends Message['type']>( type: T, handler: (msg: Extract<Message, { type: T }>, sender: browser.runtime.MessageSender) => Promise<MessageResponse<Extract<Message, { type: T }>>> ) { browser.runtime.onMessage.addListener((msg, sender, sendResponse) => { if (msg.type === type) { handler(msg, sender).then(sendResponse); return true; } }); } Такой подход гарантирует, что обработчик получит именно тот тип сообщения, который ожидает. Компилятор не пропустит несоответствие. Типизированные сообщения — стандарт для всех наших проектов, включая финансовые и e-commerce расширения с сотнями тысяч пользователей.
Что входит в работу
Мы предоставляем готовое решение под ключ:
- Архитектура и проектирование — выбор стека, типизация, структура файлов.
- Реализация и тестирование — написание кода, unit-тесты, E2E-тесты с Playwright.
- Сборка и CI/CD — настройка Vite, скрипты сборки, GitHub Actions для публикации.
- Документация — README, описание API, инструкция по сборке.
- Публикация — загрузка в Chrome Web Store, Firefox AMO, Edge Add-ons, Opera Addons (Safari — по запросу).
- Поддержка — гарантийный период 30 дней после сдачи, исправление багов, адаптация к новым версиям браузеров.
Мы имеем опыт разработки расширений для финансового сектора, e-commerce и SaaS — более 5 лет и 30+ успешных проектов. Свяжитесь с нами для оценки вашего проекта — мы поможем выбрать оптимальную архитектуру.
Сроки
Кроссбраузерное расширение (Chrome + Firefox + Edge) с единой кодовой базой, типизацией, автосборкой и публикацией в три магазина — 10–16 рабочих дней в зависимости от функциональности. Добавление Safari (Xcode-обёртка + App Store) прибавляет 5–8 дней. Сроки ревью магазинов — отдельно и параллельно.
Закажите разработку кроссбраузерного расширения — мы оценим вашу задачу за один рабочий день. Получите консультацию по телефону или в чате, чтобы обсудить функциональность и сроки.







