web/etc

크롬 익스텐션 Overview 번역

qkqhxla1 2017. 2. 20. 22:03

https://developer.chrome.com/extensions/overview 번역


개요.


https://developer.chrome.com/extensions/getstarted를 본후에는 익스텐션을 개발할 준비는 끝났다. 


기초.

크롬 익스텐션은 크롬에 기능들을 추가할 수 있는 압축된 html,css,javascript,image 등등의 파일들의 집합이다. 익스텐션은 본질적으로 웹 페이지이며, 브라우저가 웹 페이지에 제공하는 XMLHttpRequest부터 html5를 위한 JSON까지 api들을 사용할수 있다.


익스텐션은 다른 웹 페이지나 서버와 content scriptcross-origin XMLHttpRequests를 사용해서 통신할 수 있다. 또한 bookmarkstabs같은 브라우저의 일부를 프로그래밍적으로 활용할 수 있다.


익스텐션의 ui들.


크롬 앱이 아닌 많은 익스텐션이 browser actionspage actions의 형태로 크롬에 ui를 집어넣는다. 하나하나의 익스텐션은 최대 하나의 browser action 또는 page action을 가질 수 있다.

익스텐션이 대부분의 페이지들과 관계가 있을 때는 browser action을 선택하고, 페이지에 따라서 동작/비동작이 되어야 한다면 page action을 선택하자.


 


 


 


 구글 메일 체커 익스텐션은 브라우저 액션을 사용한다.

 이 위치 익스텐션은 page action과 content script을 사용한다.

 페이지의 색을 설정하는 익스텐션은 클릭이나 팝업을 보여주기 위해 browser action을 사용한다.

익스텐션과 크롬 앱은 크롬의 context menu, option page나 content script를 사용해서 방법으로 ui를 보여줄수 있다. Developer's Guide를 참고해서 익스텐션의 특징들을 살펴보고 각각의 구현체를 살펴보자.


파일들.

각각의 익스텐션은 아래의 파일들을 가진다.

manifest파일.

한개 또는 그 이상의 html파일들.

선택적으로 javascript파일,

선택적으로 필요한 다른 파일들. ex) image파일.


익스텐션을 작업할때 이 모든 파일을 하나의 폴더에 넣는다. 배포할때에는 폴더의 내용들이 .crx라는 확장자로 압축되서 배포된다. Chrome Developer Dashboard에 올리면 .crx파일이 나타난다. 배포에 대해 더 자세히 알고 싶으면 여길 참조하자.


파일 알아보기.

익스텐션에 사용하고 싶은 어떤 파일이던 넣을수 있지만 어떻게 사용할까? 일반적으로 url의 상대경로를 이용해서 html페이지에서 보여주는 것처럼 표시가 가능하다. images폴더 안의 myimage.png라는 이미지를 보여주려면 이렇게 하면 된다.


<img src="images/myimage.png">


아마 눈치챘을지 모르겠는데 크롬 디버거를 사용하면서 익스텐션의 모든 파일은 url의 절대경로를 아래처럼 접근할수 있다.


chrome-extension://<extensionID>/<pathToFile>


위의 url에서 extensionID는 익스텐션의 시스템이 각각의 익스텐션에 대해 생성하는 특수한 id이다. chrome://extensions로 들어가서 모든 익스텐션 파일의 id를 볼 수 있다. pathToFile은 익스텐션내의 가장 위의 파일부터의 경로이다. url의 상대 경로와 같다.


익스텐션을 작업하다 보면 id가 바뀔수 있다. id는 unpacked된 익스텐션의 id값은 다른 디렉터리에 익스텐션을 로딩할때마다 바뀔것이다. 익스텐션을 다시 package하면 id값이 또 바뀔거다. 익스텐션이 파일 내의 모든 경로를 써야할 일이 있으면 이미 정의된 값들중 하나인 @@extension_id를 사용해서 개발중 id값을 하드코딩으로 넣는 것을 피할 수 있다. 


익스텐션을 package해서 올리면 업데이트 후에도 변하지 않는 id값을 갖는다. id가 변하지 않는 상태가 되면 굳이 @@extension_id를 사용안해도 된다.


manifest 파일.

manifest.json은 manifest파일이라고 불리며 가장 중요한 파일이나 익스텐션에서 할수 있는 기능 등 익스텐션에 대해서 정보를 준다. 아래에 전형적인 google.com의 정보를 사용하는 manifest파일이 있다.

