jvinhit//lab

Search posts

Type to search across journal entries.

navigate open esc close

Build Chrome Extensions · Part 3 — Architecture & the Component Model

How the popup, content script, service worker and options page relate — what each one can and cannot do, why they are isolated, and the data-flow that ties them together. With an interactive context map.

Lý do số một khiến người mới mắc kẹt là coi extension như một chương trình duy nhất. Không phải vậy. Nó là một hệ phân tán nhỏ: nhiều phần trong các ngữ cảnh cô lập, mỗi phần quyền khác nhau, phối hợp bằng tin nhắn. Thấm bản đồ này thì mọi thứ sau đó trở nên dễ.

Bấm từng ngữ cảnh và chạy luồng dữ liệu khi đọc:


1. Vì sao có sự cô lập

Mỗi ngữ cảnh chạy trong một môi trường JavaScript riêng vì bảo mật và ổn định. Một content script trên trang độc hại không được chạm vào code đặc quyền của service worker; một popup crash không được kéo sập logic nền. Cô lập là cái giá — và cũng là lợi ích.

Hệ quả phải nhớ: không chia sẻ biến hay gọi hàm giữa ngữ cảnh được. Bạn chia sẻ dữ liệu qua messaging (Phần 6) và chrome.storage (Phần 7).


2. Ma trận khả năng

PopupContent scriptService workerOptions
Access the page DOM
Has its own HTML UI± (can inject)
Full chrome.* APIslimited
Always available✗ (only when open)per matching pageon events
Keeps long-lived state

Hai hàng đáng nhấn mạnh:

  • Chỉ content script chạm DOM của trang. Popup và worker sống hoàn toàn ngoài trang.
  • Không gì giữ state lâu dài. Popup chết khi đóng, content script chết khi điều hướng, service worker tắt khi rảnh. Lưu mọi thứ quan trọng vào chrome.storage.

3. Bốn ngữ cảnh chi tiết

Popup — toàn quyền chrome.*, DOM riêng, nhưng phù du. Coi nó như một view thuần trên state đã lưu: đọc khi mở, ghi khi đổi, không bao giờ là nguồn sự thật.

Content script — chạy trong trang, ở thế giới cô lập: dùng chung DOM nhưng có scope JS riêng, tách khỏi script của trang. Nó chỉ dùng được một phần nhỏ chrome.* — muốn hơn thì nhắn cho worker.

Service worker — không DOM, không window, không document. Nó là bộ điều phối: phản ứng sự kiện từ mọi ngữ cảnh khác, gọi mạng, chạy logic xuyên tab, và sở hữu các thao tác state chung. Nó ngủ khi rảnh và thức dậy ở sự kiện kế (Phần 5).

Options page — như một popup to hơn, không phù du: toàn quyền chrome.*, DOM riêng, dùng cho cài đặt, đọc/ghi chrome.storage.


4. Luồng dữ liệu kinh điển

Một hành động điển hình — “user bấm nút popup để tô sáng chữ trên trang” — đi qua ba ngữ cảnh:

Popup  ──sendMessage──▶  Service worker  ──tabs.sendMessage──▶  Content script  ──▶  Page DOM
  ▲                                                                   │
  └───────────────────────  response  ◀──────────────────────────────┘
// popup.js — ask the worker
const res = await chrome.runtime.sendMessage({ action: 'highlight', term: 'todo' });

// background.js — relay to the active tab's content script
chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => {
  if (msg.action === 'highlight') {
    chrome.tabs.query({ active: true, currentWindow: true }, ([tab]) => {
      chrome.tabs.sendMessage(tab.id, msg, sendResponse);
    });
    return true; // keep the channel open for the async response
  }
});

// content.js — actually touch the DOM
chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => {
  if (msg.action === 'highlight') {
    highlightTermInDom(msg.term);
    sendResponse({ ok: true });
  }
});

Không phải hành động nào cũng cần cả ba chặng. Một popup chỉ gọi chrome.tabs.create() thì không cần content script. Nhưng khi liên quan DOM của trang, đây là hình dạng.


5. Chọn nơi đặt code

Hướng dẫn quyết định thực dụng:

  • Cần đọc/sửa trang đang xem? → content script
  • Cần quyền chrome.* (tab, mạng, xuyên tab)? → service worker
  • Một bảng điều khiển nhanh trên icon? → popup
  • UI cài đặt thường trú? → options page
  • Dữ liệu chung giữa tất cả? → chrome.storage

Giữ mỗi phần mỏng và đơn nhiệm; định tuyến mọi thứ đặc quyền qua worker.


6. Bài tập

1. Popup cần text <h1> của trang hiện tại. Những ngữ cảnh nào tham gia và theo thứ tự nào?

Lời giải

Popup → (worker hoặc trực tiếp) → content script đọc document.querySelector('h1') → gửi text về. Content script bắt buộc vì chỉ nó chạm DOM được.

2. Lưu lựa chọn “dark mode bật” ở đâu để popup, content script và options page đều nhất quán?

Lời giải

chrome.storage — lớp lưu trữ chung mọi ngữ cảnh đọc/ghi được.

3. Vì sao service worker không tự gọi document.querySelector được?

Lời giải

Nó không có DOM — không document hay window. Truy cập DOM phải ủy quyền cho content script.

Nâng cao:trong context map, chạy luồng dữ liệu và để ý request đi qua những ngữ cảnh nào trước khi tới trang.


Điểm chính

  • Extension là hệ phân tán của các ngữ cảnh cô lập — không biến chung, không gọi hàm xuyên ngữ cảnh.
  • Chỉ content script chạm DOM trang; worker không có DOM.
  • Không gì lâu dài — lưu vào chrome.storage.
  • Giao tiếp qua messaging; định tuyến việc đặc quyền qua service worker.

Tiếp theo

Phần 4 — Content script: tiêm JS và CSS vào trang, thế giới cô lập chi tiết, mẫu khớp và run_at, tiêm UI riêng, và các bẫy khi chạm trang của người khác.