"Chrome 이 매 매칭 URL 마다 자동으로 inject 하든 (declarative), service worker 가 흥미로운 일 생긴 순간 inject 하든 (programmatic). Lesson 2 는 들어가려는 방에 맞는 문 고르기."
Declarative — manifest 가 그렇게 말함
더 단순한 경로: manifest.json 의 content_scripts 에 스크립트 list. Chrome 이 install 시점에 그 list 읽고 매칭되는 모든 navigation 에 inject. background.js 코드 없음, manifest 가 이미 선언한 것 외에 permission prompt 없음, tab 별 결정 없음. 그냥 "이 스크립트는 이 URL 들에 돈다."
각 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 가 아닌 때 돌아야 할 때.
- return value 원할 때 —
executeScript가 inject 한 함수 결과를 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 <all_urls> + 민감 site 용 fallback 으로 activeTab — 이게 canonical ClipDeck shape.
<all_urls> install 경고. "matches": ["<all_urls>"] 인 manifest 는 Chrome 의 "모든 웹사이트의 데이터를 read 하고 change" install prompt — user 가 보는 가장 무서운 거 — 를 trigger. 진짜 필요할 때만 사용. 가능하면 좁은 pattern (https://*.github.com/*) 이나 activeTab + programmatic injection 선호. Chrome Web Store review 도 명확한 정당화 없는 넓은 host permission 에 push back.