כאשר מעבירים תוסף Chrome ל-Firefox, מפתחים רבים נתקלים בהבדלים לא מובנים מאליהם: מרחבי שמות שונים של API, חתימה חובה ב-AMO, ומוזרויות של Content Scripts. בהתבסס על ניסיון של 10+ שנים ולמעלה מ-50 פרויקטים מוצלחים, אנו מציעים פיתוח Firefox Add-on מקצה לקצה המתחשב בניואנסים אלה. למעלה מ-90% מה-API תואם, אבל הפרטים חשובים.
תוספי Firefox מבוססים על WebExtensions API — אותה מפרט כמו תוספי Chrome. רוב תוספי Chrome ניתנים להעברה ל-Firefox עם שינויים מינימליים. אבל ישנם הבדלים בתמיכת API, בהליך החתימה ובמנוע התוספים.
הבדלים בין Firefox ל-Chrome ואתגרי ההעברה
| היבט | Firefox | Chrome |
|---|---|---|
| מרחב שמות של API | browser.* (Promise) + chrome.* |
chrome.* (Callback) |
| Manifest | MV2 ו-MV3 (MV3 נוסף ב-Firefox 109+) | רק MV3 (MV2 הוצא משימוש) |
| רקע | דף רקע קבוע (MV2) או SW (MV3) | רק Service Worker |
| חתימה | חובה דרך AMO | לא נדרשת |
browser_style |
נתמך | לא נתמך |
מעבר מ-chrome.* ל-browser.* הוא המלכוד הראשון. Firefox משתמש ב-Promises מקוריים, בעוד Chrome מסתמך על callbacks. ללא webextension-polyfill, הקוד לא יעבוד באופן זהה בשני הדפדפנים. Content Scripts ב-Firefox מבודדים באמצעות Xray wrapper — גישה ישירה לאובייקטי הדף בלתי אפשרית; יש להשתמש ב-window.postMessage. בנוסף, חתימת AMO החובה מאטה את מחזור השחרור אם CI לא מוגדר עם מפתחות API.
למה להשתמש ב-webextension-polyfill?
ה-polyfill מאפשר לכתוב קוד פעם אחת, באמצעות browser.* API עם Promises, והוא יעבוד ב-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 Scripts ב-Firefox. הוא מונע גישה ישירה לאובייקטי JavaScript של הדף, מה שמגביר את האבטחה אך מסבך את האינטראקציה. לתקשורת בין הסקריפט לדף, השתמשו ב-{ "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 } } או ב-window.postMessage. דוגמה:
// 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__,
}, '*');
}
}); API מבוסס Promise ו-Content Script
Firefox תומך ב-Promises מקוריים ב-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__, }, '*'); } }); הופך את הקוד לתואם ל-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 של הדף. לאינטראקציה עם הדף, נדרש browser.* או webextension-polyfill.
פרסום, חתימה ובדיקות CI
Firefox דורש חתימה על ידי Mozilla עבור כל תוסף שאינו מופץ דרך AMO. השתמשו ב-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'); — ה-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/en-US/developers/addon/api/key/. ללא חתימה, התוסף ניתן להתקנה רק דרך window.postMessage:
- פתחו את
CustomEvent - "טען תוסף זמני"
- בחרו
web-ext - עובד עד להפעלה מחדש של הדפדפן
לפריסה ארגונית ללא AMO — השתמשו ב-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 ב-Firefox Enterprise.
נוסף: תמיכה ב-Containers
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
המהנדסים שלנו, עם ניסיון של 10+ שנים ולמעלה מ-50 פרויקטים מוצלחים, עוקבים אחר תהליך סטנדרטי: בדיקת דרישות, עיצוב ארכיטקטורה, יישום באמצעות TypeScript ו-React או JavaScript פשוט, בדיקות במספר גרסאות Firefox (כולל Developer Edition ו-Nightly), חתימה אוטומטית דרך CI, ופרסום ב-AMO. התוצאה היא תוסף מוכן לשימוש מלא עם תיעוד. באמצעות webextension-polyfill, הפיתוח מהיר פי שניים בהשוואה ליישום נפרד, ונפח הקוד מופחת ב-60%.
מה כלול בפיתוח Firefox Add-on
| רכיב | תיאור |
|---|---|
| קוד מקור | קוד תוסף מלא (MV2 או MV3) |
| אינטגרציית AMO | חתימה ופרסום בחנות |
| תיעוד | הוראות התקנה והגדרה |
| אחריות תאימות | תמיכה בגרסאות Firefox העדכניות |
| תמיכה | 30 יום לאחר המסירה |
לוח זמנים ועלות
תוסף Firefox המותאם מתוסף Chrome, עם חתימה ופרסום ב-AMO — 2–3 ימי עסקים בנוסף לתוסף Chrome המוכן. פיתוח תוסף חדש מאפס — 4–8 ימים בהתאם לפונקציונליות. העלות מחושבת באופן אישי לפי מורכבות — צרו קשר להערכה מדויקת.
הזמינו פיתוח Firefox Add-on: קבלו ייעוץ מהמומחים שלנו היום. אנו מבטיחים תאימות לגרסאות Firefox העדכניות ותיעוד מלא. צרו קשר כדי לדון בפרטי הפרויקט שלכם — נספק הערכה ראשונית תוך 24 שעות.







