브라우저 네임스페이스로 전환

Chrome 148부터 모든 Chrome 확장 프로그램 API는 기존 chrome 네임스페이스 외에 browser 네임스페이스에서도 사용할 수 있습니다. 예를 들어 browser.tabs.create({})chrome.tabs.create({})는 동일합니다.

네임스페이스는 콘텐츠 스크립트, 서비스 워커, 오프스크린 문서를 비롯하여 확장 프로그램 API를 호출할 수 있는 모든 곳에서 사용할 수 있습니다. chrome과 동일한 API 객체를 가리키므로 chrome.tabs === browser.tabs입니다.

browser 네임스페이스는 브라우저 공급업체가 공유 확장 프로그램 표준에 대해 공동작업하는 W3C 커뮤니티 그룹인 WebExtensions Community Group (WECG)의 작업에서 비롯됩니다. chrome 네임스페이스는 사라지지 않으며 두 네임스페이스 모두 계속 작동합니다.

브라우저 네임스페이스 채택 여부 결정

webextension-polyfill을 사용하는 경우 다른 항목을 변경하기 전에 폴리필 사용자 참고사항으로 건너뛰세요. 답변이 다릅니다.

새 확장 프로그램을 빌드하는 경우 minimum_chrome_version"148"로 설정하고 browser를 무조건 사용합니다. 여기에서 읽기를 중지할 수 있습니다. 이 섹션의 나머지 부분은 채택 방법을 결정하는 기존 확장 프로그램을 위한 것입니다.

사용자가 사용하는 Chrome 버전 확인

기존 확장 프로그램이 있는 경우 전환하기 전에 사용자가 실행 중인 Chrome 버전을 확인하세요. Chrome은 자동 업데이트되지만 일부 사용자는 업데이트를 사용 중지하고 다른 사용자는 최신 버전을 실행할 수 없는 이전 기기를 사용합니다. 자체 분석 데이터로 확인하세요. 아직 분석을 설정하지 않은 경우 Google 애널리틱스 4로 확장 프로그램의 실적 모니터링 을 참고하여 시작하세요.

여기에서 경로를 선택합니다.

무조건 채택

매니페스트에서 minimum_chrome_version 을 설정하고 browser를 무조건 사용합니다. 런타임 가드는 필요하지 않습니다.

{
  "minimum_chrome_version": "148"
}

minimum_chrome_version을 올릴 때는 단계적 출시를 사용하세요. 문제가 발생하면 Chrome 웹 스토어에서 확장 프로그램을 롤백할 수 있습니다.

런타임 가드 사용

다른 곳에서 browser를 참조하기 전에 확장 프로그램의 시작 코드 초기에 다음 스니펫을 추가합니다.

if (!globalThis.browser) {
  globalThis.browser = chrome;
  // Consider firing an analytics event here to measure how often
  // your users hit this fallback path.
}

이렇게 하면 이전 버전에서 browserchrome의 별칭이 되므로 나머지 코드는 browser를 무조건 사용할 수 있습니다.

폴리필 사용자 참고사항

확장 프로그램이 webextension-polyfill을 사용하는 경우 Chrome 148 이상에서 no-op가 됩니다. 폴리필은 호스트 브라우저가 이미 API를 제공했다고 가정하고 browser가 이미 정의된 경우 래핑을 건너뛰었습니다.

이러한 이유로 Chrome 136에서 네임스페이스를 제공하려는 이전 시도가 롤백되었습니다. browser가 새로 정의되면서 폴리필이 래핑을 중지했지만 Chrome의 browser.runtime.onMessage는 폴리필이 제공해 온 promise 반환 리스너를 아직 지원하지 않았습니다. 이 패턴에 의존하는 확장 프로그램이 중단되었습니다. Chrome 148은 이러한 격차를 방지하기 위해 네임스페이스와 기본 promise 반환 onMessage 리스너를 함께 제공합니다.

사용자층이 Chrome 148로 이동하면 폴리필 종속 항목을 삭제할 수 있습니다.

기타 기능

runtime.sendMessage의 비동기 응답

Chrome 148에서 runtime.onMessage 리스너는 Promise를 직접 반환하여 비동기 응답을 보낼 수 있습니다. chrome.* 또는 browser.*를 사용하여 호출하든 관계없이 작동합니다.

이전에는 리스너에서 리터럴 true를 반환하고 나중에 sendResponse를 호출하는 것이 비동기적으로 응답하는 유일한 방법이었습니다.

// Old pattern - requires returning true to keep the channel open
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
  fetch('https://example.com')
    .then(response => sendResponse({ statusCode: response.status }));

  return true; // keeps the message channel open for the async response
});

이제 Promise를 직접 반환하거나 async 함수를 사용할 수 있습니다.

// New pattern - return a promise or use async/await
browser.runtime.onMessage.addListener(async (message, sender) => {
  const response = await fetch('https://example.com');
  return { statusCode: response.status };
});

return true 패턴은 계속 작동하므로 기존 코드를 변경할 필요가 없습니다.