4P by GN⁺ | ★ favorite | 댓글 1개
  • Extension.js는 Chrome, Edge, Firefox용 웹 확장 프로그램을 빌드하는 CLI로, npx extension@latest create my-extensionnpm run dev만으로 개발을 시작할 수 있음
  • Manifest V3 파편화, 브라우저별 차이, 콘텐츠 스크립트의 핫 리로드 부재, 대상별 별도 빌드 파이프라인을 무설정 개발 흐름으로 줄이는 것을 목표로 함
  • 배경, 콘텐츠, 팝업, 옵션 스크립트에 Hot Module Replacement를 제공하며 React, Vue, Svelte, Preact 컴포넌트와 TypeScript를 1급으로 지원함
  • extension build --zip으로 Chrome Web Store, Edge Add-ons, Firefox AMO 제출용 프로덕션 ZIP을 만들 수 있고, --browser=firefox 같은 브라우저별 빌드도 가능함
  • 기존 확장 프로그램에도 extension@latest를 개발 의존성으로 추가하고 build, dev, preview 스크립트를 연결하는 방식으로 도입할 수 있음

Extension.js가 해결하려는 문제

  • Extension.js는 Chrome, Edge, Firefox 확장 프로그램을 만들기 위한 CLI 도구임
  • 기본 사용 흐름은 새 프로젝트 생성 후 개발 서버를 실행하는 방식임
    • npx extension@latest create my-extension
    • cd my-extension
    • npm run dev
  • npm, pnpm, yarn, bun과 함께 동작함
  • 문서와 템플릿, 예제는 각각 Documentation, Templates, Examples에서 제공됨

개발 경험과 핵심 기능

  • 브라우저 확장 개발에서 다루는 Manifest V3 파편화, 브라우저별 차이, 콘텐츠 스크립트 핫 리로드 부재, 대상별 빌드 파이프라인 문제를 줄이는 데 초점을 둠
  • Hot Module Replacement는 background, content, popup, options 스크립트에 적용됨
    • React, Vue, Svelte, Preact 컴포넌트도 포함됨
  • Manifest V3를 기본으로 사용하며 Chrome, Edge, Firefox 대상에 대한 자동 어댑터를 제공함
  • 하나의 CLI로 Chrome, Edge, Firefox와 Chromium 또는 Gecko 기반 바이너리를 대상으로 실행할 수 있음
  • webpack, rollup, 유지보수할 플러그인 없이 zero config를 지향함
  • TypeScript, React, Vue, Svelte, Preact를 1급으로 지원함
  • extension build --zip으로 Chrome Web Store와 Firefox Add-ons 제출에 맞춘 프로덕션 빌드를 만들 수 있음
  • 기존 확장 프로그램에도 하나의 devDependency로 추가할 수 있음

다른 확장 개발 도구와의 차별점

  • Plasmo, WXT, CRXJS를 써본 사용자를 대상으로 Extension.js의 차이를 기능별로 제시함
  • GitHub 샘플을 직접 실행할 수 있음
  • 관리형 브라우저 바이너리를 제공함
    • 예: extension install firefox가 격리된 Firefox 빌드를 내려받음
  • 콘텐츠 스크립트용 크로스 브라우저 HMR이 내장되어 있으며 별도 플러그인 연결이 필요 없음
  • 스토어 제출용 프로덕션 ZIP을 만들 수 있음
    • 예: extension build --zip
  • 프레임워크에 종속되지 않음
  • 사용자 지정 Chromium 및 Gecko 바이너리를 지정할 수 있음
    • --chromium-binary
    • --gecko-binary

지원 프레임워크와 브라우저

  • 지원 프레임워크와 실행 예제는 템플릿 또는 예제로 제공됨
  • extension dev, extension start, extension preview에서 브라우저 관련 플래그를 사용할 수 있음
    • --browser <chrome | edge | firefox>로 브라우저를 선택함
    • --chromium-binary <path-to-binary>로 사용자 지정 Chromium 바이너리를 지정함
    • --gecko-binary <path-to-binary>로 사용자 지정 Gecko 또는 Firefox 바이너리를 지정함
  • 지원 브라우저는 Google Chrome, Microsoft Edge, Mozilla Firefox, Chromium 기반, Gecko 기반임
  • Apple Safari는 Next로 표시되어 있음

