개요

이 페이지와 시작하기 튜토리얼을 한번씩 봤다면 크롬 확장 프로그램을 개발하기 위한 준비가 모두 된 것입니다.

기본

확장 프로그램은 HTML, CSS, JavaScript, 이미지, 기타 등등의 파일들이 ZIP으로 묶여진 것으로 구글 크롬 브라우저에 기능을 추가해 줍니다. 본질적으로는 웹페이지이기 때문에 브라우저가 웹페이지에 제공하는 HTML5 의 모든 API들(Web APIs 참조), XMLHttpRequest 부터 JSON 까지 모든 기능들을 사용할 수 있습니다.

확장 프로그램은 웹페이지나 컨텐트 스크립트 또는 cross-origin XMLHttpRequests를 사용하는 서버와 상호작용을 할 수 있습니다. 또한 브라우저의 bookmarkstabs와 같은 기능과도 상호작용이 가능합니다.

확장 프로그램의 UI

많은 확장 프로그램들이(크롬 App이 아닌) browser actions 또는 page actions의 형태로 크롬에 UI를 추가합니다. 각각의 확장 프로그램은 대부분 하나의 브라우저 액션 또는 페이지 액션을 가질 수 있습니다. 확장 프로그램이 많은 페이지들과 연관이 있을 때 브라우저 액션을 선택합니다. 페이지에 따라 확장 프로그램의 아이콘이 활성화 또는 비활성화 되어야 할 때 페이지 액션을 선택합니다.

screenshotscreenshotscreenshot
구글 메일 체커는 브라우저 액션을 사용합니다.맵피는 페이지 액션과 컨텐트 스크립트를 사용합니다.(웹페이지에 코드를 삽입함)페이지 배경을 변경하는 팝업은 클릭하면 팝업을 보여줍니다. (브라우저 액션)

확장 프로그램은(크롬 App을 포함) 크롬 컨텍스트 메뉴, 옵션 페이지 제공, 페이지를 보는 방법을 변경하는 컨텐트 스크립트 사용 등의 여러 방법으로 UI를 나타낼 수도 있습니다. Developer’s Guide를 보시면 상세 구현과 함께 확장 프로그램의 기능 리스트를 보실 수 있습니다.

파일

확장 프로그램은 다음 파일들을 가집니다:

  • 매니페스트 파일
  • 하나 또는 그 이상의 HTML 파일(확장 프로그램이 테마인 경우 필요하지 않음)
  • 옵션: 하나 또는 그 이상의 자바스크립트 파일
  • 옵션: 이미지 파일과 같이 해당 확장 프로그램이 필요로 하는 파일

확장 프로그램 개발을 하는 동안 이 파일들은 한 폴더안에 들어있어야 합니다. 배포시에 폴더 안의 컨텐츠들은 .crx 확장자를 가지는 ZIP 파일로 묶여집니다. 이 파일은 크롬 개발자 대시보드를 통해 확장 프로그램을 업로드 하면 생성 됩니다. 더 자세한 내용은 Hosting을 참조하세요.

파일 참조하기

확장 프로그램 내에 어떠한 파일이던 넣을 수 있습니다. 그런데 어떻게 사용해야 할까요? HTML 페이지에서 했던 것 처럼 상대주소(relative URL)를 사용해서 파일을 가리키면 됩니다. 다음 예제는 images 폴더에 있는 myimage.png 파일을 참조하는 방법입니다.

크롬 디버거를 사용하면서 알 수 있었겠지만 확장 프로그램에 있는 모든 파일은 절대 경로를 통해 접근이 가능합니다:

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

<extensionID>는 각 확장 프로그램에 대해 시스템이 자동으로 생성하는 유일한 식별자입니다. chrome://extensions 에서 로드되어 있는 모든 확장 프로그램의 ID를 확인할 수 있습니다. <pathToFile>은 확장 프로그램의 최상위 폴더 아내에 있는 위치로써 상대경로와 같습니다.

(패키징 전) 개발중일 때는 확장 프로그램의 ID가 변할 수 있습니다. 특히 압축 해제된 프로그램을 다른 디렉토리에서 로드하는 경우 ID가 바뀝니다. 만약 여러분이 확장 프로그램 내에 있는 특정 파일을 절대 경로로 지정해야 할 경우 @@extension_id 라는 predefined message를 사용함으로써 개발기간 중 ID를 하드코딩 하는 것을 피할 수 있습니다.

확장 프로그램을 패키징할 때 (일반적으로는 대시보드를 통해 업로드 시) 영구적인 ID를 받게 됩니다. 프로그램을 업데이트 하더라도 ID는 변경되지 않습니다. 이후에는 @@extension_id 를 실제 영구적인 ID로 모두 변경하면 됩니다.

매니페스트 파일

manifest.json 파일은 확장 프로그램에 대한 정보를 제공합니다. 가장 중요한 파일로써 확장 프로그램이 사용할 가능성이 있습니다. 다음 코드는 google.com 에서 정보를 받는 브라우저 액션에 대한 일반적인 매니페스트 파일입니다.

