shadow-react-host
v0.1.7
Published
React Shadow DOM 호스트 라이브러리
Downloads
1,007
Readme
shadow-react-host
React에서 Shadow DOM 경계와 스타일 주입을 재사용하기 위한 경량 라이브러리입니다. 현재 런타임 공개 export 는 ShadowDomHost, useShadowStyleInjection 두 개만 유지합니다.
설치
LLM 셋업가이드
0. 개요
shadow-react-host는 React 컴포넌트를 Shadow DOM 안에 렌더링하고, 기본 스타일·커스텀 <style>·adoptedStyleSheets를 같은 ShadowRoot 경계 안에 주입하는 호스트 컴포넌트다.
주로 MFE, Web Component, 외부 서비스에 삽입되는 위젯처럼 바깥 앱의 전역 CSS와 충돌하면 안 되는 React UI에 사용한다. styles는 일반 CSS 문자열을 <style> 태그로 주입할 때 쓰고, adoptedStyleSheets는 :host, :root처럼 ShadowRoot 자체에 적용해야 하는 CSSStyleSheet를 주입할 때 쓴다.
LLM 에이전트에게 적용을 요청할 때는 이 블록 하나를 그대로 복사해 전달한다.
1. 패키지를 설치한다.
bun add shadow-react-host
2. React 엔트리 또는 위젯 루트에서 ShadowDomHost로 격리할 UI를 감싼다.
import { ShadowDomHost } from 'shadow-react-host';
const hostStyleSheet = typeof CSSStyleSheet === 'undefined' ? undefined : new CSSStyleSheet();
hostStyleSheet?.replaceSync(':host { color-scheme: light; }');
export function AppShadowRoot() {
return (
<ShadowDomHost
id="app-shadow-host"
scopeId="app-shadow-scope"
targetSelector="#app-shadow-scope"
styles={[
{
id: 'app-shadow-style',
cssText: '#app-shadow-scope .card { padding: 16px; border-radius: 12px; }',
},
]}
adoptedStyleSheets={hostStyleSheet ? [hostStyleSheet] : undefined}
>
<div className="card">Shadow DOM 내부 콘텐츠</div>
</ShadowDomHost>
);
}
3. 옵션 사용 기준
- scopeId: Shadow DOM 내부 스타일 스코프 루트 id
- targetSelector: 기본 스타일에서 치환할 대상 셀렉터. 보통 #scopeId 형태로 둔다.
- styles: ShadowRoot 안에 <style> 태그로 추가할 CSS 문자열 목록
- adoptedStyleSheets: :host, :root 대응처럼 CSSStyleSheet를 ShadowRoot에 직접 adopt해야 할 때만 전달한다. 없으면 생략한다.
- disableDefaultStyles: 라이브러리 기본 스타일이 필요 없을 때 true로 둔다.기본 설치
bun add shadow-react-hostPeer Dependencies
앱에서 아래 peer dependency 를 직접 설치해야 합니다.
react:^18.3.1 || ^19.0.0react-dom:^18.3.1 || ^19.0.0
@emotion/cache, @emotion/react, react-shadow는 shadow-react-host의 런타임 dependency로 함께 설치됩니다.
기본 import
import { ShadowDomHost, useShadowStyleInjection } from 'shadow-react-host';ShadowDomHost 예시
import { ShadowDomHost } from 'shadow-react-host';
const hostStyleSheet = typeof CSSStyleSheet === 'undefined' ? undefined : new CSSStyleSheet();
hostStyleSheet?.replaceSync(':host { color-scheme: light; }');
export function Example() {
return (
<ShadowDomHost
id="demo-host"
scopeId="demo-scope"
targetSelector="#demo-scope"
styles={[
{
id: 'demo-card',
cssText: '#demo-scope .card { padding: 16px; border-radius: 12px; background: #111827; color: white; }',
},
]}
adoptedStyleSheets={hostStyleSheet ? [hostStyleSheet] : []}
>
<div className="card">Shadow DOM 내부 콘텐츠</div>
</ShadowDomHost>
);
}adoptedStyleSheets에는 CSSStyleSheet 인스턴스를 넘길 수 있습니다. :root, :host처럼 ShadowRoot 자체에 적용해야 하는 스타일은 <style> 태그 주입 대신 이 옵션으로 주입할 수 있습니다.
useShadowStyleInjection 예시
import { useShadowStyleInjection } from 'shadow-react-host';
export function ExampleHook() {
const styleInjection = useShadowStyleInjection({
scopeId: 'hook-scope',
targetSelector: '#hook-scope',
position: 'bottom',
styles: [
{ id: 'hook-style', cssText: '#hook-scope { padding: 8px; }' },
],
});
return <pre>{JSON.stringify(styleInjection, null, 2)}</pre>;
}styleInjection 옵션
scopeId: 스타일 스코프 루트 idtargetSelector: 기본 스타일 치환 대상 셀렉터disableDefaultStyles: 기본 번들 스타일 비활성화position: 커스텀 스타일 병합 위치 (top | bottom)styles: 추가 주입 스타일 목록adoptedStyleSheets: ShadowRoot에 adopt할CSSStyleSheet목록 (:host,:root대응 등)
Storybook으로 확인하기
라이브러리의 ShadowDomHost 동작을 시각적으로 확인하려면 Storybook을 실행하세요.
bun install
bun run storybook- 기본 포트:
6006 - Storybook stories 는 모두
import { ... } from 'shadow-react-host'형식을 유지합니다. - 로컬 개발에서는 Storybook Vite alias 가 루트
src/index.ts를 바라봅니다. - 정적 산출물 확인이 필요하면
bun run build-storybook을 실행합니다.
로컬 검증
패키지 변경이나 릴리즈 전에는 아래 명령을 순서대로 확인하는 것을 권장합니다.
bun install
bun x vitest run
bun run build
bun run build-storybook
bun pm pack --dry-runbun x vitest run— 공개 API, 스타일 주입 계약, 문서 계약, Storybook 계약, 릴리즈 준비성 테스트를 확인합니다.bun run build— 스타일 생성(build:styles)과 타입/번들 산출물을 갱신합니다.bun pm pack --dry-run— 실제 배포에 포함될 파일 목록과dist산출물을 점검합니다.
SSR / client boundary 주의사항
import { ... } from 'shadow-react-host'자체는 Node SSR 환경에서도 안전합니다.- 실제 Shadow DOM 활성화와 Emotion cache 연결은 브라우저에서 동작하므로, Next.js 같은 환경에서는 ShadowDomHost 사용 컴포넌트를 클라이언트 경계 안에 두는 것을 권장합니다.
- 서버 렌더 시에는 wrapper markup 과
<style>태그만 안전하게 렌더되고, 클라이언트 하이드레이션 이후 Shadow DOM 이 활성화됩니다. adoptedStyleSheets는 브라우저에서ShadowRoot.adoptedStyleSheets를 지원할 때만 적용되며, 서버 렌더 시에는 기존<style>태그 기반 스타일만 출력됩니다.
