매주 깃허브 이슈를 복사해서 일정한 형식으로 붙여넣는 노가다 작업을 하게 되었다. 이슈가 5개를 넘어갈 때 즈음.. 왜 이걸 내가 직접 하고 있지? 라는 생각이 들었다.
개발 기간: 2일
하는 일은 간단하다.
1. 사용자는 깃허브 issue 페이지에 들어가서 익스텐션을 켠다.
2. 그 페이지에 있는 이슈를 긁어서
3. 일정한 포맷으로 만들어 보여준다.
이제 이슈 개수 * 2 (이슈 링크와 이름)
번 복붙하던걸 1번만 복붙해도 된다.
크롬 익스텐션의 구성. 자세한 설명은 구글 크롬 익스텐션 공식 문서에 잘 나와있다.
요구사항을 다시 살펴보자.
그런데 크롬 익스텐션 컴포넌트 중 DOM에 접근할 수 있는건 content-script뿐이다. 즉, content-script에서 긁어온 내용을 잘 가공해서 popup 으로 보내야 한다. 그래서 어떻게 통신하는지 찾아봤는데 잘 안 나와서 아래에 정리했다.
background.js
는 익스텐션이 켜져있는 동안 계속 살아있기 때문에 이곳에 글로벌 변수를 관리하기로 했다.A background page is loaded when it is needed, and unloaded when it goes idle. Some examples of events include:
- The extension is first installed or updated to a new version.
- The background page was listening for an event, and the event is dispatched.
- A content script or other extension sends a message.
Another view in the extension, such as a popup, calls runtime.getBackgroundPage.
(https://developer.chrome.com/docs/extensions/mv2/background_pages/)
// 보내는 쪽
chrome.runtime.sendMessage("message");
// 받는 쪽
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
console.log(message);
});
// content-script.js
chrome.runtime.sendMessage({ "key": "value" });
// background.js
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
console.log(message);
});
// inject-script.js
window.postMessage({ "key": "value" });
// content-script.js
window.addEventListener("message", function (event) {
const valueFromInjectScript = event.data.key;
// popup.js
const background = chrome.extension.getBackgroundPage();
// 이후 이 변수를 통해 backround에 정의된 값을 가져올 수 있음.
const valueInBackground = background.valueName;
타입스크립트로 개발했다면 이를 JS로 바꿔주는 작업이 필요하다. 그래도 이걸 해주는 보일러플레이트 코드가 많이 돌아다니고 있으니 활용하면 될 것 같다. 내가 만들 익스텐션은 그렇게 복잡하지 않아서 그냥 바닐라 JS로 개발했다.
크롬 익스텐션에서 클립보드 복사 기능을 구현하려면 이벤트 핸들러를 등록해야 한다. popup.html
에서 바로 onclick 프로퍼티를 설정해주는게 안된다. 보안 정책 때문에 스크립트를 실행할 수 없다는 에러가 뜬다. 이것 때문에 마지막에 많이 헤맸다. 😇
<button onclick="() => navigator.clipboard.writeText(text)">복사하기</button>
<button id="copy-button">복사하기</button>
const copyToClipboard = (text) => {
navigator.clipboard.writeText(text);
}
const copyButton = document.getElementById('copy-button');
copyButton.addEventHandler("click", copyToClipboard);