더 자세한 내용은 Manifest Files을 참조하세요.

아키텍처

많은 확장 프로그램은 백그라운드 페이지를 가집니다. 메인 로직을 담당하는 보이지 않는 페이지입니다. 또한 UI를 나타내는 많은 페이지들도 가질 수 있습니다. 사용자가 브라우저에 불러오는 웹페이지와 상호 작용을 해야 하는 경우에 필요합니다. 그리고 확장 프로그램은 컨텐트 스크립트를 반드시 사용해야 합니다.

백그라운드 페이지

background.html 에서 정의되는 백그라운드 페이지는 확장 프로그램의 동작을 제어하는 자바스크립트 코드를 포함할 수 있습니다. 종류에는 persistent background pagesevent pages가 있습니다. Persistent 백그라운드 페이지는 그 이름과 같이 항상 실행됩니다. 이벤트 페이지는 필요할 때만 실행됩니다. 백그라운드 페이지가 항상 실행되어야 하는 경우가 아니라면 이벤트 페이지를 사용하는 것이 낫습니다.

자세한 내용은 Event PagesBackground Pages를 참조하세요.

UI pages

확장 프로그램은 UI를 나타내는 일반적인 HTML을 포함할 수 있습니다. 예를 들어 브라우저 액션은 HTML로 구현된 팝업을 가집니다. 어떤 확장 프로그램은 사용자가 프로그램 동작을 설정할 수 있도록 옵션 페이지를 제공하기도 합니다. 다른 형태로는 페이지를 오버라이드한 특별한 페이지가 있습니다. 마지막으로 확장 프로그램에 있는 어떠한 HTML 파일을 나타내기 위해 tabs.createwindow.open()을 사용할 수 있습니다.

확장 프로그램 내부에 있는 HTML 페이지들은 서로의 DOM에 접근이 가능합니다. 그리고 각 페이지에 있는 함수를 호출할 수도 있습니다.

다음 그림은 브라우저 액션의 팝업이 어떠한 구조로 되어있는지 보여주고 있습니다. 팝업의 컨텐츠는 popup.html에 정의된 웹페이지입니다. 이 확장 프로그램은 또한 background.html 이라는 백그라운드 페이지도 가지고 있습니다. 팝업은 백그라운드 페이지에 있는 코드를 중복으로 사용할 필요가 없습니다. 왜냐하면 팝업이 백그라운드 페이지에 있는 함수를 호출할 수 있기 때문입니다.

팝업과 백그라운드 페이지가 서로의 DOM과 함수에 접근할 수 있다.

자세한 내용은 Browser Actions, Options, Override Pages, 그리고 페이지 간 커뮤니케이션을 참조하세요.

컨텐트 스크립트

만약 여러분의 확장 프로그램이 웹페이지와의 상호작용을 해야한다면 컨텐트 스크립트가 필요합니다. 컨텐트 스크립트는 브라우저에 로드된 페이지의 문맥(context) 안에서 실행이 되는 자바스크립트 코드입니다. 확장 프로그램의 일부가 아닌 로드된 페이지의 일부라고 생각해 주세요.

컨텐트 스크립트는 브라우저가 방문한 웹페이지의 세부내용들을 읽을 수 있고 페이지를 변경할 수 있습니다. 다음 그림은 컨텐트 스크립트가 웹페이지의 DOM을 읽고 수정하는 모습입니다. 그러나 이것이 확장 프로그램의 백그라운드 페이지 DOM을 수정할 수는 없습니다.

컨텐트 스크립트가 웹페이지의 DOM을 읽고 수정하는 모습.

컨텐트 스크립트가 부모 확장 프로그램으로부터 완전히 구분되어 있는것은 아닙니다. 아래 그림의 화살표처럼 부모와 메시지를 주고받을 수 있습니다. 예를 들어 컨텐트 스크립트가 웹페이지에서 RSS 피드를 찾은 경우 언제든지 백그라운드 페이지로 메시지를 보낼 수 있습니다. 또는 그 반대로 백그라운드 페이지가 컨텐트 스크립트에게 웹페이지의 모습을 변경시켜달라고 요청할 수도 있습니다.

컨텐트 스크립트와 부모 확장 프로그램간의 메시지 교환.

자세한 내용은 컨텐트 스크립트를 참조하세요.

chrome.* APIs 사용하기

웹페이지와 앱이 사용할 수 있는 모든 API에 대한 접근을 갖는 것 이외에도 확장 프로그램은 크롬-온니 API를 사용할 수도 있습니다. (chrome.* APIs 라고도 불림) 이 API는 브라우저와 매우 밀접한 통합을 허용합니다. 예를 들어 어떠한 확장 프로그램이나 웹앱은 URL을 열기 위해 window.open() 이라는 표준 메서드를 사용할 수 있습니다. 하지만 URL을 특정 창에서 열리도록 하려면 크롬-온니 메서드인 tabs.create를 사용해야 합니다.

