raw
Development

크롬확장프로그램 만들기 - 가이드라인! 확장프로그램 구조 설명 !

2024.08.28·8분

크롬 확장프로그램 개발


어느 날 잘쓰고 있던 학교 선배님이 만든 LMS(학습 관리 시스템)기능 확장프로그램이 학교 사이트 개편으로 인해 더 이상 쓸 수가 없어져서..내가 만들어야겠다고 생각했다..

구조

구조를 보면 간단하다. HTML+CSS+JavaScript 를 사용해서 충분히 만들 수 있다.

  • contentscript.js 사용자가 방문하는 영역에서 작동하는 스크립트 페이지의 현재 상태에 대한 정보를 전달한다. 현재 페이지의 DOM을 읽어와서 조작이 가능하다.

  • background.js 브라우저 영역에서 작동하는 스크립트 플러그인의 이벤트 핸들러 중요한 모든 이벤트 리스너가 여기 저장된다. 이벤트가 트리거 되고, 할당된 로직을 실행할 때까지 inactive 상태로 유지된다.

  • popup.js 시각적인 기능을 담당한다. HTML과 직접 상호작용하고, background 스크립트와 함께 API를 호출 popup.html이 index.html과 같은 의미이다.

크롬 설정을 누르면 확장 프로그램에 대해서 확인할 수 있다.

확장 프로그램 관리와 Chrome 웹 스토어 방문하기가 있는데 생각보다 크롬 확장프로그램을 사용을 안하는 사람이 많다.

개발자라면 도움이 되는 확장 프로그램이 많다!! CSS viewer 라던가.. Json Viewer라던가.. 코테문제를 풀면 자동으로 깃허브에 저장된다던가..!

파일을 드래고 하거단 로드를 할 수 있는데 기본적으로

menifest 파일이 존재해야한다!!!!

Manifest 파일의 핵심 역할

Chrome 확장 프로그램의 manifest 파일(manifest.json)은 확장 프로그램의 DNA다. 이 파일은 다음과 같은 중요한 기능을 한다:

text
1> - 확장 프로그램 신원 확립:
2>name, version, description 필드에 기본 정보가 들어간다.
3이 정보로 사용자와 Chrome 웹 스토어가 프로그램을 식별한다.
4
5
6- 권한 선언:
7>permissions 배열에 필요한 권한이 나열된다.
8이는 사용자의 프라이버시와 보안을 지킨다.
9
10
11- 리소스 정의:
12>icons, action 등에 시각적 요소의 위치가 지정된다.
13사용자 인터페이스 관련 파일들의 경로가 여기에 있다.
14
15
16- 백그라운드 로직 설정:
17>background 섹션에 서비스 워커나 백그라운드 페이지가 정의된다.
18확장 프로그램의 '두뇌' 역할을 하는 스크립트가 여기에 지정된다.
19
20
21- 콘텐츠 스크립트 선언:
22>content_scripts 섹션에 웹 페이지에 삽입될 스크립트가 정의된다.
23이를 통해 확장 프로그램이 웹 페이지와 상호작용한다.
24
25
26- 보안 정책 설정:
27>content_security_policy에 확장 프로그램의 보안 정책이 정의된다.
28XSS 공격 등으로부터 확장 프로그램을 보호한다.
29
30
31- API 버전 명시:
32>manifest_version에 사용하는 manifest 파일의 버전이 지정된다.
33이에 따라 Chrome이 확장 프로그램을 해석하고 실행한다.
34
35
36- 웹 접근 범위 정의:
37>host_permissions에 접근 가능한 웹 사이트가 지정된다.
38사용자의 동의 하에 특정 도메인에 대한 접근 권한이 부여된다.
39
40
41- 국제화 지원:
42>default_locale과 관련 리소스 파일로 다국어를 지원한다.
43이를 통해 전 세계 사용자를 위한 현지화가 가능하다.
44
45
46- 웹 접근성 기능:
47>commands 섹션에 키보드 단축키가 정의된다.
48이로써 사용자 경험이 향상되고 접근성이 개선된다.

천천히 읽어보면 좋다 !

menifest작성이 끝났다면 popup,contentscript,background를 작성하면 간단한 확장프로그램은 만들 수 있다.

