"Track 1은 ClipDeck을 popup만 있는 순수 UI로 끝냈어. Track 2가 background를 부여하면서 시작. Manifest field 하나, 파일 하나, reload 한 번, ClipDeck이 service worker를 갖게 돼."
Manifest field 하나, 파일 하나
Manifest 변경은 작아: top-level background object 하나가 worker 파일 가리킴. 세 가지 주목:
service_worker는 단수. MV2 (배열의scripts를 받았던)와 다르게, MV3는 파일 정확히 하나만 받아. Logic 분할 필요하면 ES module import 사용.- Path는 extension root 기준 상대,
icons나popup과 동일. persistentfield 없어 — 모든 MV3 service worker는 정의상 event-driven. 옛 background page를 살려두던 MV2의persistent: true트릭은 그냥 사라졌어.
그게 background context의 manifest 계약 전부. clipdeck/ 안 manifest.json 옆에 새 파일 저장.
Skeleton background.js
listener 셋이 전부고, 파일 최상위에 들고 있는 state도 없고, setInterval도 없어. 맨 윗부분은 깨어날 때마다 다시 돌고, listener는 event가 올 때 돌아. 건강한 MV3 service worker는 딱 이렇게 생겼어 — event handler만 평평하게 늘어놓은 파일 하나, 그 밖엔 아무것도.
알아둘 등록 두 가지:
chrome.runtime.onInstalled— install 시 한 번, 매 extension update 시 한 번, Chrome update 시에도 fire.details.reason으로 분기.chrome.runtime.onStartup— Chrome이 extension 이미 install 된 상태로 launch 할 때 fire. Browser session 당 한 번 일어나야 하는 daily-rollup 류 작업에 유용.
위 부분의 console.log가 eviction tracker야. DevTools에서 다시 찍힐 때마다 worker가 방금 cold start 한 거지.
Reload, 검증, 깨우기
Manifest 업데이트 + background.js 저장 후:
chrome://extensions의 ClipDeck 카드 reload.chrome://serviceworker-internals열고 ClipDeck 검색. Entry 하나 보여야 함: ClipDeck의 service worker, 상태 RUNNING, 신선한 registration timestamp.- 대략 30 초 대기. Refresh. 상태가 STOPPED로 전환.
- ClipDeck toolbar icon 클릭 (event 면 뭐든 — message / alarm / tab change). Refresh. 상태 RUNNING으로 복귀.
그게 service worker의 전체 dev loop: edit → reload → worker 존재 확인 → 필요할 때 깨우기 → idle out 관찰.
Service worker 검사하기
chrome://extensions → ClipDeck 카드 → "Details" → "Inspect views: service worker". DevTools가 worker scope로 열림. Console 에는 background.js 맨 위가 돌면서 찍은 [ClipDeck SW] alive at ...이 보일 거야. Network 패널에는 fetch 요청이 있으면 뜨고, Application 탭에서 storage를 볼 수 있어 (lesson 4가 거기서 놀아). Sources 탭에서는 breakpoint를 걸고 listener를 한 줄씩 따라가면서 지역 변수도 들여다볼 수 있고.
알아둘 quirk 두 개:
- Worker evict 돼도 DevTools window는 열린 채로 유지. 다음 wake가 같은 DevTools session에 재attach.
- 디버깅 도중 DevTools 닫으면 breakpoint 잃음. 다시 열고 재설정.
ClipDeck이 이제 background를 가짐
이 lesson을 지나면 ClipDeck은 자리를 둘 갖게 돼. 필요할 때만 뜨는 popup과, 뒤에서 event를 기다리는 service worker. Lesson 3에서 한 살이를 깊게 보면서 state가 실제로 날아가는 걸 눈으로 확인하고, Lesson 4에서 chrome.storage를 살아남는 층으로 얹고, Lesson 5에서 popup과 SW 사이 메시지를 잇고, Lesson 6에서 방문 카운터로 그걸 다 묶어. CRUD의 R을 위한 몸풀기지.
console.log에 [SW] prefix 박아. popup / content script / worker 모두 같은 DevTools session에 로그 찍게 될 때 (Track 3부터), prefix가 어느 surface가 말했는지 즉시 알려줘. Track 1-2에 습관 싸게 들여놔, 헷갈릴 게 생기기 전에.