memostack
article thumbnail
블로그를 이전하였습니다. 2023년 11월부터 https://bluemiv.github.io/에서 블로그를 운영하려고 합니다. 앞으로 해당 블로그의 댓글은 읽지 못할 수 도 있으니 양해바랍니다.
반응형

프로젝트 생성

본 글에서는 ui라는 이름의 디렉토리를 생성하여, esm 모듈을 만든다.

mkdir ui
cd ui

 

패키지 관리툴은 yarn berry 버전을 사용하기 위해, 아래 명령어를 수행한다.

yarn set version berry

 

package.json을 생성한다.

yarn init -y

 

{
  "name": "ui",
  "packageManager": "yarn@3.2.1",
  "version": "0.0.1",
  "main": "lib/index.js",
  "scripts": {
    "build": ""
  }
}

 

react 모듈을 만들기 위해, reactreact-dom을 의존성에 추가한다.

yarn add --dev react react-dom

 

package.json 에 react와 react-dom에 대한 peer dependency 버전 제한 설정한다. peer dependency를 추가하여 해당 react 모듈을 사용하는 곳에서 react 버전 문제로 충돌이 발생하지 않도록 한다.

"peerDependencies": {
  "react": ">=18.2.0",
  "react-dom": ">=18.2.0"
}

 

타입 스크립트 설정

typescript와 관련된 의존 lib 설치한다

yarn add --dev typescript tslib @types/node @types/react @types/react-dom @types/jest

 

타입 스크립트 초기 설정을 위해 tsc --init 명령어를 수행한다.

yarn tsc --init

 

수행 후 tsconfig.json 파일이 생성되는것을 확인 할 수 있다. 기본적으로 설정되는 tsconfig.json 이외에 사용할 옵션을 추가한다. (일부 옵션들은 CRA으로 프로젝트 생성시 만들어지는 tsconfig.json 설정값을 참고했다)

{
  "compilerOptions": {
    "declaration": true,
    "declarationDir": "lib",
    "target": "es5",
    "lib": [
      "dom",
      "dom.iterable",
      "es6",
      "esnext"
    ],
    "allowJs": true,
    "skipLibCheck": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "noFallthroughCasesInSwitch": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,
    "jsx": "react-jsx",
    "noImplicitAny": false
  },
  "include": [
    "src"
  ]
}

 

Babel 및 Rollup 설정

바벨 설정

바벨 설치

yarn add --dev @babel/core @babel/preset-env @babel/preset-react @babel/preset-typescript @babel/preset-flow

 

babel.config.json 작성

{
  "presets": ["@babel/preset-env", "@babel/preset-react", "@babel/preset-typescript", "@babel/preset-flow"]
}

 

rollup 설정

rollup 및 필요한 rollup 플러그인 설치를 한다.

yarn add --dev rollup @rollup/plugin-node-resolve rollup-plugin-typescript2 @rollup/plugin-babel @rollup/plugin-commonjs

 

rollup.config.js 설정 파일을 작성하여, es6 모듈 번들링을 하기 위한 작업을 한다.

import { babel } from '@rollup/plugin-babel';
import nodeResolve from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import typescript from 'rollup-plugin-typescript2';
import pkg from './package.json';

export default {
  input: 'src/index.ts',
  output: [
    {
      file: pkg.main,
      format: 'esm',
      sourcemap: true,
    },
  ],
  plugins: [
    commonjs(),
    nodeResolve(),
    typescript({ useTsconfigDeclarationDir: true, tsconfig: './tsconfig.json' }),
    babel({
      babelHelpers: 'bundled',
      exclude: 'node_modules/**/*.(ts|tsx|js|jsx)',
      include: 'src/**/*.(ts|tsx|js|jsx)',
      extensions: ['.ts', '.tsx', '.js', '.jsx', '.es', '.es6', '.mjs'],
    }),
  ],
};

 

 

테스트 컴포넌트 생성

테스트를 위한 간단한 버튼 컴포넌트 생성한다.

 

src/Button/Button.tsx

import React, { ReactNode } from 'react';

interface ButtonProps {
  children: ReactNode;
  onClick: () => void;
}

const Button: React.FC<ButtonProps> = ({ children, onClick }) => {
  return <button onClick={onClick}>{children}</button>;
};

export default Button;

 

src/Button/index.ts

import Button from "./Button";

export { Button };

 

src/index.ts

export { Button } from './Button';

 

빌드 및 다른 App에서 모듈 적용

rollup 명령어를 사용하여 번들링을 한다

  "scripts": {
    "build": "rollup -c"
  },

 

yarn build

 

다른 Web Application에서 import하여 정상적으로 컴포넌트를  화면에 보여주는지 확인한다.

import type { NextPage } from 'next';
import styles from '../styles/Home.module.css';
import { Button } from 'ui';

const Home: NextPage = () => {
  return (
    <div className={styles.container}>
      <Button onClick={() => console.log('clicked!')}>Click me!</Button>
    </div>
  );
};

export default Home;

반응형
블로그를 이전하였습니다. 2023년 11월부터 https://bluemiv.github.io/에서 블로그를 운영하려고 합니다. 앞으로 해당 블로그의 댓글은 읽지 못할 수 도 있으니 양해바랍니다.
profile

memostack

@bluemiv_mm

포스팅이 좋았다면 "좋아요❤️" 또는 "구독👍🏻" 해주세요!