본문 바로가기
React

🤩 rollup + typescript + react 세팅하기

by 윤-찬미 2021. 4. 26.

🐣 이제 시간남을때마다 컴포넌트 라이브러리를 제작중입니다! 이름은 elpo-ui (엘포유아이) 입니다.

제가 좋아하는 캐릭터 덤보가 코끼리 캐릭터 이라 코끼리와 덤보 이름을 섞은 엘포 입니다 ㅋㅋ

아직 디자인 시스템을 구축, 기획 준비 단계라 차근 차근 블로그에 올리겠습니다.

 

우선 그전에 번들링 셋팅 부터 할거라,

오늘은 rollup + typescript + react setting을 같이 해보도록 하겠습니다!

헤헤 번들링이 안돼서 한참 돌고 돌았는데, 알고보니 오타,, 그러나,, 에디터에서 잡아주지 못한 ,, 흥

 

우선 지난 포스팅에 롤업을 쓰는 이유(바벨이랑 차이점)을 두고 포스팅을 했었는데요! 한번 읽어보심 좋을 것 같아여

(들어간 김에 광고 클릭 ㄱ ㄱ)

yoon-dumbo.tistory.com/43

 

롤업과 웹팩의 차이점 (rollup vs webpack)

🤩 ui 라이브러리를 만들어 보자~ 최근 하고 있는 사이드 프로젝트에들어가는 ui-components 를 라이브러리화 시켜 npm 에 올려 두고 쓰려고 cm-ui (씨뮤아이) 라는 이름으로 개발을 준비 중입니다. 기

yoon-dumbo.tistory.com

 

아니 한번 셋팅해봤는데, 웹팩보다 세팅이 쉬워요! 짝짝짝!


👩🏻‍💻 시작합니다!

우선 최종적인 폴더 구조는 아래와 같습니다.

 

우선 필요한 패키지 부터 설치 해주겠습니다. 당연히 리액트 패키지를 만들 것이니, 리액트, 리액트돔 필요하겠죠?

npm i react react-dom @types/react -D 

 

그리고 react. react-dom 이친구들은 peerDependencies에 위치해야하니, package.json에서 변경을 해주세요!

✋🏻 peerDependencies 위치

react나 react-dom의 경우 다른 프로젝트에서도 사용할 것입니다. 이때 패키지의 호환성 모듈을 지정합니다.

"devDependencies": {
  "@types/react": "^17.0.3",
},
"peerDependencies": {
  "react": "^17.0.2",
  "react-dom": "^17.0.2"
},

👩🏻‍💻 이번엔 typescript 에 대한 설정을 해주도록 하겠습니다.

typescript install

npm i typescript -D

 

typescript 설정 파일

루트디렉토리에 tsconfig.json file을 만들어주시고 안에는 아래와 같이 작성했습니다.

설정은 원하시는대로 커스텀 하시면 됩니다.🤩

특히 디렉토리 부분을 셋팅하는 rootDir,outDir, include, exclude 등은 여러분 프로젝트에맞게 셋팅하면 됩니다.

{
  "compilerOptions": {
    "target": "es5",
    "lib": [
      "dom",
      "dom.iterable",
      "esnext"
    ],
    "declaration": true, //빌드할때 자동으로 d.type file을 만들거야!
    "declarationDir": "build/types", //d.type file이 만들어졌다면 build/type 폴더에 넣어줘
    "allowJs": true,
    "skipLibCheck": true,
    "sourceMap": true,
    "rootDir": "packages/src",
    "outDir": "./build",
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "esModuleInterop": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "jsx": "react",
    "baseUrl": "./"
  },
  "include": [
    "packages/src",
    "packages/src",
    "packages/index.tsx",
    "node_modules/*"
  ],
  "exclude": [
    "node_modules",
    "build",
    "packages/src/**/*.stories.tsx",
    "packages/src/**/*.test.tsx"
  ]
}

🧚🏻‍♂️ babel Setting 하기

이번엔 바벨 셋팅을 해보도록 하겠습니다.

바벨 셋팅에 필요한 패키지들을 먼저 install해주어야 겠지요?

저는 styled-components + react 기반의 코드를 작성할 예정이라,

babel-plugin-styled-components, babel-preset-react-app 도 설치해주겠습니다.

npm i -D babel babel-plugin-styled-components babel-preset-react-app

 

바벨 셋팅 파일인 babelrc.json file을 최상단 루트에 만들어 줍니다.

그리고 아래와 같이 설정 들을 써주시면 됩니다.

타입스크립트를 사용하시는 분들은 typescript 는 꼭 true로 해주세요.

{
  "presets": [["react-app", { "flow": false, "typescript": true }]],
  "plugins": ["babel-plugin-styled-components"]
}

🧚🏻‍♂️ rollup Setting 하기