비동기 vs 동기 메서드

chrome.* APIs 에 있는 대부분의 메서드는 비동기 방식입니다: 동작이 끝나길 기다리지 않고 바로 리턴을 합니다. 결과값이 필요할 경우에는 메서드에 콜백 함수를 전달합니다. 메서드가 리턴을 받으면 콜백이 실행됩니다. 비동기 메서드의 시그니처(선언 형태)는 다음과 같습니다.

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

다른 chrome.* 메서드는 동기 방식입니다. 콜백을 사용하지 않는데, 동작이 끝날 때까지 메서드에서 리턴값이 오지 않기 때문입니다. 일부 리턴 타입을 가지는 동기 메서드가 있기도 합니다. runetime.getURL 메서드가 있습니다:

string chrome.runtime.getURL()

이 메서드는 콜백 함수는 없지만 string 타입을 리턴합니다. 비동기적인 동작은 하지 않으면서 URL을 동기적으로 리턴하고 있습니다.

콜백 예제

사용자의 현재 선택된 탭에 새 URL로 이동하려면 tabs.query를 써서 현재 탭의 ID를 얻어야 합니다. 그리고 tabs.update를 사용해 새 URL로 이동합니다.

만약 query()가 동기 방식이면 코드는 다음과 같이 작성해야 합니다:

그러나 query()는 비동기로 동작하기 때문에 이 코드는 제대로 짠 코드가 아닙니다. 비동기 메서드는 수행이 끝날 때까지 기다리지 않고 리턴값도 없습니다. query() 메서드의 원형에 콜백 파라미터를 넣어서 비동기식으로 코드를 작성해야 합니다.

chrome.tabs.query(object queryInfo, functioncallback)

위의 잘못된 코드를 콜백 파라미터를 사용해 수정해 보겠습니다. query() 로부터 결과값을 받는 콜백 함수를 어떻게 선언하는지, 콜백 함수 안에서 update()를 어떻게 호출하는지 보도록 하겠습니다.

예제의 동작 순서는 1→4→2 입니다. query()에 명시되어 있는 콜백 함수는 현재 탭에 대한 정보가 있을 때에만 호출이 됩니다. (라인2가 실행됨) update() 는 비동기 메서드이지만 이 예제에서는 update의 결과값을 활용하지 않기 때문에 콜백 파라미터를 쓰지 않았습니다.

더 자세한 내용

더 자세한 내용은 chrome.* API를 참조하세요.

페이지 간 커뮤니케이션

확장 프로그램에 있는 HTML 페이지들은 가끔 서로간의 통신을 필요로 합니다. 여기에 있는 모든 페이지가 동일한 스레드 위에서 동일한 프로세스를 실행하기 때문에 페이지는 서로간에 함수를 직접 호출할 수 있습니다.

확장 프로그램 안에서 페이지를 찾으려면 chrome.extension에 있는 getViews()getBackgroundPage()와 같은 메서드를 사용합니다. 어떤 페이지가 다른 페이지에 대한 참조를 한번 가지게 되면, 그 페이지의 함수를 호출하고 DOM을 조작할 수 있게 됩니다.

데이터 저장과 익명 모드

확장 프로그램은 storage API, HTML5의 web storage API (localStorage와 같은), 서버 요청 등을 사용해 데이터를 저장할 수 있습니다. 무언가를 저장하고 싶을 때는 제일 먼저 그 창이 익명 모드(=시크릿 모드)인지를 확인해야 합니다. 기본적으로 익명 모드에서는 확장 프로그램이 실행되지 않습니다. 브라우저가 익명 모드인 상태에서 사용자가 여러분의 확장 프로그램에서 어떤 것을 예상하고 있는지를 잘 생각해야 합니다.

익명 모드는 창을 닫을 때까지 어떠한 흔적도 남기지 않을 것을 보장하고 있습니다. 이 창에서 데이터를 다룰 때에는 이러한 약속을 지키기 위해 가능한 최선을 다해야 합니다. 예를 들어 여러분의 확장 프로그램이 브라우저 방문 기록을 클라우드에 저장하는 일을 하는 프로그램이더라도 익명 모드에서는 해당 데이터를 저장하지 않아야 합니다. 반면 확장 프로그램의 설정을 저장하는 것은 어떠한 창에서든 가능합니다.

규칙: 사용자가 웹에서 어떠한 곳을 방문했고 무엇을 했다는 데이터가 보이더라도 그것이 익명 모드인 경우에는 저장해선 안됩니다.

익명 모드인지 확인하려면 tabs.Tab 또는 windows.Window 객체에 있는 incognito 속성을 확인해야 합니다. 예제를 확인하세요:

그 다음 할 일

확장 프로그램에 대한 기본적인 소개가 끝났고 이제 개발을 시작할 준비가 되었습니다. 몇가지 문서들을 더 봐도 좋습니다.