크롬 익스텐션은 사용자가 원하는 기능을 추가로 설치하여 웹을 더욱 편하게 이용하게 해주는 프로그램입니다.
이번에 프로젝트로 크롬익스텐션을 만들게 되었는데 이에 대해 튜토리얼 및 자료들을 보면서 한국어로된 버전도 있으면 좋을것 같아 정리하게 되었습니다.
크롬 익스텐션은 다음과 같은 구성 요소로 이루어집니다.
모든 크롬 익스텐션은 중요한 정보를 제공하는 manifest.json
이라는 JSON
형식의 파일을 가지고 있습니다.
이
json
파일에 많은 속성들을 넣을 수 있는데 이 부분은 튜토리얼을 진행하면서 같이 보겠습니다.
기본적인 manifest.json
예시
{
"name": "My Extension",
"description": "A nice little demo extension.",
"version": "2.1",
"manifest_version": 3,
}
백그라운드 스크립트는 익스텐션의 이벤트 핸들러이며 익스텐션에 중요한 브라우저 이벤트들의 리스너들을 포함합니다. 백그라운드에서 계속 돌아가면서 이벤트가 발생하면 지시된 논리를 수행합니다.
여기서 말하는 이벤트는 새 페이지로 이동, 책갈피 제거 또는 탭 닫기와 같은 브라우저 트리거를 말합니다.
백그라운드 스크립트를 등록하기 위해서는 manifest
에 다음과 같은 설정을 해주어야 합니다.
{
"name": "My Extension",
"description": "A nice little demo extension.",
"version": "2.1",
"manifest_version": 3,
"background": {
"service_worker": "background.js"
},
}
익스텐션의 유저 인테페이스 부분을 담당합니다. 튜토리얼이나 아키텍처에서는 popup.html
을 말하며 이 팝업 페이지에서 tabs.create
혹은 window.open()
을 호출하여 다른 페이지를 띄울수도 있습니다.
일반적으로 기본적인 팝업 설정은 manifest
에서 다음과 같이 작성합니다.
{
"name": "Getting Started Example",
"description": "Build an Extension!",
"version": "1.0",
"manifest_version": 3,
"background": {
"service_worker": "background.js"
},
"action": {
"default_popup": "popup.html",
},
}
웹 페이지를 읽거나 쓰는 확장 기능은 컨텐츠 스크립트를 사용합니다. 이 스크립트는 브라우저가 방문하는 웹 페이지의 DOM읽고 수정합니다.
컨텐츠 스크립트는 메시지를 교환하고 스토리지 API를 사용하여 값을 저장함으로써 상위 확장과 통신할 수 있습니다.
익스텐션을 통해 크롬 브라우저를 커스터마이징 하는 것처럼 옵션 페이지도 익스텐션을 커스터마이징하게 만들어줍니다. 옵션을 사용하여 기능을 활성화하고 사용자가 원하는 기능들을 선택할 수 있게 만들어줍니다.
manifest
에 다음과 같이 설정합니다.
{
...
"options_page": "options.html"
}
여기까지가 크롬 익스텐션의 아키텍처이며 아래는 튜토리얼 내용과 React 프로젝트에서 어떤식으로 크롬 익스텐션을 만드는지에 대한 내용입니다.
크롬 익스텐션을 개발할 때, 크롬 API를 알면 더욱 효과적이고 브라우저와의 긴밀한 통합을 만들 수 있습니다.
참고사이트: API Reference
이 튜토리얼에서는 간단한 HTML/CSS를 활용하여 크롬 익스텐션의 버튼을 누르면 그 색으로 화면의 배경색이 변하는 앱을 만들어봅니다.
우선 작업할 공간에 manifest.json
파일을 만들어줍니다.
{
"name": "Getting Started Example",
"description": "Build an Extension!",
"version": "1.0",
"manifest_version": 3
}
이후 크롬 브라우저의 확장 프로그램 관리에 들어가서 다음과 같이 누르면
현재 만들어진 확장 프로그램 등록이 가능합니다.
현재는 아무 기능이 없기 때문에 기능을 추가해 봅시다.
{
"name": "Getting Started Example",
"description": "Build an Extension!",
"version": "1.0",
"manifest_version": 3,
"background": {
"service_worker": "background.js"
}
}
백그라운드 스크립트를 등록하고, background.js
라는 파일을 만들어 다음과 같이 작성해봅시다.
let color = '#3aa757';
chrome.runtime.onInstalled.addListener(() => {
chrome.storage.sync.set({ color });
console.log('Default background color set to %cgreen', `color: ${color}`);
});
안의
onInstalled
는 확장을 처음 설치할 때, 새 버전으로 업데이트할 때, Chrome을 새 버전으로 업데이트할 때 실행됩니다.
또한 storage API를 사용하는데, 이는 LocalStorage API와 동일한 스토리지 기능을 제공하지만 약간의 차이점이 존재합니다.
차이점은 간단한게 아래와 같고 더 알고싶다면 아래의 링크를 참고해주세요
링크: chrome.storage
스토리지 API를 포함한 대부분의 API는 manifest
의 권한 필드에 등록되어있어야 사용 가능합니다.
{
...
"permissions": ["storage"]
}
이후, reload를 한 뒤, 서비스 워커를 클릭하여 콘솔창을 보면 백그라운드 스크립트가 잘 작동되었다는 다음과 같은 화면을 볼 수 있습니다.
이제 익스텐션을 누르면 보일 인터페이스를 만들 차례입니다.
작업 폴더 아래에 popup.html
을 만들고 다음과 같이 만들어봅시다.
popup.html
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="button.css">
</head>
<body>
<button id="changeColor"></button>
</body>
</html>
button.css
button {
height: 30px;
width: 30px;
outline: none;
margin: 10px;
border: none;
border-radius: 2px;
}
button.current {
box-shadow: 0 0 0 2px white, 0 0 0 4px black;
}
이후
manifest
에 추가를 해주어야 팝업창에 표시할 수 있는데, 그 전에 이미지 추가를 위해 아래 링크에서 이미지들을 다운 받고 작업환경에images
라는 폴더를 추가해줍시다. 그 이후 manifest에 아이콘 등록도 해주면 됩니다.
manifest.json
{
"name": "Getting Started Example",
"description": "Build an Extension!",
"version": "1.0",
"manifest_version": 3,
"background": {
"service_worker": "background.js"
},
"permissions": ["storage"],
"action": {
"default_popup": "popup.html",
"default_icon": {
"16": "/images/get_started16.png",
"32": "/images/get_started32.png",
"48": "/images/get_started48.png",
"128": "/images/get_started128.png"
}
},
"icons": {
"16": "/images/get_started16.png",
"32": "/images/get_started32.png",
"48": "/images/get_started48.png",
"128": "/images/get_started128.png"
}
}
여기서
default_icon
은 도구모음 아이콘의 지정을 위한 것이며icons
는 확장 관리 페이지, 권한 경고 및 즐겨찾기 아이콘에도 이미지를 표시하기위해 적용한 것입니다.
이후 크롬 익스텐션을 고정시키고 보면 다음과 같은 화면을 확인할 수 있습니다.
위 버튼에 아까 백그라운드 스크립트에 저장해둔 색을 사용하려면 popup.js
를 만들어 다음의 코드를 추가하면 됩니다
popup.js
let changeColor = document.getElementById('changeColor');
chrome.storage.sync.get('color', ({ color }) => {
changeColor.style.backgroundColor = color;
});
이후 popup.html
에도 추가해줍시다.
popup.html
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="button.css">
</head>
<body>
<button id="changeColor"></button>
<script src="popup.js"></script>
</body>
</html>
이제 확장자의 버튼을 눌렀을 때, 그 색으로 화면의 색을 변경하기 위한
popup.js
코드를 업데이트 시켜주어야합니다.
popup.js
// 버튼을 클릭했을때, 현재 페이지에 설정된 배경색으로 바꿉니다.
changeColor.addEventListener("click", async () => {
let [tab] = await chrome.tabs.query({ active: true, currentWindow: true });
chrome.scripting.executeScript({
target: { tabId: tab.id },
function: setPageBackgroundColor,
});
});
// 이 함수의 본문은 컨텐츠 스크립트로 실행됩니다.
// 현재 페이지
function setPageBackgroundColor() {
chrome.storage.sync.get("color", ({ color }) => {
document.body.style.backgroundColor = color;
});
}
chrome.tabs.query
는Tab[]
이라는 프로미스를 반환하며 지정된 속성이 있는 모든 탭을 가져오거나, 속성이 지정되지 않은 경우 모든 탭을 가져옵니다.active
는 창이 활성화 되어있는지,currentWindow
는 탭이 현재 창에 있는지를 물어보는 속성입니다.
chrome.scripting
은 아래와 같은 형식으로 사용합니다.
이후 manifest
에 현재 페이지에 대한 익스텐션 임시 액세스를 허용하는 activeTab
사용 권한과 스크립팅 API의 executeScript
메서드를 사용하는 스크립팅 권한이 필요합니다.
manifest.json
{
...
"permissions": ["storage", "activeTab", "scripting"],
}
이후 크롬 익스텐션을 눌러보면
다음과 같이 완성된 모습을 볼 수 있습니다.
현재 익스텐션은 녹색으로만 변경할 수 있는데, 사용자가 익스텐션 기능을 더 많이 제어하도록 옵션을 줄 수 있습니다. 이를 위한 작업을 진행해 봅시다.
작업 폴더안에 options.html
파일을 만듭니다.
options.html
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="button.css">
</head>
<body>
<div id="buttonDiv">
</div>
<div>
<p>Choose a different background color!</p>
</div>
</body>
<script src="options.js"></script>
</html>
이후 manifest
에 options_page
를 등록합니다.
{
"name": "Getting Started Example",
...
"options_page": "options.html"
}
익스텐션을 리로드한 뒤 익스텐션에 우클릭을 하면 다음과 같은 화면을 볼 수 있습니다.
마지막은 options.js
를 만들어 로직을 추가하는 것입니다.
options.js
let page = document.getElementById("buttonDiv");
let selectedClassName = "current";
const presetButtonColors = ["#3aa757", "#e8453c", "#f9bb2d", "#4688f1"];
// 버튼 클릭에 반응하여 선택된 버튼을 마킹하고 저장합니다.
// 선택
function handleButtonClick(event) {
// 전에 선택된 색상 버튼의 스타일링을 제거합니다.
let current = event.target.parentElement.querySelector(
`.${selectedClassName}`
);
if (current && current !== event.target) {
current.classList.remove(selectedClassName);
}
// 선택한 버튼을 마킹합니다.
let color = event.target.dataset.color;
event.target.classList.add(selectedClassName);
chrome.storage.sync.set({ color });
}
// 제공된 각 색상에 대해 페이지에 버튼을 추가합니다.
function constructOptions(buttonColors) {
chrome.storage.sync.get("color", (data) => {
let currentColor = data.color;
for (let buttonColor of buttonColors) {
let button = document.createElement("button");
button.dataset.color = buttonColor;
button.style.backgroundColor = buttonColor;
if (buttonColor === currentColor) {
button.classList.add(selectedClassName);
}
button.addEventListener("click", handleButtonClick);
page.appendChild(button);
}
});
}
// 색상 옵션을 구성하여 페이지 초기화
constructOptions(presetButtonColors);
이후 옵션에 들어가면 색상을 선택할 수 있습니다.
전체 코드는 여기서 확인할 수 있습니다.
https://github.com/hustle-dev/Frontend-Skill/tree/main/chrome-extension-example