1. (구현) 간단한 Store & 리액트와 통합 시키기
import { useSyncExternalStore } from 'react';
type Listener = () => void;
type Selector<T, U> = (state: T) => U;
class Store<T> {
private state: T;
private listeners: Set<Listener> = new Set();
constructor(initialState: T) {
this.state = initialState;
}
getState = (): T => {
return this.state;
}
setState = (newState: Partial<T> | ((prevState: T) => Partial<T>)): void => {
this.state = {
...this.state,
...(typeof newState === 'function' ? newState(this.state) : newState),
};
this.notify();
}
subscribe = (listener: Listener): (() => void) => {
this.listeners.add(listener);
return () => {
this.listeners.delete(listener);
};
}
private notify = (): void => {
this.listeners.forEach((listener) => listener());
}
}
export function createStore<T>(initialState: T) {
const store = new Store(initialState);
function useStore<U>(selector: Selector<T, U> = (state: T) => state as unknown as U): U {
return useSyncExternalStore(store.subscribe, () => selector(store.getState()));
}
return {
useStore,
getState: store.getState,
setState: store.setState,
};
}
2. Rollup 설정하기
import typescript from "@rollup/plugin-typescript";
import commonjs from "@rollup/plugin-commonjs";
import resolve from "@rollup/plugin-node-resolve";
import dts from "rollup-plugin-dts";
export default [
{
input: "src/index.ts",
output: [
{
file: "dist/index.js",
format: "cjs",
},
{
file: "dist/index.esm.js",
format: "esm",
},
],
plugins: [
resolve(),
commonjs(),
typescript({ tsconfig: "./tsconfig.json" }),
],
external: ["react"],
},
{
input: "dist/types/index.d.ts",
output: [{ file: "dist/index.d.ts", format: "es" }],
plugins: [dts()],
},
];
플러그인 역할
- typescript
- commonjs
- CommonJS 모듈을 es moudle 로 변환
- resolve
- dts
- typescript 선언 파일(
.d.ts
)생성
각 설정객체
{
// 진입점 파일 지정
input: "src/index.ts",
// 두가지 형식으로 출력 생성
output: [
{
file: "dist/index.js",
format: "cjs",
},
{
file: "dist/index.esm.js",
format: "esm",
},
],
// 플러그인들 설정
plugins: [
resolve(), // 외부 종속성을 찾고, 번들에 포함시킴
commonjs(), // CommonJS 모듈을 ESM 으로 변환
typescript({ tsconfig: "./tsconfig.json" }), // TypeScript 파일 컴파일
],
external: ["react"], // React 를 외부 종속성으로 처리 (번들에 포함시키지 않는다.)
},
{
// 컴파일 된 타입 선언 파일을 입력으로 서용
input: "dist/types/index.d.ts",
// dist/index.d.ts에 타입 선언 파일 생성
output: [{ file: "dist/index.d.ts", format: "es" }],
// 타입 선언 파일 번ㄷ르링
plugins: [dts()],
},