"Chrome이 매 매칭 URL 마다 자동으로 inject 하든 (declarative), service worker가 흥미로운 일 생긴 순간 inject 하든 (programmatic). Lesson 2는 들어가려는 방에 맞는 문 고르기."
Declarative — manifest가 그렇게 말함
더 단순한 길부터 보자. manifest.json의 content_scripts에 스크립트를 적어 두는 거야. 그러면 Chrome이 설치할 때 그 목록을 읽어 두고, 조건에 맞는 페이지로 갈 때마다 알아서 넣어 줘. background.js에 쓸 코드도 없고, manifest에 이미 적어 둔 것 말고 추가로 물어보는 것도 없고, tab 마다 판단할 일도 없어. 그냥 "이 스크립트는 이 주소들에서 돈다" 하나야.
각 entry가 logical content script 하나. 실제로 쓸 field 들:
matches— 필수. URL match pattern 배열 (https://*.github.com/*,<all_urls>, 등).exclude_matches— 선택,matches에서 빼낼 영역.js— extension package 안 script file 배열.css— stylesheet file 배열. 같은 방식으로 inject.run_at—document_start(DOM parse 전),document_end(DOM ready, resource는 로딩 중),document_idle(다 settle — default).all_frames— boolean, default false. iframe 안에도 닿아야 하면 true.world—ISOLATED(default, Lesson 3에서 다룸) 또는MAIN(Chrome 111+, page 자체 JS world에서 실행).
Programmatic — chrome.scripting.executeScript
On-demand 경로: manifest에 스크립트 list 안 하고, 뭔가 trigger 되면 service worker가 inject. Toolbar icon 클릭, context menu activation, popup 메시지, alarm fire 등 — SW가 chrome.scripting.executeScript 부르고 함수나 파일을 특정 tab에 push.
이게 맞는 도구일 때:
- 스크립트가 가끔만, 모든 page load가 아닌 때 돌아야 할 때.
- inject한 함수의 return value가 SW로 돌아와야 할 때.
- Manifest가 표현 못 하는 logic 기반으로 어느 tab / 어느 frame 인지 선택해야 할 때.
대가는 "scripting" permission과 만지려는 URL의 host permission — permission 모델은 Track 6가 풀어 줘.
activeTab 단축키
현재 tab의 toolbar-click injection 에는 "activeTab" 이라는 특별 permission이 있어 — user prompt 없이 임시 host access 부여. User가 toolbar icon 클릭 (또는 context menu / keyboard shortcut trigger) 시 활성화, navigation까지 그 tab에 유지. Opt-in extension의 Chrome 권장 경로 — 무서운 <all_urls> 경고 없이 "지금 있는 페이지에 부탁하면 동작".
둘 결합
둘 다 같이 쓰는 게 완전히 valid 하고 흔해. ClipDeck의 최종 shape:
- Declarative — 항상 도는 선택 capture: 매 page, user 선택 listening, 저장 요청 시 즉시 보낼 수 있게.
- Programmatic — 일회성 작업: "이 page의 article body 추출," "이 page에 저장된 clip highlight," toolbar icon 이나 popup 버튼으로 trigger.
ClipDeck Track 3 선택
Track 3 milestone — user 선택 텍스트 저장 — 에는 declarative가 승리. 스크립트가 매 page에서 listening 해야 user가 save action 부르는 순간 selection이 이미 scope에 있어. Programmatic injection은 user의 intent와 race 하게 됨: SW가 inject 끝낼 무렵 selection이 사라졌을 수 있어 (toolbar 클릭이 popup 접고 가끔 selection clear). 넓은 declarative match와 activeTab programmatic path는 같은 정적 script의 fallback 관계가 아니라 별도 전략이야. Declarative entry에서 뺀 site라면 user gesture 뒤 chrome.scripting.executeScript를 부를 때만 activeTab이 도와.
<all_urls> install 경고. "matches": ["<all_urls>"] 인 manifest는 Chrome이 "모든 웹사이트의 데이터를 읽고 변경"한다는 강한 install prompt를 띄워. user가 가장 경계하는 경고야. 진짜 필요할 때만 사용. 가능하면 좁은 pattern (https://*.github.com/*) 이나 activeTab + programmatic injection 선호. Chrome Web Store review도 명확한 정당화 없는 넓은 host permission에 push back.