2. 나만의 상태관리 라이브러리 만들기

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()],

},

];

플러그인 역할

각 설정객체

{

// 진입점 파일 지정
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()],
},