들어가기에 앞서
먼저 내가 테스트한 Monorepo의 구조이다.
host/
src/index.tsx # Context.Provider 적용
remotes/
remote1/
remote2/
...
shared/
context/ # Context 로직
- React Context와 관련된 로직은
shared
패키지에 있다. host
패키지에서 App 컴포넌트를 Context의 Provider로 감싸 전체 App이 Context를 구독하도록 한다.- Context가 필요한
remotes
패키지에서 useContext()를 사용한다.
React Context의 Instance가 생성되는 시점
테마를 적용하는 Context가 있다. 1️⃣ 에서 createContext()
를 호출했고 그 결과 새로운 타입의 Context인 ThemeContext가 만들어졌다. 인스턴스가 생성된 것이 아니다. (참고)
// shared/context/ThemeProvider.tsx
type Theme = typeof THEME_DARK | typeof THEME_LIGHT
export const ThemeContext = createContext<Theme>('' as Theme) // 1️⃣
export const ThemeUpdateContext = createContext<
React.Dispatch<React.SetStateAction<Theme>>
>(() => {})
ThemeContext.displayName = 'ThemeContext'
ThemeUpdateContext.displayName = 'ThemeUpdateContext'
export const ThemeProvider = ({ children }) => {
...
return (
<ThemeContext.Provider value={...}>
<ThemeUpdateContext.Provider value={...}>
{children}
</ThemeUpdateContext.Provider>
</ThemeContext.Provider>
)
}
ThemeContext의 인스턴스가 생성되는 시점은 바로 App 컴포넌트에 ThemeContext.Provider를 적용하는 2️⃣ 부분이다. 즉, React Context의 인스턴스가 생성되는 곳은 host
패키지라는 뜻이다.
// host/src/index.tsx
import { createRoot } from 'react-dom/client'
import { ThemeProvider } from '@db/shared'
import App from './App'
const container = document.getElementById('app')
const root = createRoot(container!)
root.render(
<ThemeProvider> // 2️⃣
<App />
</ThemeProvider>
)
하지만 host
패키지는 흩어져있는 remotes
패키지 내의 컴포넌트와 페이지를 모아 전체 어플리케이션의 라우팅을 처리해주는 역할을 할 뿐이다. 실제로 ThemeContext의 theme 상태를 사용하는 것은 remotes
패키지들이다. 그러기 위해선 host
패키지에서 생성된 인스턴스를 다른 remotes
패키지로 공유하는 것이 필요하다.
Module Federation의 shared
옵션
Webpack의 Module Federation을 사용하면 쉽게 공유가 가능하다.
// host/webpack.config.js
const webpack = require('webpack')
const { ModuleFederationPlugin } = webpack.container
const deps = require('./package.json').dependencies // 디펜던시 안에 shared 패키지 존재
module.exports = {
plugins: [
new ModuleFederationPlugin({
shared: {
...deps,
react: { singleton: true, requiredVersion: deps['react'] },
},
}),
]
}
'💻💀 > 개발' 카테고리의 다른 글
[JS] 이벤트의 target과 currentTarget 차이 (with 버블링) (0) | 2022.08.06 |
---|---|
[JS] 고차 함수(Higher-Order Function) (0) | 2022.07.31 |
[Monorepo] Jest 실행 때 자꾸 SyntaxError가 난다면 Babel 설정을 다시 해보자 (0) | 2022.07.24 |
highcharts의 y-axis label에 천 단위 콤마 추가하기(in React) (0) | 2022.01.05 |
[JS] JavaScript에서 CSS 변수 값 사용하기 (0) | 2021.10.24 |