{
  "name": "My Extension",
  "version": "2.1",
  "description": "Gets information from Google.",
  "icons": { "128": "icon_128.png" },
  "background": {
    "persistent": false,
    "scripts": ["bg.js"]
  },
  "permissions": ["http://*.google.com/", "https://*.google.com/"],
  "browser_action": {
    "default_title": "",
    "default_icon": "icon_19.png",
    "default_popup": "popup.html"
  }
}

자세히 살펴보려면 여기를 보자.


아키텍쳐.

많은 익스텐션이 익스텐션의 주 로직을 담당하며, 안보이는 background page를 가지고 있다. 익스텐션은 또한 ui를 보여주기 위해 다른 페이지들을 포함할 수 있다. 익스텐션이 '유저가 로딩한' 페이지와 통신해야 하면 content script를 사용해야 한다.


background page.

background page는 익스텐션을 컨트롤하는 javascript코드를 포함하는 background.html파일로 정의된다. background page에는

persistent background pagesevent pages의 두가지 종류가 있다. persistent background pages는 이름에서 알수있듯이 항상 열려있다. event pages는 필요에 따라 열리고 닫힌다. 진짜 익스텐션을 계속 돌릴거 아니면 왠만해서는 event page를 추천한다.


더 알고싶으면 event pagebackground page를 보자.


ui 페이지.

익스텐션은 ui를 보여주기 위해 html페이지를 포함할 수 있다. 예를 들면 browser action은 html로 나타나는 팝업창을 가질수 있다. 어떤 익스텐션이던 익스텐션의 작업을 커스터마이징 하기 위한 option page를 가질 수 있다. 또다른 특별한 페이지는 override page이다. 마지막으로 html파일을 보여주기 위해 tabs.create나 windows.open을 사용할 수 있다.


익스텐션 안의 html 페이지는 다른 DOM들에 완전히 접근할 수 있고, 다른 함수 등등을 불러올(invoke) 수 있다.


아래의 그림은 browser action의 팝업 페이지의 아키텍쳐이다. 팝업 콘텐츠의 웹 페이지는 popup.html라는 html파일이다. 

이 익스텐션은 또한 background.html로 정의되는 background page도 가지고 있다. 팝업은 백그라운드 페이지의 함수를 불러올 수 있기 때문에 코드를 복제할 필요가 없다.

더 알고싶으면 Browser actionoptions, override pages, communication between pages를 보자.


content script.

익스텐션은 content script를 이용해 웹 페이지와 통신할수 있다. content script는 브라우저에서 로딩되서 실행되는 자바스크립트다. content script를 익스텐션의 일부가 아닌, 로딩된 페이지의 일부분이라 생각하자.


content script는 브라우저가 방문하는 페이지의 세부사항을 읽을 수 있고, 페이지에 변화를 만들 수 있다. 아래의 그림에서 content script는 보여지는 웹 페이지의 DOM을 읽고 변경할 수 있다. 하지만 익스텐션의 background 페이지의 DOM을 변화시킬수는 없다.

content script는 익스텐션으로부터 완전히 분리될 수 없다. content script는 익스텐션과 아래에 보이는 그림처럼 메시지를 교환할 수 있다. 예를 들면 content script는 RSS fedd를 브라우저에서 찾자마자 메시지를 보내거나 background page는 content script에게 브라우저의 외형 등을 바꾸기 위해 메시지를 보낼 수 있다.

더 자세히 살펴보려면 content scripts를 보자.


크롬 api사용하기.

api에 접근하는 것과 더불어 익스텐션에서 크롬만 사용할수 있는 api에 접근할 수 있다. 예를 들면 어떤 익스텐션이나 웹앱에서 window.open()함수를 사용할수 있다. 하지만 크롬 전용 api인 tabs.create를 사용해서 어떤 윈도우에서 보여질지 정할 수도 있다.


동기, 비동기 메소드.

크롬에서의 대부분의 api는 비동기이다. 그러므로 결과값을 받고 싶으면 콜백 함수를 메소드안에 넣어서 받을수 있다. 콜백 함수는 함수가 리턴되고 나서 나중에 실행된다. 아래에 비동기 메소드의 시그니쳐에 대한 예가 있다.


chrome.tabs.create(object createProperties, function callback)


이것 빼고 다른 chrome.으로 시작하는 메소드는 동기다. 동기 메소드는 끝나기 전까지 리턴하지 않기 때문에 콜백 함수를 갖지 않는다. 종종 동기 메소드는 return type을 갖는다. runtime.getURL메소드를 보자.


