Chrome 확장 프로그램 : 코드 재사용(4)
본문
이 시리즈가 처음이고 이전 게시물을 읽고 싶지 않다면 다음과 같은 간단한 요약을 참조하십시오.
- 나는 모든 포스트에서 업데이트하고 개선 한 매우 간단한 크롬 확장 프로그램을 만드는 이 시리즈를 시작했습니다.
- 우리가 작업하고 있는 크롬 확장 프로그램은 "Acho, 우리는 어디에 있습니까?"라고 합니다.
- Acho는 내 강아지 🐶의 이름이며,이 확장에서 그는 짖고 현재 탐색 중인 페이지의 제목을 알려줍니다.
-, 브라우저 작업을 통해 (Chrome의 탐색 모음 오른쪽에 나타나는 팝업)
-, 또는 화면 오른쪽 하단에 알림을 표시하는 키보드 단축키를 사용합니다.
소개
지금까지 확장 기능에는 다음과 같은 기능이 있습니다.
- 활성 탭의 제목과 함께 브라우저 작업 (팝업)을 표시합니다.
- 현재 탭을 복제하는 명령
- 활성 탭 제목과 함께 화면 오른쪽 하단에 알림을 표시하는 명령입니다.
다음은 이러한 기능의 논리를 관리하기 위해 구축 한 구성 요소입니다.
"활성 탭 가져 오기"및 "탭 제목 표시"기능은 여러 구성 요소에서 사용되지만 현재는 해당 논리가 각 구성 요소 내부에 복제됩니다. 상상 하셨겠지만, 우리는 그 논리를 한 번만 작성하고 프로젝트 전체에서 공유 할 방법을 찾아야 합니다.
ℹ️ 재사용성 정보 : 코드를 재사용 하면 시간을 절약하고 프로젝트의 중복성을 줄일 수 있습니다. 동일한 코드를 여러 번 작성하는 것을 피함으로써 코드가 더 깨끗해지고 공유 논리에 대한 업데이트가 한 곳에서 수행 될 수 있기 때문에 프로젝트를 더 쉽게 유지 관리 할 수 있습니다.
따라서 더 나은 버전의 앱은 다음과 같습니다.
이 버전에서 컴포넌트는 특정 로직에 대해서만 책임이 있으며 공유 로직은 acho.js 파일에서 분리되어 쉽게 유지 및 공유 할 수 있습니다. 중복 된 논리도 없습니다.
샘플 크롬 확장에서 이를 달성하는 방법을 살펴 보겠습니다.
공유 논리를 별도의 파일로 중앙 집중화
우선, 우리는 재사용 가능한 로직이 별도의 파일에 집중되어야 합니다. 그래서 우리는 acho.js라는 새 파일을 만들 것입니다. 여기에서 Acho라는 클래스를 만들고 나중에 각 구성 요소에서 호출 할 메서드를 추가합니다.
실제 예에서는 공유 논리에 대해 둘 이상의 파일을 사용할 수 있습니다. 예제를 단순하게 유지하기 위해 하나만 사용합니다.
acho.js 파일은 다음과 같습니다.
/** Shared logic */
class Acho {
/**
* Gets the active Tab
* @returns {Promise<*>} Active tab
*/
getActiveTab = async () => {
const query = { active: true, currentWindow: true };
const getTabTitlePromise = new Promise((resolve, reject) => {
chrome.tabs.query(query, (tabs) => {
resolve(tabs[0]);
});
});
return getTabTitlePromise;
}
/**
* Concatenates the tab title with Acho's barks.
* @param {String} tabTitle Current tab title
* @returns {String}
*/
getBarkedTitle = (tabTitle) => {
const barkTitle = `${this.getRandomBark()} Ahem.. I mean, we are at:
${tabTitle}`
return barkTitle;
}
/**
* Array of available bark sounds
* @private
* @returns {String[]}
*/
getBarks = () => {
return [
'Barf barf!',
'Birf birf!',
'Woof woof!',
'Arf arf!',
'Yip yip!',
'Biiiirf!'
];
}
/**
* Returns a random bark from the list of possible barks.
* @private
* @returns {String}
*/
getRandomBark = () => {
const barks = this.getBarks();
const bark = barks[Math.floor(Math.random() * barks.length)];
return bark;
}
}
두 가지 공개 방법이 있습니다.
- getActiveTab은 활성 탭을 반환합니다.
- getBarkedTitle은 임의의 짖는 소리와 탭 제목이 연결된 문자열을 생성합니다. 브라우저 작업 (팝업)과 알림 모두에서 사용합니다.
그런 다음 공개 메소드의 논리를 단순화하기 위한 몇 가지 비공개 메소드가 있습니다.
재사용 가능한 코드에 액세스
큰. 이제 재사용 가능한 로직을 많은 구성 요소에서 사용할 준비가 되었지만 그게 다가 아닙니다. 각 구성 요소에서 이 논리에 액세스하는 방법을 알아 내야 합니다.
- 백그라운드 스크립트 (background.js)
- 콘텐츠 스크립트 (content.js)
- 브라우저 작업 스크립트 (popup.js)
이 문제에 접근하려면 이러한 모든 구성 요소가 동일한 확장의 일부이지만 다른 컨텍스트에서 실행된다는 점을 기억하는 것이 중요합니다.
- popup.js는 브라우저 액션의 컨텍스트에서 실행됩니다.
- 콘텐츠 스크립트는 웹 페이지의 컨텍스트에서 실행됩니다.
- 백그라운드 스크립트는 브라우저에 의해 트리거 된 이벤트를 처리하며 필요할 때만 로드됩니다. 현재 웹 페이지 및 브라우저 작업과 독립적으로 작동합니다.
그렇다면 이러한 다양한 컨텍스트에서 재사용 가능한 코드를 어떻게 사용할 수 있습니까?
브라우저 액션에서
이것은 우리가 구현할 솔루션이 정적 HTML + JS 웹 사이트에서 수행하는 작업이기 때문에 익숙 할 것입니다. 브라우저 작업 HTML 파일 (popup.html)에 스크립트로 acho.js 파일을 추가 할 것입니다. ) <script> 태그 사용 :
popup.html 파일을 열고 <body> 태그의 맨 아래에 다음과 같이 스크립트를 추가하십시오.
<body>
<!-- the rest of the body -->
<script src='popup.js'></script>
<script src='acho.js'></script> <!-- 👈 -->
</body>
끝난! 이제 popup.js의 Acho 클래스를 사용할 수 있으며 코드가 크게 줄어들 것입니다.
document.addEventListener('DOMContentLoaded', async () => {
const dialogBox = document.getElementById('dialog-box');
const query = { active: true, currentWindow: true };
const acho = new Acho(); // 👈
const tab = await acho.getActiveTab();
const bark = acho.getBarkedTitle(tab.title);
dialogBox.innerHTML = bark;
});
콘텐츠 스크립트에서
여기에 있는 해결책은 명확하지 않을 수 있지만 매우 간단합니다. manifest.json 파일의 현재 콘텐츠 스크립트 객체 내에서 js 배열에 acho.js를 추가하기 만하면 됩니다.
{
"manifest_version": 2,
"name": "Acho, where are we?",
...
"content_scripts": [
{
"matches": ["<all_urls>"],
"js": ["content.js", "acho.js"], // 👈
"css": ["content.css"]
}
],
}
이제 content.js의 Acho 클래스를 인스턴스화하고 사용하여 "barked title"문자열을 생성 할 수 있습니다.
// Notification body.
const notification = document.createElement("div");
notification.className = 'acho-notification';
// Notification icon.
const icon = document.createElement('img');
icon.src = chrome.runtime.getURL("images/icon32.png");
notification.appendChild(icon);
// Notification text.
const notificationText = document.createElement('p');
notification.appendChild(notificationText);
// Add to current page.
document.body.appendChild(notification);
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
const notification = document.getElementsByClassName('acho-notification')[0];
const notificationText = notification.getElementsByTagName('p')[0];
// 👇👇👇
const acho = new Acho();
notificationText.innerHTML = acho.getBarkedTitle(request.tabTitle);
notification.style.display = 'flex';
setTimeout(function () {
notification.style.display = 'none';
}, 5000);
return true;
});
백그라운드 스크립트에서
솔루션은 비슷합니다. manifest.json에있는 배경 객체의 스크립트 배열에 acho.js를 추가해야 합니다.
{
"manifest_version": 2,
"name": "Acho, where are we?",
...
"background": {
"scripts": [ "background.js", "acho.js" ], // 👈
"persistent": false
}
}
마찬가지로 이제 background.js에서 Acho 클래스에 액세스 할 수 있습니다.
chrome.commands.onCommand.addListener(async (command) => {
switch (command) {
case 'duplicate-tab':
await duplicateTab();
break;
case 'bark':
await barkTitle();
break;
default:
console.log(`Command ${command} not found`);
}
});
/**
* Gets the current active tab URL and opens a new tab with the same URL.
*/
const duplicateTab = async () => {
const acho = new Acho(); // 👈
const tab = await acho.getActiveTab();
chrome.tabs.create({ url: tab.url, active: false });
}
/**
* Sends message to the content script with the currently active tab title.
*/
const barkTitle = async () => {
const acho = new Acho(); // 👈
const tab = await acho.getActiveTab();
chrome.tabs.sendMessage(tab.id, {
tabTitle: tab.title
});
}
acho.getActiveTab()의 약속을 기다릴 수 있도록 함수를 비 동기화 해야 했습니다. 원하는 경우 대신 acho.getActiveTab(). then ((tab) => {})을 사용할 수 있습니다.
그게 다야! 이제 모든 컴포넌트가 acho.js의 로직을 재사용하고 있습니다.
결론
공유 논리를 포함하는 별도의 파일을 만들고 다른 전략을 사용하여 모든 구성 요소에서 해당 파일을 사용할 수 있도록 함으로써 중복 된 코드를 제거하고 재사용 성을 적용 할 수 있었습니다.
이제 확장 프로그램의 코드를 읽고 유지하기가 더 쉽습니다 👌
저장소
이 저장소에서 내 모든 Chrome 확장 프로그램 예제를 찾을 수 있습니다.
https://dev.to/paulasantamaria/chrome-extensions-reusing-code-3f1g
- 이전글2021 년에 ExpressJS를 중단해야 하는 이유 21.02.20
- 다음글Chrome 확장 프로그램 : 웹 페이지 변경(3) 21.02.19