배경색을 바꾸는 확장프로그램을 만들어 보자 !!

text
1// manifest.json
2{
3 "name": "Simple Change Color",
4 "description": "현재 탭의 배경색을 변경하고 텍스트를 추가하는 간단한 MV3 확장 프로그램",
5 "version": "1.0.0",
6 "manifest_version": 3,
7 "permissions": [
8 "activeTab",
9 "scripting"
10 ],
11 "host_permissions": [
12 "<all_urls>"
13 ],
14 "action": {
15 "default_popup": "popup.html"
16 },
17 "content_scripts": [
18 {
19 "matches": [
20 "<all_urls>"
21 ],
22 "js": [
23 "contentScript.js"
24 ],
25 "run_at": "document_idle"
26 }
27 ]
28}
29
30// popup.html
31<!DOCTYPE html>
32<html>
33
34<head>
35 <title>Change background Color</title>
36</head>
37
38
39<body>
40 <button id="changeColor">background Color change</button>
41 <button id="addText">text add</button>
42 <script src="popup.js"></script>
43</body>
44
45</html>
46
47// popup.js
48document.getElementById('changeColor').addEventListener('click', async () => {
49 let [tab] = await chrome.tabs.query({ active: true, currentWindow: true });
50 if (chrome.runtime.lastError) {
51 console.error(chrome.runtime.lastError);
52 return;
53 }
54 if (tab && !tab.url.startsWith("chrome://")) {
55 try {
56 await chrome.scripting.executeScript({
57 target: { tabId: tab.id },
58 function: setPageBackgroundColor,
59 });
60 console.log("Script executed successfully");
61 } catch (error) {
62 console.error("Error executing script:", error);
63 }
64 } else {
65 console.error("Cannot execute script on this page");
66 }
67});
68
69function setPageBackgroundColor() {
70 document.body.style.backgroundColor = `rgb(${Math.random() * 255}, ${Math.random() * 255}, ${Math.random() * 255})`;
71}
72
73document.getElementById('addText').addEventListener('click', async () => {
74 let [tab] = await chrome.tabs.query({ active: true, currentWindow: true });
75 if (chrome.runtime.lastError) {
76 console.error(chrome.runtime.lastError);
77 return;
78 }
79 if (tab && !tab.url.startsWith("chrome://")) {
80 try {
81 const response = await chrome.tabs.sendMessage(tab.id, {action: "addText"});
82 console.log("Message sent successfully", response);
83 } catch (error) {
84 console.error("Error sending message:", error);
85 // Content Script가 로드되지 않았을 수 있으므로, 스크립트를 주입하고 다시 시도합니다.
86 try {
87 await chrome.scripting.executeScript({
88 target: { tabId: tab.id },
89 files: ["contentScript.js"]
90 });
91 const response = await chrome.tabs.sendMessage(tab.id, {action: "addText"});
92 console.log("Message sent successfully after injecting content script", response);
93 } catch (injectError) {
94 console.error("Error injecting and executing content script:", injectError);
95 }
96 }
97 } else {
98 console.error("Cannot send message to this page");
99 }
100});
101
102// background.js
103chrome.runtime.onInstalled.addListener(() => {
104 console.log('배경색 변경기가 설치되었습니다.');
105});
106
107// contentScript.js
108chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
109 if (request.action === "addText") {
110 const newElement = document.createElement('div');
111 newElement.textContent = '이 텍스트는 확장 프로그램에 의해 추가되었습니다!';
112 newElement.style.position = 'fixed';
113 newElement.style.top = '10px';
114 newElement.style.right = '10px';
115 newElement.style.backgroundColor = 'yellow';
116 newElement.style.padding = '10px';
117 newElement.style.zIndex = '9999';
118 document.body.appendChild(newElement);
119 sendResponse({status: "Text added successfully"});
120 }
121 return true; // 비동기 응답을 위해 필요합니다.
122});

파일은 위 주석에 나와있는 것처럼 나눠야 한다.

이렇게 파일이 만들어지면 위에서 확장프로그램 개발자모드를 체크! 하고 파일을 로드하면 된다.

이런식으로 작동이 잘 되는걸 볼 수 있다. !!