# 컴포넌트 라이브러리 개발(React library 배포 with Typescript, circleci) 이번 글에선 typescript로 개발된 리엑트 라이브러리 패키지를 circleci를 통해 자동배포하는 과정까지 설명할 예정입니다. 이전 글인 **컴포넌트 라이브러리 개발(디자인 시스템, npm 배포 기초까지)** 를 읽고 오시면 더 좋습니다. [컴포넌트 라이브러리 개발(디자인 시스템, npm 배포 기초까지)](https://blog-seolim.vercel.app/article/4) ## 사전에... ### package.json React component library를 개발하려면 먼저 react의 버저닝에 유의해야 합니다. react는 16.8 버전을 기준으로 hook의 사용이라는 큰 변화가 있었습니다. 따라서 개발하는 패키지를 최소 16.8 버전 이상의 환경에서 할 것을 권장합니다. package.json에 peerDependencies를 아래와 같이 설정합니다. ```typescript peerDependencies { "react": "^16.8.0 || ^17.0.0 || ^18.0.0", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0", } ``` 위 디펜던시에따라 라이브러리를 사용하는 개발자는 16.8버전 이상의 react를 사용해야 정상적으로 동작합니다. 만약 17, 18을 설정하지 않으면 16버전에서만 동작하게됩니다. 그외 필요한 패키지를 설치하고 dependency 혹은 peerDependency에 추가합니다. `@seolim/react-ui` 는 개발용 package.json과 deploy용을 별도로 두고 개발합니다. devDependecies에 storybook등이 포함되어 있고 react를 굳이 dependecies로 설정할 이유가 없으므로(peerDependecies로인해 리엑트 없이는 사용 불가하므로) 아예 별도의 파일로 관리합니다. ```bash - package.json ## 개발용 package.json - package.deploy.json ## 배포용 package.json -> peerDependecies만 설정되어 있음 ``` ## 디렉토리 구조와 typescript 설정 ``` ├── .circleci │ └── config.yml ├── component │ ├── index.tsx │ └── ...components... ├── package.json ├── package.deploy.json ├── tsconfig.json └── ... ``` `@seolim/react-ui` 의 대략적인 디렉토리 구조는 위와 같습니다. .circleci 는 배포 자동화를 위한 config 설정이고, component 디렉토리는 개발한 컴포넌트 소스코드를 담은 디렉토리입니다. js 패키지와 달리 ts 패키지를 배포하기 위해선 각 패키지에 대한 타입선언이 포함된 `d.ts` 파일이 포함되어야 합니다. `d.ts` 는 `@types/~~` 로 별도 배포하거나 패키지자체에 포함되어 배포합니다. `@seolim/react-ui` 는 빌드 타임에 `d.ts`를 포함되도록 빌드합니다. tsconfig.json을 아래와 같이 설정합니다. ```json { "compilerOptions": { "outDir": "./dist", "module": "commonjs", "target": "es5", "lib": ["es6", "dom", "es2016", "es2017"], "jsx": "react", "types": ["react", "@emotion/react/types/css-prop"], "sourceMap": true, "declaration": true, "esModuleInterop": true, "strictNullChecks": true, "noImplicitAny": true, "removeComments": true, "typeRoots": ["index.d.ts", "node_modules/@types"] }, "include": ["component"], "exclude": ["node_modules", "dist"] } ``` 주요한 설정은 output을 dist 디렉토리에 설정하는 **outDir**, typescript를 commonjs로 트랜스파일링 하는 것에대한 **module**설정, 빌드 디렉토리(component)를 포함하는 **include** 설정이 있습니다. 그 외 설정에 대해선 아래 북마크를 참고하시면 좋습니다. [tsconfig의 모든것](https://evan-moon.github.io/2021/08/22/tsconfig-compiler-options-modules/) package.json에 build 명령어를 아래와 같이 설정합니다. ```json "script": { "clean": "rm -rf dist", "build": "npm run clean && tsc && cp deploy.package.json dist/package.json", } ``` 빌드를 실행해보면 dist 파일을 생성하고 내부에 d.ts, sourcemap파일이 포함되어 생성됩니다. 예를 들어 아래와 같은 Button.tsx를 작성하고 index.tsx에서 export 후 빌드하게 되면 dist 디렉토리에 Button.d.ts, Button.js, Button.js.map이 생성된 것을 확인할 수 있습니다. ```typescript! /** Button.tsx */ import React from 'react'; const Button = () => <button>커스텀</button>; export default Button; /** index.tsx */ export { default as Button } from './Button.tsx'; ``` ## circleci를 통한 자동 배포 빌드까지 완료되었기에 이제 배포단계만 남았습니다. 아래 커맨드를 실행합니다. ```bash npm publish --access=public dist ``` 이 과정을 circleci를 통해 자동화 해봅시다. circleci는 자동 배포를 위한 컴퓨팅과 트리거를 제공하는 서비스로 프로젝트를 등록하는 방법은 생략하고 circleci의 설정 부분만 다루도록 하겠습니다. circleci를 등록하는 방법은 아래 공식 문서를 참고합시다. [circleci quick start](https://circleci.com/docs/getting-started/) config.yml 파일을 아래처럼 설정합니다. ```yaml version: 2.1 defaults: &defaults working_directory: ~/{reponame}/{your working directory} docker: - image: cimg/node:14.20.0 jobs: react-publish: <<: *defaults steps: - checkout: path: ~/{reponame} ## 캐시 가져오기 - restore_cache: keys: - v1-dependencies-{{ checksum "package.json" }} - v1-dependencies - run: name: install node_modules command: npm install ## 캐시 저장하기 - save_cache: paths: - node_modules key: v1-dependencies-{{ "package.json" }} - run: name: npm build environment: NODE_ENV: product command: npm run build - run: name: authentication command: npm set //registry.npmjs.org/:_authToken=$NPM_TOKEN - run: name: deploy command: npm publish --access=public dist workflows: version: 2 build: jobs: ## 동작 브랜치 설정 - react-publish: filters: branches: only: master ``` 주요 부분을 살펴보면 배포를 위한 **authentication**에서 npm login 과정을 token을 설정하여 처리하는 곳입니다.다. 자세한 내용은 아래 설명을 참고합시다. [circleci deploy to npm registry](https://circleci.com/docs/deploy-to-npm-registry/?utm_source=google&utm_medium=sem&utm_campaign=sem-google-dg--japac-en-dsa-maxConv-auth-nb&utm_term=g_-_c__dsa_&utm_content=&gclid=Cj0KCQjw--2aBhD5ARIsALiRlwDYN45jN4KFjYR9-xDlFapdO4wXbgAYx7t58oNnfWYa_6HfAsUBYhwaAtr8EALw_wcB) 위 과정을 모두 등록하고 master 브랜치에 push하면 본인의 라이브러리가 배포되고 `npm install`을 통해 가져올 수 있습니다. ## 마무리 지금까지 컴포넌트 라이브러리를 직접 npm 배포와 자동화까지 살펴보았습니다. 다음엔 storybook을 통해 본인의 라이브러리에 대한 디자인 가이드를 제작, 배포하는 과정까지 설명하겠습니다.