일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- 다짐
- mono-repo
- 디자인 토큰
- 개발자
- 2021년
- c#
- 뇌를자극하는C#
- typescript
- 라이브러리제작
- css framework
- react
- frontend
- 2023 회고
- component
- 2020년
- nextjs
- 24년 계획
- front
- design-system
- design
- npm
- javascript
- design token
- 2024 계획
- 프로그래밍
- compound component
- vite
- 회고
- style-dictionary
- 디자인시스템
- Today
- Total
개탕 IT FACTORY
디자인시스템(4).시스템 구축(라이브러리 제작) vite편 본문
디자인시스템 구축
전 글에서 compound component와 Polymorphic component에 대해서 다뤄봤고,
추가적으로 디자인 토큰이 어떤 것인지에 대해서도 알아보았다.
이번에는 디자인시스템 라이브러리 구축을 위한 과정을 한번 다뤄볼까한다.
디자인 시스템 구축 과정
사실 Rollup으로 구축할려고했으나 vite의 강세와 더불어 내부로직으로 Rollup 설정이 가능한 vite로 빠르게 구축후 Rollup으로 포팅하는 과정을 할려고한다.
고려사항
- 최소한의 번들 사이즈를 유지하게 만든다 (tree shacking 기능이 있는걸 사용한다)
- storybook을 적극활용하여 컴포넌트를 관리한다
- Typescript기반으로 개발한다
- React 개발환경에 맞춰 개발한다 (다른 것들은 추후고려대상)
개발 구축
빠른 개발환경 구축을 위해 vite의 template를 사용하여 설정한다.
라이브러리이긴하지만 개발 내부를 볼수있게 코드베이스에서 확인이 가능하도록 react 템플릿사용
# npm 7+, '--'를 반드시 붙여주세요
npm create vite@latest rendar-design-system -- --template react-ts
# yarn
yarn create vite rendar-design-system --template react-ts
# pnpm
pnpm create vite rendar-design-system --template react-ts
storybook 설치
npx storybook@latest init # 위와 같아 설치하면 스토리북은 자동으로 설치된다
vite.config.ts 수정
처음 설정되어있을시에는 아래와 같을것이다
import { defineConfig } from "vite"; import react from "@vitejs/plugin-react"; // https://vitejs.dev/config/ export default defineConfig({ plugins: [react()], });
변경해주기위해서 2개의 라이브러리 설치가 필요하다
vite-plugin-dts
: TypeScript 정의 파일을 생성해준다 ex) index.d.tsvite-tsconfig-paths
: tsconfig.json의 경올 설정을 Vite에 반영해주는 라이브러리위 라이브러리 외 필요한 라이브러리는 설치해서 사용하면된다
# yarn yarn add vite-plugin-dts vite-tsconfig-paths --dev # npm npm install vite-plugin-dts vite-tsconfig-paths --save-dev
그리고 아래와 같이 변경
import { defineConfig } from "vite"; // Vite 설정을 정의하기 위한 함수 import path from "path"; // 파일 및 디렉토리 경로 작업을 위한 Node.js 모듈 import react from "@vitejs/plugin-react"; // React와의 통합을 위한 Vite 플러그인 import dts from "vite-plugin-dts"; // TypeScript 정의 파일 생성을 위한 플러그인 import tsconfigPaths from "vite-tsconfig-paths"; // tsconfig.json의 경로 설정을 Vite에 반영하기 위한 플러그인 export default defineConfig({ plugins: [ react(), // React 플러그인 사용 dts({ insertTypesEntry: true, // 타입 정의 파일을 생성할 때 entry point를 추가 }), tsconfigPaths(), // tsconfig.json의 paths 옵션을 Vite에서 사용할 수 있게 해줌 ], build: { lib: { entry: path.resolve(__dirname, "index.ts"), // 라이브러리의 진입점 파일 name: "rendar-design-system", // 라이브러리의 글로벌 네임스페이스 formats: ["es", "cjs"], // 번들링 포맷: ES Module과 CommonJS fileName: (format) => `rendar-design-system.${format}.js`, // 생성될 파일 이름 }, rollupOptions: { external: ["react", "react-dom", "@emotion/react", "@emotion/styled", "@emotion/server"], // 번들링에서 제외할 외부 모듈 }, sourcemap: true, // 소스맵 생성 여부 (디버깅 용이) emptyOutDir: true, // 빌드 시 출력 디렉토리를 비울지 여부 }, });
주석으로 설명을 해놨지만 설명을 해보자면
build.lib : Vite의 라이브러리로 빌드할수 있게 설정하는 옵션
entry
: 라이브러리 실행 진입점name
: 라이브러리 글로벌 네이밍formats
: 번들링 포맷을 써준다 (현재 ES module과 CommonJS를 지원하게끔 설정)fileName
: 빌드해서 생성될 패키지 파일명rollupOptions
: 기존 Rollup 번들을 커스텀합니다. (Rollup 옵션과 동일)external
: 번들링시 제외할 외부 모듈 (설치됬다고 가정한다)sourcemap
: 소스맵 생성여부emptyOutDir
: 빌드시 출력 디렉토리 비울지package.json
package.json은 아래와 같이 변경해준다 (주석으로 설명)
main
: 패키지 진입점types
: typescript 타입 정의 파일 경로export
: main 필드와 동일하기 진입 경로 설정 가능, 추가적으로conditional exports
,subpath exports
지원files
: 패키지 설치시 포함될 항목{ "name": "rendar-design-system", // 패키지 이름 "version": "0.0.4", // 패키지 버전 "type": "module", // 이 패키지가 ES 모듈임을 명시 "main": "dist/index.es.js", // 패키지의 진입점 파일 (기본적으로 ES 모듈을 사용) "types": "dist/index.d.ts", // TypeScript 타입 정의 파일 경로 "exports": { // 패키지 내보내기 설정 ".": { // 기본 경로 설정 "import": "./dist/index.es.js", // ES 모듈 사용 시의 진입점 "require": "./dist/index.cjs.js", // CommonJS 모듈 사용 시의 진입점 "types": "./dist/index.d.ts" // 타입 정의 파일 }, "./package.json": "./package.json", // package.json 파일 경로 "./dist/*": "./dist/*" // dist 디렉토리 내 모든 파일 접근 허용 }, "files": [ "/dist" // 패키지에 포함될 파일 또는 디렉토리 목록 (여기서는 dist 디렉토리만 포함) ], //.. 이하 패키지 동일 }
tsconfig.json
typescript를 지원하기 때문에 아래와 같이 해준다
vite설치시 기본항목은 동일하나
include
부분에 진입점 index.ts를 추가해줘야된다{ "compilerOptions": { "target": "ES2020", // 컴파일된 JavaScript 코드가 호환될 ECMAScript 버전을 지정 (ES2020). "useDefineForClassFields": true, // 클래스 필드에 대해 define 대신 ESNext 방식 사용. "lib": ["ES2020", "DOM", "DOM.Iterable"], // 컴파일 시 포함할 라이브러리 설정 (ES2020, DOM, DOM.Iterable). "module": "ESNext", // 모듈 시스템 설정 (ESNext). "skipLibCheck": true, // 라이브러리 파일의 타입 검사를 생략하여 컴파일 속도 향상. /* Bundler mode */ "moduleResolution": "bundler", // 모듈 해석 방식을 번들러 모드로 설정. "allowImportingTsExtensions": true, // TypeScript 확장자를 포함한 import 허용. "resolveJsonModule": true, // JSON 파일을 모듈로서 import 허용. "isolatedModules": true, // 각 파일을 개별적인 모듈로 컴파일. "noEmit": true, // 출력 파일을 생성하지 않음. "jsx": "react-jsx", // JSX 코드의 변환 방식을 설정 (React 17 이상의 jsx 변환 방식 사용). /* Linting */ "strict": true, // 엄격한 타입 검사 설정. "noUnusedLocals": true, // 사용되지 않는 지역 변수를 허용하지 않음. "noUnusedParameters": true, // 사용되지 않는 파라미터를 허용하지 않음. "noFallthroughCasesInSwitch": true, // switch 문에서 case의 fallthrough를 허용하지 않음. "outDir": "./dist", // 컴파일된 출력 파일의 디렉토리 설정. "rootDir": "./", // 소스 파일의 루트 디렉토리 설정. "paths": { "@/*": ["./src/*"] // 모듈 경로 별칭 설정. } }, "include": ["index.ts", "src"], // 포함할 파일과 디렉토리 설정 (라이브러리 index 파일도 포함). "references": [{ "path": "./tsconfig.node.json" }] // 참조할 다른 tsconfig 파일 경로 설정. }
배포전 테스트
배포이전에 테스트를 하고 싶으면 build시킨 파일을 link 시키면된다
yarn link
# or
npm link
node_modules
를 확인해보면 제작한 라이브러리 이름으로 설치가 된 것을 확인해 볼 수 있다.
테스트가 끝났을경우 아래 unlink 명령어를 통해 제거해주어야한다
yarn unlink
# or
npm unlink
컴포넌트 제작하기
배포를하기 위해 간단한 버튼을 만들어볼까한다components/Button/Button.tsx
import styled from "@emotion/styled";
import { ReactNode } from "react";
const ButtonContainer = styled.button`
border: 1px solid gray;
border-radius: 8px;
padding: 20px;
`;
interface ButtonProps {
children: ReactNode;
}
export const Button = ({ children, ...props }: ButtonProps) => {
return <ButtonContainer {...props}>{children}</ButtonContainer>;
};
components/index.tsx
컴포넌트를 모으기 위해 export 파일들을 관리해준다
export { Button } from "./Button/Button";
배포하기
먼저 CLI를 통해서 NPM 계정에 로그인을 해봅시다
npm login
CLI에 로그인을 하였다면 배포를 진행해봅시다
유료로 계정을 결제중이라면 private를 사용해두되지만 저같이 유료결제를 하지 않았을시에는 public을 명시해줍니다.
npm publish --access=public
배포 확인하기
배포이후에는 계정으로 들어가 배포가되었는지 확인을해본다
profile → packages → 내가 만든 라이브러리
아주 잘 배포가 되고 있었다.
결론
나만의 라이브러리, 나만의 디자인 시스템 구축이라는 말만해보고 실천해보지 못하였다
라이브러리는 나보다 더 나은 사람이 만드는거야 라는 생각으로 차일 피일 미루다보니 이렇게 되었는데
막상 만들고 보니 별거 아니였다
물론 시중에 나온 유명한 라이브러리는 최적화 및 여러명의 컨트리뷰터, 구글등의 유명 회사 개발자분들이 만들다보니 내부 로직이나 성능 등은 뛰어날 것이다.
하지만 해본것과 안해본것은 천지차이 아닌가? 라이브러리를 제작해본 경험만으로도 충분히 추후 회사나 나의 사이드프로젝트를 통해 라이브러리를 개발할수있다는 자신감을 가질수 있을 것 같다
이번 프로젝트는 vite 번들러를 사용했지만, 라이브러리에 최적화 되어있는 rollup으로 마이그레이션을 진행해볼까한다.
아마 구현하면서 모노레포 형식으로 vanilla-extract 버전이나 tailwind 버전등을 제작해서 여러 부분으로 제작을 해볼까한다
'Front-end' 카테고리의 다른 글
4년차 프론트엔드 24년 회고록 (0) | 2024.12.30 |
---|---|
JWT refresh token 중복 호출 이슈 (6) | 2024.10.12 |
Vanilla Extract - 설치 및 구현 (0) | 2024.03.25 |
디자인시스템(3). 디자인 토큰 (0) | 2024.03.03 |
디자인시스템(2). Compound Component(합성컴포넌트) (1) | 2024.01.16 |