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

manifest.json 안에 뭐가 들어가?

~12 min · mv3, manifest, schema, clipdeck, hands-on

Level 0Extension 입덕
0 XP0/54 lessons0/13 achievements
0/100 XP to next level100 XP to go0% complete
"manifest.json 은 extension 의 출생증명서야. Chrome 이 가장 먼저 읽는 파일이고, 가장 먼저 거절하는 파일이야."

세 필드짜리 manifest

Chrome 은 정확히 세 개 필드만 있는 manifest 를 받아 줘. 쓸 만한 건 안 되지만 — load 는 돼.

저게 바닥이야. 다른 모든 거 — popup / side panel / background worker / content script — 다 이 세 필수 field 위에 쌓는 거. 이 바닥을 알아야 안 쓸 15 개 필드를 cargo-cult 안 해.

Field 의 세 단계

manifest field 를 세 층으로 생각해:

  • 필수 — Chrome 이 이게 없으면 load 자체를 거부해. 딱 셋: manifest_version / name / version.
  • 강력 추천 — 없으면 load 는 되는데 user experience 망가져. description / icons / default_locale.
  • Surface 조건부 — 그 surface 를 쓸 때만 의미 있음. action (toolbar icon + popup) / background (service worker) / content_scripts / side_panel / permissions / host_permissions / content_security_policy / options_ui / commands / web_accessible_resources 등 십여 개.

Surface 안 쓰면서 surface 조건부 field 추가 — 무해하지만 noise. Surface 쓰면서 빠뜨려 — silent failure. extension 이 load 되긴 하는데 아무 일도 안 일어나. 그 부류 버그가 MV3 디버깅 스토리의 절반이야.

필수 3 인방 세부

  • manifest_version: 2024 이후로 반드시 3. 문자열 아닌 숫자.
  • name: 1-75 자, chrome://extensions 와 toolbar hover 에 표시.
  • version: 1-4 개의 점-구분 정수. "0.1.0" / "1.2" / "3" 다 valid. Chrome 이 update 비교할 때 숫자로 비교.

강력 추천 그룹

  • description: 1-132 자, name 아래 한 줄 설명.
  • icons: size (16, 32, 48, 128) 를 PNG path 로 매핑하는 object. 일부 size 빼먹어도 Chrome 이 graceful 하게 fallback 하지만 — 16 + 48 + 128 만 채워도 모든 UI surface 커버.
  • default_locale: _locales/*/messages.json i18n 활성화. 필요할 때까지 미뤄.

Surface 조건부 — 큰 것들

  • action — toolbar icon + popup 설정. default_popup 이 클릭 시 렌더할 HTML 파일 가리킴.
  • background — service worker 파일 선언. MV3 형태: { "service_worker": "background.js" }.
  • content_scripts — injection 규칙 배열. matches (URL pattern) / js (script 파일 list) / run_at (document_start | document_end | document_idle) / all_frames (boolean).
  • side_panel — Chrome side panel surface (Chrome 114+) 에 load 할 HTML.
  • permissions — API capability (storage / tabs / activeTab / scripting / sidePanel 등).
  • host_permissions — extension 이 read/inject 할 수 있는 URL pattern. API permissions 와 분리.
  • content_security_policy — extension page 가 뭘 load 가능한지 fine-tune. Default 이미 빡빡함; 풀거나 조이는 거 명확히 알 때만 건드려.

ClipDeck 의 hello-world manifest

Track 1 에서 ClipDeck 한테 필요한 거 다섯 가지: name / version / manifest version / toolbar icon / popup. 끝. Service worker 없음 / content script 없음 / side panel 없음 / permissions 없음 — Track 1 은 hello-world.

아래 manifest 를 clipdeck/manifest.json 으로 저장. Popup HTML 과 JS 는 lesson 4 (hello-clipdeck) 에서; icon 은 16×16 / 48×48 / 128×128 PNG 아무거나. 단색 사각형도 OK.

필수 셋, 추천 셋, 나머지 조건부. manifest.json 에서 기억할 거 하나만이라면 — 이 세 단계, 그리고 추가하는 모든 field 는 그게 선언한 surface 를 쓰겠다는 약속.
Silent failure 는 surface 조건부 field 에 산다. "service_worker" 오타 — load 됨. content script 의 matches 빠뜨림 — load 됨. Chrome 의 strictness 는 필수 field 에 즉시 발동하지, optional field 에 관대해 — 디버깅은 어느 침묵이 의심스러운지 아는 거.

Code

Chrome 이 받는 3-field 최소 manifest·json
{
  "manifest_version": 3,
  "name": "Bare Minimum",
  "version": "0.1.0"
}
ClipDeck Track-1 hello-world manifest.json (clipdeck/ 아래 저장)·json
{
  "manifest_version": 3,
  "name": "ClipDeck",
  "version": "0.1.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"
  }
}

External links

Exercise

clipdeck/ 디렉토리 편한 곳에 만들어 (Desktop / ~/dev / 어디든 작은 프로젝트 두는 곳). 이 lesson 의 ClipDeck hello-world manifest 를 clipdeck/manifest.json 으로 저장. 그 다음 placeholder PNG 아이콘 셋 — icons/icon-16.png / icons/icon-48.png / icons/icon-128.png — 만들어. 단색 사각형도 OK, 투명 PNG 도 OK, 아무 이미지 편집기 (Preview / Photoshop / 온라인 도구) 다 됨. Icon 건너뛰지 마 — Chrome 이 없어도 load 는 되지만 warning 띄워서, 깨끗한 load 원하면 채워. popup.html 자체는 lesson 4 의 일; 지금은 순수하게 manifest scaffold.
Hint
ImageMagick 깔려 있으면 아이콘 셋 한 줄로: for s in 16 48 128; do magick -size ${s}x${s} xc:steelblue icons/icon-${s}.png; done. macOS Preview 의 File → Export → PNG (고정 픽셀 dimension) 도 됨. 핵심은 정확한 path 에 valid PNG 파일을 두는 것 — manifest.json 의 icons field 가 깔끔하게 resolve 되도록.

Progress

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

댓글 0

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

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