빌드, 패키징, 관리형 브라우저

  • 프로덕션 빌드는 npx extension@latest build로 실행함
  • 스토어 제출용 ZIP 패키지는 npx extension@latest build --zip으로 생성함
  • 브라우저별 빌드도 가능함
    • 예: npx extension@latest build --browser=firefox --zip
  • 유용한 빌드 플래그가 제공됨
    • --zip: 스토어 업로드용 ZIP으로 패키징함
    • --zip-source: 스토어의 소스 코드 검토를 위해 소스 파일을 포함함
    • --zip-filename <name>: 출력 파일명을 제어함
    • --polyfill: 크로스 브라우저 webextension polyfill을 활성화함
  • Extension.js는 깨끗한 개발 세션을 위해 격리된 브라우저 바이너리를 다운로드하고 관리할 수 있음
    • npx extension@latest install firefox
    • npx extension@latest install --browser=all
    • npx extension@latest install --where

기존 확장 프로그램과 샘플 실행

  • 기존 확장 프로그램에는 개발 의존성으로 설치함
    • npm install extension@latest --save-dev
  • package.json 스크립트에 extension build, extension dev, extension preview를 연결해 사용할 수 있음
    • npm run dev: 개발
    • npm run build: 프로덕션 빌드
    • npm run preview: 프로덕션 출력 확인
  • Chrome Extension Samples의 샘플을 직접 가져와 실행할 수 있음
  • 커뮤니티와 예제는 Discord, GitHub issues, examples에서 제공됨
  • 라이선스는 MIT

댓글과 토론

