크롬 익스텐션 개발 공부하기
크롬 익스텐션을 만들 일이 생겨서 급하게 공부를 했습니다. 공부해서 알게 된 내용 자체는 딱히 정리할 가치가 적겠지만, 공부를 한 과정을 기록으로 남기면 혹시 누군가에게 도움이 될 수도 있을까 싶어서 글을 씁니다.
공부할 계기와 맥락을 만들기
막연하게 ‘이걸 공부해두면 언젠가 도움이 되겠지’하는 모드보다는, 구체적인 맥락과 목표가 있는 상황에서 공부를 하면 더 좋다고 생각합니다.
코딩도 비슷합니다. 막연하게 ‘이렇게 설계를 해두면 언젠가 도움이 되겠지’보다는, 구체적인 요구사항이 있고 이 요구사항을 가장 잘 만족할 수 있는 최소한의 코드를 만드는 편이 대체로 더 좋습니다.
애자일 방법론에서는 이를 YANGI, DTSTTCPW라고 줄여서 부릅니다.
- YAGNI: You Are Not Gonna Need It
- DTSTTCPW: Do The Simplest Thing That Could Possibly Work
도요타 방식Toyota Way 또는 이를 본받은 린 소프트웨어 개발Lean Software Development에서는 풀pull과 푸시push로 구분하기도 합니다. ‘이런 걸 만들면 팔리겠지’보다는(일단 만들고 시장에 밀어내는 푸시 방식) ‘시장 수요에 반응하여 만든다’를(시장의 수요가 당기면 이에 반응하며 만드는 방식) 더 선호합니다.
일상에서 또는 업무 중에 공부를 할 계기를 만들려고 노력하면 좋다고 생각합니다. 공부를 위해서 억지로 안해도 될 일을 만들라는 뜻은 아니고, 여러 선택지가 있다면 되도록 공부가 되는 방향으로 선택을 하면 좋다는 뜻입니다.
공부 시작. 현황 파악
처음 할 일은 현재의 지식 수준을 점검하고, 주어진 일을 하기 위해 필요한 최소한의 학습 목표를 설정하는 것입니다.
크롬 확장 기능이 웹 표준을 최대한 재활용하는 기술이라는 사실은 이미 알고 있고, HTML/CSS/JS 등 웹 표준도 어느 정도 알고 있는 상황입니다. 그러니 크롬 확장 기능을 개발하기 위해 필요한 내용만 추가로 공부를 하면 됩니다. 그 중에서도 특히 이번 업무에서 필요한 익스텐션이 실행되고 있는 페이지의 DOM을 읽고 쓰는 방법입니다.
따라서 대략적인 목표는 이렇습니다.
- 크롬 확장 기능의 주요 개념을 빠르게 익히기
- DOM을 읽고 쓰는 방법 알아내기
크롬 확장 기능의 주요 개념 빠르게 익히기
우선 구글에서 “chrome extensions development”를 검색해서(쌍따옴표는 없이 입력), 공식 개발자 문서를 찾았습니다.
“Welcome”, “What’s new”, “Getting started” 등의 내용이 눈에 띕니다. 저는 보통 “What’s new”를 먼저 훑어 읽는 편입니다. 모르는 말들이 얼마나 많이 나오는지, 최근에 어떤 변화들이 있었는지 등 ‘분위기 파악’을 할 수 있어서 좋습니다.
“What’s new”를 대충 훑어 읽다보니 “Manifest V3”이 최신 버전이며 “Manifest V2” 지원이 곧 끝난다는 말이 눈에 띕니다. V2와 V3 사이의 차이가 얼마나 큰지는 모르겠지만, 스택오버플로우 등에서 크롬 확장 기능 관련 글을 읽을 때 V2에 대한 내용인지 V3에 대한 내용인지를 구분해서 봐야할 것 같다는 생각을 했습니다.
대충 분위기 파악을 했으니 “Getting started” 문서를 열었습니다.
익스텐션이 할 수 있는 일들은
- 서비스 워커 사용
- 현재 페이지의 DOM을 읽고 쓰기
- 커스텀 옵션 페이지를 만들기
- 아이콘을 누르면 나오는 메뉴나 브라우저 주소창이나 컨텍스트 메뉴 커스터마이징
등이 있다고 합니다. 이 중 특히 관심이 가는 내용은 “현재 페이지의 DOM 읽고 쓰기”입니다.
이어서 간단한 튜토리얼이 나오는데 이걸 따라해보면 좋겠다는 생각을 했습니다.
튜토리얼 따라하기
튜토리얼을 따라할 때 코드를 복붙하지 않고 직접 입력하는 걸 선호하는 편입니다. 저만 그런지 모르겠는데, 복붙을 하고나서 읽으며 이해하는 느낌이랑 직접 입력하면서 이해할 때의 느낌이 사뭇 다르더라구요.
어른들(?)이 공부는 종이에 팬으로 써가면서 해야 한다고 말씀하시곤 했는데, 그거랑 비슷한 것 같기도 해요. 저는 공부는 키보드로 쳐가면서 해야 잘 되는 것 같아요.
아무튼, 빈 디렉터리를 만들고 manifest.json
을 만들었습니다.
{
"name": "Getting Started Example",
"description": "Build an Extension!",
"version": "1.0",
"manifest_version": 3
}
이제 크롬 주소창에 chrome://extensions
라고 입력해서 확장 기능 화면으로 이동합니다.
우측 상단의 “Developer Mode” 옵션을 켰더니 “Load Unpacked”라는 버튼이 생겼습니다. 로컬
디렉터리에서 익스텐션을 읽어오는 기능입니다.
manifest.json
이 있는 디렉터리를 선택했더니 바로 익스텐션이 등록됐습니다. 이후의 작업 흐름은
이렇습니다.
- 소스를 수정하고 저장
- 확장 기능의 새로고침 아이콘을 클릭
- 잘 작동하는지 확인
소스를 저장하기만 하면 ‘Hot Module Replacement’가 되는 요즘의 웹 개발 환경에 비해 좀 번거롭지만 견딜만한 수준인 것 같습니다. 더 짧은 피드백을 원한다면 익스텐션도 테스트 주도 개발을 하면 될테구요.
불필요한 내용 건너뛰기
튜토리얼의 다음 단계는 서비스워커를 등록하는 내용인데, 제가 지금 하려는 업무랑 상관이 없습니다. 그래서 그냥 건너뛰기로 했습니다.
구체적인 목표와 맥락이 있는 상황에서 공부를 하는 게 좋은 이유 중 하나라고 생각합니다. 수동적으로 시키는대로 따라하는 게 아니라 지금 읽으려고 하는 내용이 내 맥락에 도움이 되는지 여부를 능동적으로 그리고 구체적으로 따져가며 읽을 수 있으니까요.
그 다음 내용은 스토리지에 무언가를 저장하는 내용, 관련 권한을 설정하는 내용, 유저 인터페이스 만들기, 아이콘 바꾸기 등의 내용인데 역시나 다 건나뛰었습니다.
그랬더니 “Getting started” 문서가 끝나버렸어요.
필요한 내용 찾아 읽기
“Getting started” 제일 앞 부분에서 ‘content script’라는 걸 쓰면 페이지 DOM을 읽고 쓸 수 있다는 내용이 있었습니다. 그래서 공식 문서에서 해당 내용을 찾았습니다.
문서 제일 앞에 이런 말이 나옵니다.
Content scripts are files that run in the context of web pages. By using the standard Document Object Model (DOM), they are able to read details of the web pages the browser visits, make changes to them, and pass information to their parent extension.
딱 저에게 필요한 내용입니다.
manifest.json
에 아래 내용을 추가하면 된다고 합니다.
{
"content_scripts": [
"matches": ["https://*.blah.com/*"],
"js": ["content-script.js"]
]
}
사용자가 matches
에 명시된 패턴에 일치하는 웹페이지에 방문하면 content-script.js
의
내용을 실행한다고 합니다.
아기 걸음
처음 하는 일이고 자신이 없을수록 피드백을 자주 받으면 좋습니다. 피드백을 자주 받으면서 좁은 보폭으로 진행하는 걸 켄트 벡Kent Beck은 “아기 걸음baby steps”이라고 표현하더라구요.
저도 아기 걸음을 걷기로 했습니다. content-script.js
파일을 만들고 이 스크립트가 실제로
실행되는지 확인을 하기 위한 최소한의 코드를 작성했습니다.
console.log('Hello from content-script.js')
저장하고 확장기능을 새로고침한 다음에 개발자 콘솔을 열고 페이지에 접속했더니 로그가 잘 찍혔습니다. 첫 단계는 성공.
다음에는 이 스크립트가 페이지의 DOM을 잘 읽어오는지 확인을 해야 합니다. 가장 간단한 방법은?
const title = document.title
console.log(`The title is: ${title}`)
저장하고 확장기능을 새로고침한 다음에 다시 콘솔을 확인했는데, 역시나 잘 됐습니다. 두번째 단계도 성공.
마지막으로, 이 스크립트가 페이지의 DOM을 변경할 수도 있는지 확인을 하면 됩니다. 역시나 가장 간단한 방법은?
document.title = 'Hello from content-script.js'
저장하고 확장기능을 새로고침한 다음에 페이지에 방문했더니 제목이 원하는대로 바뀌는 것을 확인할 수 있었습니다. 성공.
TDD를 하지 않는 환경에서도 TDD를 하는 것과 거의 유사하게 작업을 할 수 있었습니다. 각 단계가 아주 작고 간단하기 때문에 의외의 결과가 나오더라도 더 쉽게 대응을 할 수 있어서 좋습니다.
마무리
공부가 끝났습니다. 이제 크롬 확장 기능으로 원하는 걸 만드는 방법을 다 알았습니다. 그 다음 할 일은 무엇일까요?
많은 사람들이 ‘일이 일단 되기만 하면’ 불편하더라도 그냥 그 상황에서 일을 하고는 합니다. 그치만 ‘일이 일단 되면’ 그 다음에는 그 일을 편하게 잘 할 수 있는 환경을 만드는 단계를 꼭 거치면 좋습니다.
앞으로 지금보다 큰 보폭으로 진도를 뽑아야할텐데 매번 저장하고 확장기능을 새로고침하고 페이지를 다시 열어보기를 반복할 수는 없으니까요.
이 이야기는 다음에 이어서 쓰도록 하겠습니다.