Chrome 확장 프로그램 메시지 전송을 위한 구조화된 클론 잠금 해제

Justin Lulejian
Justin Lulejian

게시일: 2026년 4월 13일

다양한 확장 프로그램 구성요소 (백그라운드 스크립트, 콘텐츠 스크립트, 팝업) 간의 통신은 기존에 JSON 직렬화에 의존했습니다. JSON은 안정적이지만 제한사항이 있습니다.

Chrome 148부터 확장 프로그램 개발자가 메시지 직렬화에 구조화된 클론 알고리즘 을 JSON 대신 사용하도록 선택할 수 있다고 발표하게 되어 기쁩니다. 이 현대화를 통해 수동 직렬화 해결 방법 없이 확장 프로그램 컨텍스트 간에 더 복잡한 데이터 유형을 전송할 수 있습니다.

구조화된 클론을 사용하는 이유

JSON 직렬화 (JSON.stringify 내부적으로)는 작동하지만 최신 JavaScript 유형을 처리할 때 개발자가 복잡한 단계를 거쳐야 하는 경우가 있습니다.

확장 프로그램을 개발할 때 발생할 수 있는 구체적인 예는 다음과 같습니다.

// Sending a Map with JSON serialization
const myMap = new Map([['id', 123]]);

// Arrives as {} on the other side!
chrome.runtime.sendMessage(myMap);

// Workaround: Convert Map to an Array of entries before sending
const message = Array.from(myMap.entries());
chrome.runtime.sendMessage(message);

// On the receiving side:
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
  const receivedMap = new Map(message);
});

해결해야 했을 수 있는 JSON이 실패하는 다른 상황은 Set, BigInt, NaNInfinity, Date, Error 객체입니다.

구조화된 클론 직렬화를 사용하면 이전에는 확장 프로그램 메시지를 통해 전송하기 어렵거나 불가능했던 다양한 객체를 전송할 수 있습니다. 예를 들어 Map 객체를 이제 직접 전송할 수 있습니다.

// Sending a Map with Structured Clone
const myMap = new Map([['id', 123]]);

// Arrives as a Map on the other side!
chrome.runtime.sendMessage(myMap);

// On the receiving side:
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
  // message is already a Map instance!
  console.log(message.get('id')); // 123
});

지원되는 유형 더보기

구조화된 클론은 다양한 기타 유형 을 지원합니다(예: FileBlob).

참여 방법

이전 버전과의 호환성을 보장하고 기존 확장 프로그램이 중단되지 않도록 이 기능은 선택 사항입니다. manifest.json에 단일 키를 추가하여 확장 프로그램에 전역적으로 사용 설정할 수 있습니다.

{
  "name": "My Extension",
  "version": "1.0",
  "manifest_version": 3,
  "message_serialization": "structured_clone"
}

생략되거나 Chrome 버전이 148보다 낮은 경우 브라우저는 확장 프로그램의 현재 JSON 기반 구현으로 기본 설정됩니다.

구조화된 클론 알고리즘을 지원함으로써 확장 프로그램 메시지 API를 표준 웹 플랫폼 기능(웹 워커 및 iframe 통신에 사용되는 postMessage와 유사)과 더 가깝게 조정하여 더 많은 유연성과 기능을 제공합니다.

상호 운용성 및 주의사항

구조화된 클론 직렬화 구현은 JSON보다 훨씬 더 많은 유형을 지원하지만 구현과 관련된 몇 가지 아키텍처 가정 및 비호환성이 있으므로 유의해야 합니다.

지원되지 않는 유형

Shared objects like SharedArrayBuffer and transferring of objects like ArrayBuffer are not supported with our implementation. SharedArrayBuffer 는 상황에 따라 직렬화 또는 역직렬화에 실패하며 Uint8Array와 같은 전송 가능한 객체를 전송하려고 하면 대신 사본이 전송됩니다.

확장 프로그램 간 통신

데이터 무결성을 보장하기 위해 일치하는 직렬화 형식을 적용합니다. 직렬화 형식이 일치하지 않는 확장 프로그램은 runtime.sendMessage 또는 runtime.connect를 통해 직접 통신할 수 없습니다. 예를 들어 확장 프로그램 A가 JSON 직렬화를 사용하고 구조화된 클론을 사용하여 확장 프로그램 B에 메시지를 보내려고 하면 메시지가 전송되지 않고 포트가 닫힙니다 (그 반대의 경우도 마찬가지).

웹페이지 통신

externally_connectable을 사용하는 웹페이지는 대상 확장 프로그램의 직렬화 형식에 자동으로 적응합니다. 확장 프로그램이 구조화된 클론을 사용하는 경우 runtime API를 사용하여 메시지를 보내는 웹 컨텍스트는 구조화된 클론을 자동으로 사용합니다 (그 반대의 경우도 마찬가지). 즉, 직렬화 오류를 방지하려면 웹사이트와 확장 프로그램이 예상되는 직렬화 형식에 대해 동기화되어야 합니다.

기본 메시지

기본 메시지 채널은 항상 JSON 직렬화를 강제합니다. 구조화된 클론 전용 유형 (BigInt와 같은)을 기본 호스트로 전송하려고 하면 메시지가 확장 프로그램의 컨텍스트를 벗어나기 전에 실패합니다.

toJSON() 메서드

커스텀 toJSON() 메서드가 있는 클래스 또는 객체를 사용하여 커스텀 직렬화를 실행하는 경우 (예: 객체를 전송하기 전에 비밀번호를 삭제하여 데이터 삭제) 구조화된 클론은 toJSON()무시 합니다. 속성 값을 직접 복사합니다. 커스텀 직렬화에 toJSON()을 사용하는 경우 전송하기 전에 수동 작업이 필요할 수 있습니다. 예를 들면 다음과 같습니다.

class User {
  constructor(name, password) {
    this.name = name;
    this.password = password;
  }

  // This will be ignored by structured clone!
  toJSON() {
    return { name: this.name };
  }
}

const user = new User("Alice", "secret123");

// JSON -> {"name":"Alice"}
// Structured Clone -> { name: "Alice", password: "secret123" }

JSON 직렬화가 사라지나요?

아니요. Chrome은 예측 가능한 미래에 두 직렬화 형식을 모두 지원할 것입니다.

의견 공유

이 새로운 기능이 확장 프로그램 개발을 위한 더 원활하고 강력한 워크플로를 제공할 수 있기를 바랍니다.

구조화된 클론 구현의 기능을 검증하기 위한 테스트 모음을 만들었지만 웹 플랫폼에는 다양한 객체가 있습니다. 이 새로운 기능을 사용해 보고 발견한 버그나 엣지 케이스를 신고해 주세요. 보내주신 의견은 전체 커뮤니티를 위해 구현을 개선하는 데 도움이 됩니다.