Hacker News 의견들
  • 멋진 프로젝트임. 내 확장 프로그램(https://github.com/herrherrmann/omnivore-list-popup)에도 써볼까 함
    지금까지는 확장 빌드나 개발 모드 관리를 직접 스크립트로 처리했지만, 이미 web-ext로 편하게 만들 수 있을지 보고 있었음
    다만 주 브라우저가 Firefox인데, Extension.js는 아직 Firefox를 완전히 지원하지 않는 것으로 보임

    • Mozilla Add-On은 --polyfill 플래그를 붙이면 Chrome이나 Edge에서 실행할 수 있지만, 현재 Firefox에는 확장을 수동으로 추가해야 함
      가까운 시일 내에 Firefox 지원을 넣을 계획은 있지만, 지금은 브라우저 실행기가 없음
  • 지금 딱 필요한 도구임. 만들어서 공유해줘서 고맙고, Firefox 지원이 잘 되길 기대함
    Firefox 지원 이슈: https://github.com/cezaraugusto/extension.js/issues/5

    • 특히 manifest.json의 충돌하는 요구사항을 다루는 데 도움이 되면 좋겠음
      예를 들면 이벤트 페이지와 백그라운드 서비스 워커의 차이, 또는 브라우저마다 요구하거나 금지하는 권한이 일관되지 않은 경우가 있음
    • GitHub의 Firefox 지원 이슈에 세부 내용을 더 적어주면 좋겠음. 커뮤니티가 해결을 도울 수도 있음
  • 좀 헷갈림. 이미 Chrome 전용 확장을 JavaScript로 작성해봤는데, 시작은 Chrome 확장 문서 사이트에서 파일 몇 개 복사하는 정도였음
    IDE 설정은 따로 하지 않았고, 뭘 해야 하는지도 잘 모르겠음
    이 도구가 파일 몇 개 복사하는 것 이상으로 무엇을 해주는지 이해하고 싶음. 크로스 브라우저 지원인지, 다중 언어 지원인지 궁금함

    • 그런 경우 Extension.js는 일반 웹 개발에서 놓치기 쉬운 설정 세부사항을 관리해줄 수 있음
      Chrome 확장 문서에서 파일 몇 개를 복사한 뒤에는 브라우저에서 “개발자 모드”를 직접 켜고 파일을 추가해야 함. 코드를 바꾸면 브라우저 확장이 영향을 주는 여러 실행 맥락을 수동으로 새로고침해야 변경 사항을 볼 수 있음. 여러 브라우저에서 테스트하려면 이 과정을 각각 반복해야 함
      TypeScript나 JavaScript 프레임워크 같은 패키지 의존성을 쓰려면 기존 확장 추상화 프레임워크에 의존해 새 방식을 배우거나, webpack, Parcel, esbuild 같은 도구로 직접 설정을 만들어야 함. 이쯤 되면 브라우저 확장 개발이 복잡하고 답답해질 수 있음
      Extension.js는 개발용 브라우저에서 확장을 묶어 실행하는 과정을 자동화해 이를 단순화함. HTML/CSS/JavaScript가 아닌 브라우저 영역까지 포함해 모든 실행 맥락에 자동 새로고침을 지원하고, TypeScript와 React 같은 코드 의존성도 별도 설정 마법 없이 설치만으로 지원함. 여러 브라우저에서도 동시에 실행됨
  • 좋은 프로젝트임. 첫 Chrome 확장은 https://crxjs.dev/vite-plugin/getting-started로 만들었는데, 스타일을 제대로 동작시키는 데 손이 많이 갔음
    브라우저 확장 개발이라서 그랬을 수도 있음: https://chromewebstore.google.com/detail/bettermenu-for-door...
    아직 할 일이 많아서 이 프로젝트도 확인해볼 예정임

  • 정말 멋짐. README까지 아름답게 잘 되어 있음
    Google Play가 워낙 엉망이라 앱에 확장을 붙이는 걸 미루고 있었는데, 이걸 한번 써볼 생각임

  • 멋짐. 비슷한 프레임워크인 Plasmo와는 어떻게 대비되는지 궁금함
    https://www.plasmo.com/

    • 가장 큰 차이는 Plasmo가 프레임워크라는 점이라고 봄. 즉 새 확장을 만들려면 그 추상화를 배우고, 그 추상화에 맞춘 예제에 의존해야 함
      브라우저 확장 자체와 꼭 관련 있지는 않은 설정 파일과 특정 규칙도 따라야 함
      반면 Extension.js는 표준 확장 API로 확장을 만들 수 있게 하고, 설정 파일만 추상화함. 도구 고유의 세부 방식을 배울 필요가 없음. 그래서 Chrome이나 MDN의 예제가 매니페스트 파일을 단일 기준으로 삼고 동작한다면, Extension.js에서 쓰기 위해 리팩터링할 필요가 없어 새 프로젝트를 시작하고 프로토타입을 만들기 쉬워짐
    • Plasmo는 매우 유용해 보임. 실제로 확장 개발에 써본 적이 있는지 궁금함
  • 확장을 몇 개 만들어봤음. 하나는 장난성으로, imgur가 하트 색을 바꿔 모두가 불만이었을 때 그 색을 바꾸는 확장이었음
    Chrome 확장을 만들 때마다 가면 증후군이 크게 옴. 이상하게 새 프로젝트를 만드는 게 너무 어려워서, 이런 도구가 있으면 정말 좋겠음

    • 완전 공감함. 확장 개발은 원래 재미있어야 하는 것 아닌가 싶음. 다음 프로젝트에서 Extension.js가 도움이 되길 바람
  • 마음에 듦. 확장과 탭 간 통신에도 마법을 좀 뿌려주면 좋겠음
    확장을 만들 때마다 DOM을 읽거나 확장에서 활성 탭으로 메시지를 보내는 과정이 늘 고통스러움

    • Plasmo에 살펴볼 만한 메시징 라이브러리가 있음
      https://docs.plasmo.com/framework/messaging
    • 당장 계획에는 없지만, 그동안 npm에 괜찮은 라이브러리가 분명 있을 것 같음
    • 이 과정에서 무엇이 특히 답답하거나 헷갈리는지 더 공유해줄 수 있는지 궁금함
  • 이슈를 하나 추가했음. Safari 지원은 Apple의 safari-web-extension-converter CLI 도구를 쓰면 비교적 단순할 것 같음

  • 좋아 보임. 내 확장인 Vim for Docs에 한번 써볼 예정임
    Firefox가 지원되지 않는 건 아쉽지만, 어차피 Firefox와 Chromium 기반 브라우저를 둘 다 지원하는 확장 빌드 도구가 있는 것도 아님

    • Firefox 지원은 다음 업데이트에 들어갈 예정임. 기대해도 좋음