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

Unpacked vs packed — Dev loop 와 .crx file

~10 min · unpacked, crx, developer-mode, distribution

Level 0Extension 입덕
0 XP0/54 lessons0/13 achievements
0/100 XP to next level100 XP to go0% complete
"Unpacked 가 너 위한 거, packed 가 다른 모두 위한 거. Lesson 2 가 quest 내내 써 온 developer-mode 'Load unpacked' loop 과 다른 머신으로 가는 signed .crx 의 차이."

Unpacked

Quest 전체, unpacked 로 작업해 옴: chrome://extensions → Developer mode → Load unpacked 통해 load 된 disk 의 폴더. Extension 이 디렉토리에서 file 들 live read; content.js 편집 + reload click 이 전체 dev loop. Bundling 필요 없음, 서명 없음, 어디든 upload 없음.

Unpacked extension 이 Chrome install 별 generated extension ID 받음 — 각 머신에서 다름. Development 엔 fine; specific extension ID hardcode 하는 거 ship 하면 (일부 Native Messaging host 가 이렇게) 문제 됨.

Packed

Packed extension 이 .crx file: extension content 의 ZIP + 서명 (제어하는 키로 RSA-signed, 또는 Web Store 통해 publish 하면 Chrome 자체로). .crx 가 다른 사람의 Chrome 에 install 되는 것.

생산 두 방법:

  • chrome://extensions → Pack extension — local 도구. Extension 디렉토리와 (선택적) .pem key file 요청. 첫 실행이 .crx 와 fresh .pem 둘 다 생산; future update 가 같은 key 로 서명하도록 .pem 안전한 곳 유지 (Chrome 이 update 에 same-key 를 same extension 으로 다룸).
  • Chrome Web Store — extension 디렉토리의 ZIP upload, Chrome 이 서명, .crx 가 store 에 살아. Public extension 의 99% 가 가는 경로.

Same-key update 계약

.pem (private key) 이 extension 의 identity 제어. 각 update 를 같은 .pem 으로 서명하는 한, Chrome 이 새 .crx 를 기존 extension 의 upgrade 로 다룸 — user 가 새 버전 받음, storage persist, extension ID 같음. Key 잃으면 그 extension 사실상 orphan; 새 ID 아래 새 extension publish 하고 user migrate 해야 함.

Web Store-published extension 은 local .pem 필요 없음 — Google 이 key 관리. Extension ID 가 첫 publish 시 생성되고 절대 안 바뀜.

Distribution 살아남는 dev workflow

권장: unpacked 로 개발, primary distribution 경로로 Web Store 통해 publish. Hybrid:

  • Git repo 하나, production permission 가진 single source-of-truth manifest.json.
  • Local dev: npm run builddist/ 로 출력, chrome://extensions 가 dist/ 에 'Load unpacked' point.
  • Ship 하려면: npm run build && cd dist && zip -r ../clipdeck.zip ., Web Store developer dashboard 에 zip upload.
  • Web Store 가 서명 / hosting / auto-update 처리; user 가 one click 으로 install.

Sideloading 과 어려운 이유

Chrome 이 Web Store 밖에서 .crx file install 을 무겁게 제한. Desktop Chrome:

  • Chrome://extensions 의 Drag-and-drop install 이 동작했지만; 이제 enterprise policy 나 developer-mode unpacked 통해 install 된 extension 으로 제한.
  • 직접 .crx URL → Chrome 이 "This extension can't be added from this website" 비슷한 거 prompt.
  • Group policy install (Chrome Enterprise) 이 sideloaded production extension 의 지원 경로.

Chrome Enterprise 없는 dev team 우회: Web Store 에 unlisted publish. 각자 unlisted URL 에서 install; 나머지는 normal Web Store flow.

Unlisted loophole

Web Store 의 'Unlisted' 가 extension 존재하지만 검색이나 category browsing 에 나타나지 안 한다는 뜻. URL 주면 사람들이 install 가능. Submission flow 가 public 과 같음 (privacy policy, review, 모든 것), 하지만 marketing surface 가 invisible. Chrome Enterprise overhead 정당화 안 하는 private-team extension 의 맞는 default.

Development 엔 unpacked, distribution 엔 Web Store 통해 packed. Sideloaded .crx file 이 v1 엔 dead end; Web Store (public 이나 unlisted) 사용하든가 enterprise group policy 에 commit 하든가.
.pem 을 git 에 commit 안 함. .pem private key 가 extension 서명; 그것 가진 사람이 너처럼 update publish 가능. Credential 처럼 다루기: repo 밖 유지, password manager 에 사본 저장, backup 손-encrypt. 잃는 게 Web Store extension 엔 catastrophic 아님 (Google 이 자체 key 가짐) 하지만 local 서명한 어떤 extension 에도 catastrophic.

Code

Shell — Web Store upload artifact 생산·bash
# Web Store upload 위한 build + zip
npm run build                       # dist/ 출력
cd dist && zip -r ../clipdeck.zip .  # source map / .gitignore 등 exclude
cd ..
ls -la clipdeck.zip                  # 이게 upload 할 것
manifest.json — Chrome 의 update 감지에 semver-friendly version 유지·json
{
  "name": "ClipDeck",
  "version": "1.0.0",
  "description": "Save text clips from any page. Browse, search, and copy from a persistent side panel.",
  "manifest_version": 3
}

External links

Exercise

현재 dev loop 검증: chrome://extensions → Developer mode toggle ON → Load unpacked → clipdeck/ 디렉토리 선택. 작은 visible 변경 (popup heading rename), card 의 reload 버튼 click, popup update 확인. 다음 같은 page 의 Pack extension 버튼 시도 — clipdeck/ 디렉토리 선택, key field 비워 두기, Pack click. 부모 디렉토리에 .crx 와 .pem 얻음. .crx 를 chrome://extensions 에 드래그해서 install 시도 — Chrome 이 untrusted source 메시지로 거부하는 거 주목. Sideload 제한 작동. .crx 와 .pem 이 self-hosted enterprise distribution 엔 여전히 유용; Web Store 엔 대신 unsigned zip upload.
Hint
'Load unpacked' 가 silently 아무것도 안 하면, manifest.json 에 JSON syntax error 가질 수도 — chrome://extensions 열고 extension card 의 'Errors' 버튼 찾기. Reload 가 popup.html 변경 안 잡으면, popup 도 reload 필요할 수도 (popup 닫고 다시 열기). Background.js 변경은 항상 reload 버튼 필요; popup/panel HTML 편집이 Chrome cache 했으면 가끔 안 함. 생성한 .pem 이 너 눈 only — 공유 안 함, commit 안 함, SSH key 처럼 다루기.

Progress

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

댓글 0

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

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