C.W.K.
Stream
Lesson 02 of 06 · published

Service Worker 등록하기

~10 min · service-worker, manifest, background, clipdeck, hands-on

Level 0Extension 입덕
0 XP0/54 lessons0/13 achievements
0/100 XP to next level100 XP to go0% complete
"Track 1 은 ClipDeck 을 순수 UI — popup 전용 — 으로 끝냈어. 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 기준 상대, iconspopup 과 동일.
  • persistent field 없어 — 모든 MV3 service worker 는 정의상 event-driven. 옛 background page 를 살려두던 MV2 의 persistent: true 트릭은 그냥 사라졌어.

그게 background context 의 manifest 계약 전부. clipdeck/manifest.json 옆에 새 파일 저장.

Skeleton background.js

Listener 셋, module-level state 없음, setInterval 없음. 파일 위 부분은 매 wake-up 마다 실행; listener 는 event fire 시 실행. 그게 건강한 MV3 service worker 의 전체 형태 — event handler 의 flat 파일, 그 외 아무것도 없음.

알아둘 등록 두 가지:

  • 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 에서 그게 다시 print 될 때마다 worker 가 방금 cold start 한 거.

Reload, 검증, 깨우기

Manifest 업데이트 + background.js 저장 후:

  1. chrome://extensions 의 ClipDeck 카드 reload.
  2. chrome://serviceworker-internals 열고 ClipDeck 검색. Entry 하나 보여야 함: ClipDeck 의 service worker, 상태 RUNNING, 신선한 registration timestamp.
  3. 대략 30 초 대기. Refresh. 상태가 STOPPED 로 전환.
  4. 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 의 top-level 실행에서 나온 [ClipDeck SW] alive at ... 로그 보여줘. Network 패널은 fetch request (있으면). Application 탭은 storage (lesson 4 가 거기 살아). Sources 탭은 breakpoint, listener step-through, local 검사 가능.

알아둘 quirk 두 개:

  • Worker evict 돼도 DevTools window 는 열린 채로 유지. 다음 wake 가 같은 DevTools session 에 재attach.
  • 디버깅 도중 DevTools 닫으면 breakpoint 잃음. 다시 열고 재설정.

ClipDeck 이 이제 background 를 가짐

이 lesson 후 ClipDeck 은 surface 둘 — popup (UI, on-demand) 와 service worker (background, event-driven). Lesson 3 이 lifecycle 깊이, state loss 직접 데모 포함. Lesson 4 가 chrome.storage 를 생존 layer 로 추가. Lesson 5 가 popup ↔ SW message passing wire. Lesson 6 이 visit counter 로 묶음 — CRUD 의 R 워밍업.

Manifest field 는 작아. 그 뒤의 mental model 은 커. background.js 에 쓸 매 줄이 worker 가 event 사이에 사라질 수 있다는 걸 가정해.
background.js 의 모든 console.log[SW] prefix 박아. popup / content script / worker 모두 같은 DevTools session 에 로그 찍게 될 때 (Track 3 부터), prefix 가 어느 surface 가 말했는지 즉시 알려줘. Track 1-2 에 습관 싸게 들여놔, 헷갈릴 게 생기기 전에.

Code

clipdeck/manifest.json — background.service_worker 추가 + version bump·json
{
  "manifest_version": 3,
  "name": "ClipDeck",
  "version": "0.2.0",
  "description": "Selected-text clipboard you can CRUD from any page.",
  "icons": {
    "16": "icons/icon-16.png",
    "48": "icons/icon-48.png",
    "128": "icons/icon-128.png"
  },
  "action": {
    "default_popup": "popup.html",
    "default_title": "ClipDeck"
  },
  "background": {
    "service_worker": "background.js"
  }
}
clipdeck/background.js — 최소 service worker·javascript
// clipdeck/background.js — ClipDeck v0.2 (Track 2 lesson 2)
// Service worker top-level — runs on every wake-up.

console.log("[ClipDeck SW] alive at", new Date().toISOString());

chrome.runtime.onInstalled.addListener((details) => {
  console.log(
    "[ClipDeck SW] onInstalled — reason:",
    details.reason,
    "previousVersion:",
    details.previousVersion
  );
});

chrome.runtime.onStartup.addListener(() => {
  console.log("[ClipDeck SW] onStartup — Chrome launched");
});

// No module-level state. No setInterval. No fetch loops.
// Every event handler is the entire unit of work.

External links

Exercise

clipdeck/manifest.json 업데이트해서 background.service_worker field 추가 + version 을 "0.2.0" 으로 bump. clipdeck/background.js 를 위 skeleton 으로 생성. chrome://extensions 에서 ClipDeck 카드 reload. 그 다음 checkpoint 따라가: (1) chrome://serviceworker-internals — ClipDeck 찾고 status 메모 (reload 직후 RUNNING). (2) 30 초 대기, refresh — STOPPED 로 전환. (3) ClipDeck toolbar icon 클릭. chrome://serviceworker-internals refresh — RUNNING 으로 복귀. (4) ClipDeck 카드의 Inspect views: service worker 열어서 Console 에 [ClipDeck SW] alive at ... 로그 보이는지 확인.
Hint
chrome://serviceworker-internals 에 ClipDeck entry 안 보이면 manifest 업데이트 안 적용 — JSON syntax 확인 (trailing comma 가 보통 원인) 후 reload 재클릭. background.js 에 syntax error 있으면 ClipDeck extension 카드의 Errors panel 이 line 보여줘. background.service_worker 없는 extension 에는 Inspect views 가 안 나타나니까, 그 항목 존재가 manifest 적용 두 번째 확인.

Progress

Progress is local-only — sign in to sync across devices.
이 페이지에서 버그를 발견하셨거나 피드백이 있으세요?문제 신고

댓글 0

🔔 답글 알림 (로그인 필요)
로그인댓글을 남기려면 로그인해 주세요.

아직 댓글이 없어요. 첫 댓글을 남겨보세요.