Build Chrome Extensions · Part 2 — The Manifest, Deep Dive
Every manifest.json key that matters: action, permissions vs host_permissions, content_scripts, background, icons, web_accessible_resources, commands and side_panel — with an interactive manifest builder.
manifest.json là hợp đồng giữa extension và trình duyệt. Làm đúng thì mọi thứ vào khớp; làm sai thì không gì nạp được. Phần này là tài liệu tham chiếu bạn sẽ quay lại liên tục.
Bật tính năng trong builder và xem manifest tự ráp — tham chiếu khi ta đi:
1. Các key định danh
{
"manifest_version": 3,
"name": "My Extension",
"version": "1.0.0",
"description": "Short description shown in the store and management page.",
"icons": { "16": "icons/16.png", "48": "icons/48.png", "128": "icons/128.png" }
}
- phải là
3. - chuỗi số có dấu chấm; Web Store yêu cầu tăng mỗi lần upload.
- cung cấp tối thiểu 16, 48, 128.
2. action — nút trên thanh công cụ
"action": {
"default_popup": "popup.html",
"default_title": "My Extension",
"default_icon": { "16": "icons/16.png", "48": "icons/48.png" }
}
Nếu bỏ default_popup, bấm icon sẽ kích hoạt chrome.action.onClicked — hữu ích cho extension kiểu bật/tắt không có UI.
3. permissions vs host_permissions
Sự phân biệt này là điều quan trọng nhất trong manifest.
- quyền truy cập API
chrome.*(khả năng):
"permissions": ["storage", "tabs", "scripting", "contextMenus", "notifications", "alarms"]
- quyền truy cập dữ liệu của website cụ thể (origin):
"host_permissions": ["https://*.github.com/*", "https://api.example.com/*"]
Phân chia tư duy: permissions nói “tôi muốn dùng tính năng trình duyệt này”; host_permissions nói “tôi muốn đọc/sửa các site này”.
activeTablà bạn của bạn. Thay vìhost_permissionsrộng, quyềnactiveTabcấp truy cập tạm thời vào tab hiện tại chỉ khi user bấm icon — đỡ đáng sợ lúc cài và review store nhanh hơn.
Ta dành cả Phần 9 để dùng chúng an toàn.
4. content_scripts — code tự tiêm vào trang
"content_scripts": [
{
"matches": ["https://*.github.com/*"],
"js": ["content.js"],
"css": ["content.css"],
"run_at": "document_idle"
}
]
- mẫu khớp quyết định trang nào được tiêm script.
- thời điểm chạy.
- cũng có
exclude_matches,all_frames, và khớp theo glob.
Đầy đủ ở Phần 4.
5. background — service worker
"background": { "service_worker": "background.js", "type": "module" }
Ở MV3 nền là một service worker, không phải trang thường trú. "type": "module" cho phép dùng import. Phần 5 nói về vòng đời theo sự kiện của nó.
6. Bề mặt UI: options_page & side_panel
"options_page": "options.html",
"side_panel": { "default_path": "panel.html" }
options_page là trang cài đặt đầy đủ; side_panel (Chrome 114+) gắn một panel thường trú cạnh trang (cần quyền "sidePanel"). Cả hai ở Phần 8.
7. commands — phím tắt
"commands": {
"toggle-feature": {
"suggested_key": { "default": "Ctrl+Shift+Y", "mac": "Command+Shift+Y" },
"description": "Toggle the feature"
},
"_execute_action": { "suggested_key": { "default": "Ctrl+Shift+E" } }
}
_execute_action đặc biệt mở popup bằng bàn phím. Lệnh tùy biến kích hoạt chrome.commands.onCommand trong service worker.
8. web_accessible_resources — phơi file cho trang
Mặc định trang web không nạp được file từ extension của bạn. Để tiêm một ảnh hoặc script vào trang, bạn phải whitelist:
"web_accessible_resources": [
{ "resources": ["inject.js", "logo.png"], "matches": ["https://*/*"] }
]
MV3 yêu cầu giới hạn matches (không phơi cho tất cả một cách mù quáng) — vá một lỗ bảo mật thật từ MV2.
9. Bức tranh đầy đủ
Một manifest thực tế cho extension tương đối mạnh:
{
"manifest_version": 3,
"name": "GitHub Helper",
"version": "1.2.0",
"description": "Adds shortcuts and metrics to GitHub.",
"icons": { "16": "icons/16.png", "48": "icons/48.png", "128": "icons/128.png" },
"action": { "default_popup": "popup.html" },
"background": { "service_worker": "background.js", "type": "module" },
"content_scripts": [
{ "matches": ["https://github.com/*"], "js": ["content.js"], "run_at": "document_idle" }
],
"permissions": ["storage", "activeTab", "scripting", "contextMenus"],
"host_permissions": ["https://api.github.com/*"],
"options_page": "options.html",
"commands": { "_execute_action": { "suggested_key": { "default": "Ctrl+Shift+G" } } }
}
10. Bài tập
1. Key nào để truy cập chrome.storage, key nào để đọc trang https://news.ycombinator.com?
Lời giải
permissions cho API; host_permissions cho site.
2. Bạn muốn một phím tắt mở popup. Thêm gì?
Lời giải
"commands": { "_execute_action": { "suggested_key": { "default": "Ctrl+Shift+E" } } }3. Vì sao nên ưu tiên activeTab hơn "host_permissions": ["<all_urls>"] khi có thể?
Lời giải
activeTab cấp truy cập tạm thời, kích hoạt bằng click, chỉ tab hiện tại — đặc quyền tối thiểu, prompt cài đỡ đáng sợ, review store dễ hơn.
Nâng cao:trong builder, bật content scripts + host permissions + một command, và đọc xem entry nào xuất hiện trong mảng permissions.
Điểm chính
- Manifest là hợp đồng; chỉ ba key bắt buộc, còn lại khai báo khả năng.
permissions= APIchrome.*;host_permissions= truy cập site — giữ cả hai tối thiểu.- Mỗi bề mặt lớn có một key manifest.
web_accessible_resources(kèmmatches) cần để phơi file extension cho trang.
Tiếp theo
Phần 3 — Kiến trúc & mô hình component: popup, service worker, content script, options page liên hệ ra sao, mỗi cái làm được và không làm được gì, và bức tranh luồng dữ liệu giúp phần còn lại của series “thông”.