회사에서 새로운 아키텍처를 설계하기 위해서 Frontend 미팅을 하던 중 새로운 아키텍처의 시드를 만드는 것 이외에 재활용 할 수 있는 UI 컴포넌트들을 패키지화 시켜서 관리하는 방안에 대해서 이야기가 나왔습니다.
현재 개발하고 있는 제품에서 사용하고 있으며, 재활용이 가능한 컴포넌트의 목록을 회사 내 위키에 정리 하였고 Common UI Component Package
를 만들어 이를 앞으로의 솔루션에 공통적으로 적용하는 식으로 관리를 하자는 결론을 도출했습니다.
이번 Common UI Component Package
는 CRA
를 통해서 작업을 하며, 환경은 CRA + Typescript + Emotion
입니다.
패키지 배포 및 빌드 시 package.json 에 설정한 파일만 빌드가 됨으로써 필요한 파일들만 패키징 해 빌드 후 사이즈가 작은 모습을 확인했습니다.
또한 npm 에 퍼블리싱 해 버전 관리를 쉽게 할 수 있도록 빌드 했습니다.
Typescript
를 통해서 작성됩니다. 그렇기 때문에 Common UI Component Package
에도 Typescript
를 적용하기 위해서 CRA
에 typescript template
을 씌어줍니다.npx create-react-app osci-playce-ui --template typescript
Typescript
설정을 위해서 tsconfig.json
의 옵션을 수정합니다.{
"compilerOptions": {
"target": "es5",
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"noFallthroughCasesInSwitch": true,
"module": "esnext",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": false, //수정
"jsx": "react-jsx",
"declaration": true, //수정
"outDir": "./dist" //수정
},
"include": ["./src/lib/**/*.tsx", "./src/lib/**/*.ts"] //수정
}
noEmit
: 출력을 내보내지 않겠다는 옵션입니다.
declaration
: d.ts
파일을 생성할지 말지에 대한 옵션입니다.
outDir
: tsc
명령어로 컴파일 된 파일들이 어디에 위치할지 설정합니다.
include
: tsc
명령어로 컴파일 할 파일들이 어디에 위치하는지 설정하는 옵션입니다.
package.json
파일을 수정합니다.{
"name": "common-ui",
"version": "0.1.2",
"private": false,
"main": "dist/index.js",
"types": "dist/index.d.ts",
"browser": "./browser/specific/main.js",
"dependencies": {
"@emotion/react": "^11.9.3",
"@emotion/styled": "^11.9.3",
"@types/node": "^16.11.44",
"@types/react": "^18.0.15",
"@types/react-dom": "^18.0.6",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-scripts": "5.0.1",
"typescript": "^4.7.4"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject",
"prepare": "rm -rf dist && mkdir dist && tsc"
},
"eslintConfig": {
"extends": [
"react-app",
"react-app/jest"
]
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
},
"description": "Comon UI",
"author": {
"name": "name",
"git": "url"
},
"repository": {
"type": "git",
"url": ""
},
"contributors": [
]
}
name
: npm 에 배포할 패키지의 이름입니다. @ 로 시작한다면 npm 유저 이름이 붙어야합니다. (ex @dhkang/common-ui
)
version
: 배포할 패키지의 버전을 명시합니다. (main, minor, patch 순서)
private
: 배포할 패키지가 private
인지 설정합니다.
main
: 라이브러리의 진입점을 설정합니다.
types
: 타입스크립트를 지원하기 위한 타입 추론을 도와주는 진입점 파일을 명시해줍니다.
browser
: 브라우저에서 구동되는 라이브러리를 만들기 위해서는 해당 프로퍼티도 선언해줘야 합니다.
script
를 추가합니다. 아래 스크립트를 실행하면 기존의 dist
폴더를 지우고 다시 생성하여 타입스크립트 파일을 컴파일 합니다.
"prepare": "rm -rf dist && mkdir dist && tsc"
{
...
"description": "Comon UI",
"author": {
"name": "name",
"url": "url"
},
"repository": {
"type": "git",
"url": ""
},
"contributors": [
"contributor"
]
}
.npmignore
파일을 생성 후 작성 해줍니다.node_modules/
src/
public/
tsconfig.json
src/lib/
아래 폴더에 작성해주면 됩니다.index.tsx
에서 export
해줍니다.export { default as TestComponent } from "./TestComponent";
export { default as CircleComponent } from "./CircleComponent";
npm publish
npm login
// ID, PWD, OTP (가입한 이메일로 날라옵니다.)
npm 에 퍼블리싱 된 라이브러리를 확인합니다.
테스트를 위해 다른 프로젝트에서 해당 라이브러리를 설치합니다.
npm i common-ui
yarn add common0ui
import { CircleComponent, TestComponent } from "osci-playce-ui";
function FirstList() {
return (
<div>
<CircleComponent color="red" />
<TestComponent />
</div>
);
}
export default FirstList;
props 가 green 일 때
props 가 red 일 때
위와 같은 방식을 활용한다면 쉽게 UI Component package 를 관리하고 사용할 수 있습니다.