string chrome.runtime.getURL()


이 메소드는 동기 메소드이기 때문에 콜백이 없으며, string을 리턴 타입으로 받는다.


콜백 사용하기 예제.


사용자가 현재 사용하고 있는 탭을 새 url로 열고 싶다고 가정해보자. 이걸 위해 tabs.query를 사용한 tab의 id값을 얻어와야 한다. 그리고 tabs.update를 사용해 현재 탭을 새 url로 이동하게 해야 한다. 


query()함수가 동기 함수면 이런식으로 사용 가능하다.

//THIS CODE DOESN'T WORK
var tab = chrome.tabs.query({'active': true}); //WRONG!!!
chrome.tabs.update(tab.id, {url:newUrl});
someOtherFunction();

query()함수가 비동기 함수이기 때문에 이런식으로 사용하면 안된다. 이 함수는 실행시 끝날때까지 기다렸다가 리턴하는게 아니라 바로 리턴하고, 심지어 결과값도 의미가 없다. query()의 콜백 함수의 인자로 함수를 전달함으로서 제대로 사용할 수 있다.


chrome.tabs.query(object queryInfo, function callback)


앞의 코드를 고치려면 콜백 함수를 사용해야 한다. 다음의 코드는 query()함수의 결과값을 콜백 함수로 받아 사용하는 예제이다.

//THIS CODE WORKS
chrome.tabs.query({'active': true}, function(tabs) {
  chrome.tabs.update(tabs[0].id, {url: newUrl});
});
someOtherFunction();
이 코드에서는 맨 위의 주석을 제거하고 1번째, 4번째, 2번째 라인의 순서로 코드가 실행된다. 이 콜백 함수는 query()함수에 특화되어 있고 현재의 탭이 실행된 후의 결과값, 즉 query()함수가 리턴한 후의 값을 받아서 실행된다. update()함수도 비동기이지만 위의 예제에서는 이후에 결과값을 사용하지 않기 때문에 굳이 콜백함수를 사용하지 않는다.


자세히..

더 자세한 정보를 위해서는 api문서를 참고하자.


페이지들간의 통신.

익스텐션이 들어간 html 페이지들은 통신이 필요하다. 왜냐하면 모든 익스텐션의 페이지가 하나의 프로세스의 동일한 쓰레드에서 동작하기 때문이다. 페이지들은 서로를 부르기 위해 함수를 사용할 수 있다.


익스텐션에서 페이지를 찾으려면 chrome.extension메소드 내부의 getView나 getBackgroundPage같은 함수를 사용할 수 있다. 페이지가 익스텐션을 가진 다른 페이지를 참조하면 다른 페이지의 함수를 불러올 수 있고, 그 페이지의 DOM을 조작할 수 있다.


데이터 저장과 익명 모드.

익스텐션은 storage api를 사용해서 데이터를 저장하거나 서버에 데이터를 저장하라고 요청을 보낼 수 있다. 뭔가를 저장하고 싶을때마다 익명 모드의 윈도우에서 온건지 고려해봐야 한다. 기본적으로 익스텐션은 익명 모드의 윈도우에서 실행되지 않는다. 그러므로 브라우저가 익명 모드일때 유저가 어떤 것을 원할지 고려해야 한다.


익명 모드는 흔적을 남기지 않는것을 보증한다. 익명 윈도우에서 데이터를 다룰때 익명 모드이니만큼 흔적을 남기지 않도록 최선을 다해야 한다. 예를 들면 내가 만든 익스텐션이 일반적으로 클라우드에 검색 기록을 저장해둔다면 익명 모드의 윈도우에서는 저장하지 말자. 이것과는 상관없이 익스텐션의 세팅은 익명모드 윈도우던 아니던 어디서든지 가져와서 저장할 수 있다.


경험상 익명 모드에서도 일부 데이터가 보여질 수 있는데 저장하지 말자.


윈도우가 익명 모드인지 확인하려면 incognito property를 tabs.Tabwindows.Window에서 확인하자.


function saveTabData(tab, data) {
  if (tab.incognito) {
    chrome.runtime.getBackgroundPage(function(bgPage) {
      bgPage[tab.url] = data;      // Persist data ONLY in memory
    });
  } else {
    localStorage[tab.url] = data;  // OK to store data
  }
}