드디어 롤업 셋팅을 하네요!

롤업셋팅에 필요한 패키지들을 install해주겠습니다.

⭐️ rollup

롤업 패키지

⭐️ rollup-plugin-typescript2

타입스크립트를 번들링하기 위한 패키지

⭐️ @rollup/plugin-commonjs

CommonJS 모듈을 ES6으로 변환하는 롤업 플러그인

⭐️ @rollup/plugin-node-resolve

ode_modules에서 써드파티 모듈을 사용하는 용도

⭐️ rollup-plugin-peer-deps-external

peerDependency로 설치된 라이브러리의 코드가 번들링된 결과에 포함되지 않고, import 구문으로 불러와서 사용할 수 있게 해주는 플러그인

⭐️ @rollup/plugin-image

 JPG, PNG, GIF, SVG 및 WebP 파일을 가져 오는 롤업 플러그인입니다.

npm i -D rollup rollup-plugin-typescript2 @rollup/plugin-commonjs @rollup/plugin-node-resolve rollup-plugin-peer-deps-external @rollup/plugin-image

 

최상단 루트경로에 rollup.conig.js file을 만들어 주세요!

[전체코드]

import peerDepsExternal from "rollup-plugin-peer-deps-external";
import resolve from "@rollup/plugin-node-resolve";
import image from "@rollup/plugin-image";
import commonjs from "@rollup/plugin-commonjs";
import babel from '@rollup/plugin-babel';
import typescript from "rollup-plugin-typescript2";

const packageJson = require("./package.json");
const extentions = ["js", "jsx", "ts", "tsx"];
const external = ["react", "react-dom", "styled-components"];

process.env.BABEL_ENV = "production";

export default {
  input: "packages/src/index.ts",
  output: [
    {
      file: packageJson.main,
      format: "cjs",
      sourcemap: true,
    },
    {
      file: packageJson.module,
      format: "esm",
      sourcemap: true,
    }
  ],
  plugins: [
    peerDepsExternal(),
    resolve({ extentions }),
    babel({
      extentions,
      include: ['packages/src/**/*'],
      exclude: /node_modules/,
      babelHelpers: 'runtime',
    }),
    commonjs({ 
      include: /node_modules/
    }),
    typescript({ useTsconfigDeclarationDir: true }),
    image(),
  ],
  external
}

 

인풋에 들어가는 부분은 처음 entry point를 잡아준 것입니다. packages/src/index.ts부터 저는 번들링을 시작하겠다는 의미라고 생각하시면 됩니다.

 input: "packages/src/index.ts"

 

저는 최종 번들링파일을 두개의 아웃풋으로 낼 겁니다.

cjs, esm 모듈 두개를 내려고 합니다.

그 전에 아래 와 같은 부분보이시죠?

const packageJson = require("./package.json");

package.json file 을 require해서 가져 온 후 

package.json에 번들링을 어떻게 어느 파일에 어떤 확장자로 해줄건지 지정해 주고, 그 값을 가져오겠습니다.

package.json 상단에 여러분이 원하시는 빌드 된 후 위치할 경로들을 각각 적어줍니다.

 "main": "./build/index.js",
 "module": "./build/index.es.js",
 "types": "./build/types/index.d.ts",

 

이 값들은 롤업 파일에서 아래와 같이 쓰입니다.

output: [
    {
      file: packageJson.main,
      format: "cjs",
      sourcemap: true,
    },
    {
      file: packageJson.module,
      format: "esm",
      sourcemap: true,
    }
  ],

 

아래는 어떤 확장자를 처리해줄건지 써놓은 부분입니다.

const extentions = ["js", "jsx", "ts", "tsx"];

 

이부분 까지 완료 하셨다면, package.json file에 빌드, 타입만드는 명령어를 선언 해주겠습니다.

저는 빌드 하기전에 .d.ts file을 자동생성 해준 후 번들링을 해주도록 아래와 같은 명령어를 추가 했습니다.

위치는 script 객체 안에 선언 해주시면 됩니다.

 "build": "tsc --emitDeclarationOnly & rollup -c"

 

이제 간단한 컴포넌트를 하나 만들어 우리가 아까 설정해놓은 input file(package/src/index.ts) 에 가져오겠습니다.

package/src/Button/Button.tsx

import React from 'react';
import { IButtonProps } from './Button.type';

function Button({ children }:IButtonProps):JSX.Element {
  return (
    <button type="button">
      {children}
    </button>
  );
}

export default Button;

package/src/Button/Button.type.tsx

import React from "react";

export interface IButtonProps {
  children: React.ReactNode
}

package/src/index.ts

export { default as Button } from './Button/Button';

 

여기까지 완료 하셨다면, 이제 번들링을 해보겠습니다.

콘솔창에 npm run build 를 해보세요!

 

위와 같이 뜨면 성공입니다!