๋ณธ๋ฌธ์œผ๋กœ ๊ฑด๋„ˆ๋›ฐ๊ธฐ

ยท ์•ฝ 1๋ถ„

๋ชจ๋“ˆ ์ „์ฒด ๋ชฉ๋ก ๋ณด๊ธฐ#

pip list

์—…๋ฐ์ดํŠธ๊ฐ€ ํ•„์š”ํ•œ ํ•ญ๋ชฉ ๋ณด๊ธฐ#

pip list --outdated

์—…๋ฐ์ดํŠธ๊ฐ€ ํ•„์š”ํ•˜์ง€ ์•Š์€ ์ตœ์‹  ํ•ญ๋ชฉ ๋ณด๊ธฐ#

pip list --uptodate

PIP ์—…๋ฐ์ดํŠธํ•˜๊ธฐ#

pip install --upgrade pip

ยท ์•ฝ 1๋ถ„

sudo: unable to resolve host ์—๋Ÿฌ ํ•ด๊ฒฐ#

์ƒํ™ฉ#

  • sudo ๋ช…๋ น์–ด๊ฐ€ ํ•„์š”ํ•œ ์ƒํ™ฉ์—์„œ sudo: unable to resolve host๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ์ƒํ™ฉ

  • hostname๊ณผ hosts์˜ ์ •๋ณด๊ฐ€ ๋‹ฌ๋ผ์„œ ์ƒ๊ธฐ๋Š” ๋ฌธ์ œ

ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•#

  • sudo vi /etc/hosts

    2021-01-16-210113-image-0

  • 127.0.0.1 localhost ๋’ค์— 127.0.1.1 ip-{hostname} ๋ฅผ ์ถ”๊ฐ€

    2021-01-16-210113-image-1


ยท ์•ฝ 1๋ถ„

ssh๋ฅผ ์ด์šฉํ•˜์—ฌ ์›๊ฒฉ ์„œ๋ฒ„์™€ ์–‘๋ฐฉํ–ฅ ํŒŒ์ผ ์ „์†กํ•˜๊ธฐ#

์›๊ฒฉ โ†’ ๋กœ์ปฌ#

scp [์˜ต์…˜] [๊ณ„์ •๋ช…]@[์›๊ฒฉ IP ์ฃผ์†Œ]:[์›๋ณธ ๊ฒฝ๋กœ] [์ „์†ก ๋ฐ›์„ ์œ„์น˜]
scp abc@111.222.333.444:/home/abc/index.html /home/me/

๋กœ์ปฌ โ†’ ์›๊ฒฉ#

scp [์˜ต์…˜] [์›๋ณธ ๊ฒฝ๋กœ ๋ฐ ํŒŒ์ผ] [๊ณ„์ •๋ช…]@[์›๊ฒฉ IP ์ฃผ์†Œ]:[์ „์†กํ•  ๊ฒฝ๋กœ]
scp /home/me/index.html abc@111.222.333.444:/home/abc/

ยท ์•ฝ 1๋ถ„

๊ถŒํ•œ ๋ณ€๊ฒฝ#

chown -R username.username folder/

๋ช…๋ น์–ด๋กœ ํ•ด๋‹น ํด๋”์˜ ์†Œ์œ ์ž๋ฅผ username์œผ๋กœ ๋ฐ”๊ฟ€ ์ˆ˜ ์žˆ๋‹ค.

์ฐธ๊ณ ์ž๋ฃŒ#

[๊ธฐ๋ณธ] ๋ฆฌ๋ˆ…์Šค์˜ ํผ๋ฏธ์…˜(๊ถŒํ•œ)์„ ์กฐ์ •ํ•˜๊ธฐ (chmod, chown)

ยท ์•ฝ 2๋ถ„

Crontab์œผ๋กœ ๋งค์ผ ์Šคํฌ๋ฆฐ์ƒท ๊ด€๋ฆฌํ•˜๊ธฐ#

ํ™˜๊ฒฝ#

  • MacOS + zsh

  • Google Drive File Stream (๋ฌด์ œํ•œ ์šฉ๋Ÿ‰)


๋ชฉ์ #

  • MacOS ์šฉ๋Ÿ‰ ๋ถ€์กฑ

  • ์ฐ์€ ์Šคํฌ๋ฆฐ์ƒท์ด๋‚˜ ๋™์˜์ƒ ๋ณด๊ด€

  • ํ•˜๋ฃจ๋งˆ๋‹ค ์Šคํฌ๋ฆฐ์ƒท ํด๋”์— ํŒŒ์ผ์ด ์Œ“์ด๋Š” ๊ฒƒ ๋ฐฉ์ง€

  • Dock์—์„œ ๋ฐ”๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ๊ด€๋ฆฌ

์Šคํฌ๋ฆฐ์ƒท ์„ค์ •#

  • ์Šคํฌ๋ฆฐ์ƒท์˜ ์ €์žฅ ์œ„์น˜๋ฅผ ๊ตฌ๊ธ€ ๋“œ๋ผ์ด๋ธŒ ํŒŒ์ผ ์ŠคํŠธ๋ฆผ์˜ ํŠน์ • ํด๋”๋กœ ์ง€์ •

์‰˜ ์Šคํฌ๋ฆฝํŠธ#

  • screenshots ํด๋”์— ํŒŒ์ผ์ด ์žˆ์œผ๋ฉด

    • ๋ชจ๋‘ prev-screenshots๋กœ ๋ณต์‚ฌํ•œ๋‹ค.

    • screenshots ํด๋”์˜ ํŒŒ์ผ์„ ๋ชจ๋‘ ์ง€์šด๋‹ค (์ง€์šธ ๋•Œ confirm [y/n] ๋ฉ”์‹œ์ง€ ๋„์šฐ์ง€์•Š๊ฒŒ ์˜ต์…˜ ์„ค์ •)

  • ์—†์œผ๋ฉด ์—์ฝ”

~/scripts/mv_screenshots.sh

#!/bin/zsh
target=/Volumes/GoogleDrive/๋‚ด\ ๋“œ๋ผ์ด๋ธŒ/์ด๋ฏธ์ง€/screenshotsarchive=/Volumes/GoogleDrive/๋‚ด\ ๋“œ๋ผ์ด๋ธŒ/์ด๋ฏธ์ง€/prev-screenshots
if find "$target" -mindepth 1 -print -quit 2>/dev/null | grep -q .; then    setopt localoptions rmstarsilent    cp -R "$target" "$archive/`date +\%Y-\%m-\%d`"    rm "$target"/*else    echo "Target '$target' is empty"fi

Bash checking if folder has contents

Why does rm -f ask me for confirmation on zsh?


ํฌ๋ก ํƒญ ์„ค์ •#

  • ๋งค์ผ ์˜คํ›„ 11:30์— ์‰˜ ์Šคํฌ๋ฆฝํŠธ๋ฅผ ์‹คํ–‰ํ•˜๊ณ  ์‹คํ–‰ํ•œ ๊ฒฐ๊ณผ๋ฅผ ๋‹น์ผ์˜ ๋กœ๊ทธ ํŒŒ์ผ๋กœ ๊ธฐ๋กํ•œ๋‹ค.

crontab -e

30 23 * * * zsh ~/scripts/mv_screenshots.sh >> ~/log/job_`date +\%Y-\%m-\%d`.log 2>&1

์ž‘์—… ์Šค์ผ€์ฅด๋Ÿฌ ํฌ๋ก (Cron) ๊ฐ„๋‹จ ์‚ฌ์šฉ๋ฒ•

Crontab.guru - The cron schedule expression editor


ยท ์•ฝ 3๋ถ„

Merge Options#

Merge#

๊ธฐ๋ณธ์ ์ธ Merge ๋ฐฉ๋ฒ•์œผ๋กœ ํ•˜๋‚˜์˜ ๋ธŒ๋žœ์น˜์˜ ๋ณ€๊ฒฝ ์ด๋ ฅ ์ „์ฒด๋ฅผ ํ•ฉ์น˜๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค.

๋‘ ๋ณ€๊ฒฝ ์ด๋ ฅ์„ ๋ณ‘ํ•ฉํ•œ Merge commit์ด ์ƒˆ๋กœ ์ƒ์„ฑ๋œ๋‹ค.

2021-01-03-210103-image-0

Squash and merge#

๋ธŒ๋žœ์น˜ ์ƒ์˜ ๋ชจ๋“  ์ปค๋ฐ‹์„ ํ•˜๋‚˜๋กœ ๋ณ‘ํ•ฉํ•œ ๋‚ด์šฉ์„ ๋‹ค๋ฅธ ๋ธŒ๋žœ์น˜์— ์ถ”๊ฐ€ํ•˜๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค.

PR์— ์žˆ๋Š” commit log๋“ค์„ ํ•œ ๊ฐœ์˜ ์ปค๋ฐ‹์œผ๋กœ ์ถ”๋ ค์„œ main ๋ธŒ๋žœ์น˜์— ๋ณ‘ํ•ฉํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์—, 1 PR = 1 commit ์ฒ˜๋Ÿผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

2021-01-03-210103-image-1

์ฐธ๊ณ ์ž๋ฃŒ#

[Git] Merge ์ดํ•ดํ•˜๊ธฐ (Merge / Squash and Merge / Rebase and Merge)

6. Github์œผ๋กœ ํ˜‘์—…ํ•˜๋Š” ๋ฒ•

GitHub์˜ Merge, Squash and Merge, Rebase and Merge ์ •ํ™•ํžˆ ์ดํ•ดํ•˜๊ธฐ : TOAST Meetup

Rebase and Merge#

๋ธŒ๋žœ์น˜ ์ƒ์˜ ๋ชจ๋“  commit๋“ค์„ ํ•ฉ์น˜์ง€ ์•Š๊ณ  main ๋ธŒ๋žœ์น˜์— ์ถ”๊ฐ€ํ•˜๋Š” ๋ฐฉ๋ฒ•์ด๋‹ค.

2021-01-03-210103-image-2

GitHub๊ณผ GitLab์˜ Squash and merge ์ฐจ์ด#

GitHub#

Github์—์„œ๋Š” PR์— ๋Œ€ํ•œ ๋จธ์ง€ ๋ฐฉ๋ฒ•์„ ๋‹ค์Œ ์‚ฌ์ง„๊ณผ ๊ฐ™์ด ์ œ๊ณตํ•œ๋‹ค.

2021-01-03-210103-image-3

Squash and merge ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•  ๊ฒฝ์šฐ, Merge commit์ด ๋”ฐ๋กœ ์ƒ์„ฑ๋˜์ง€ ์•Š๊ณ , PR ํƒ€์ดํ‹€์„ ์ปค๋ฐ‹ ์ œ๋ชฉ์œผ๋กœ ํ•˜๊ณ , ๋ธŒ๋žœ์น˜์˜ commit log๋“ค์ด ์ปค๋ฐ‹ ๋‚ด์šฉ์œผ๋กœ ์ƒ์„ฑ๋œ๋‹ค.

2021-01-03-210103-image-4

GitLab#

๋ฐ˜๋ฉด, GitLab์—์„œ๋Š” MR์„ ๋จธ์ง€ํ•  ๋•Œ, Squash commits์˜ ์˜ต์…˜์„ ์ฒดํฌํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•˜๋Š”๋ฐ, GitHub๊ณผ ๋‹ฌ๋ฆฌ ๊ธฐ๋ณธ์ ์œผ๋กœ Merge commit์ด ์ƒ์„ฑ๋˜๋„๋ก ์„ค์ •๋˜์–ด ์žˆ๋‹ค.

2021-01-03-210103-image-5

Merge commit์„ ์ƒ์„ฑํ•˜์ง€ ์•Š๊ธฐ ์œ„ํ•ด์„œ๋Š” Fast-forward merge๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค.

Fast-forward merge requests

Fast-Forward Merge๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  Squash commits ์˜ต์…˜์„ ์ฒดํฌํ•˜์ง€ ์•Š์œผ๋ฉด, Rebase and Merge ์ฒ˜๋Ÿผ ๋™์ž‘ํ•œ๋‹ค.

Fast-Forward Merge๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  Squash commits ์˜ต์…˜์„ ์ฒดํฌํ•˜๋ฉด Squash and Merge ์ฒ˜๋Ÿผ ๋™์ž‘ํ•œ๋‹ค.

ํ•˜์ง€๋งŒ GitHub์—์„œ ์ž๋™์ ์œผ๋กœ ์ปค๋ฐ‹ ๋ฉ”์‹œ์ง€ body์— ๋ธŒ๋žœ์น˜์˜ ์ปค๋ฐ‹ ๋กœ๊ทธ๋ฅผ ๊ธฐ๋กํ•ด์ฃผ๋Š”๋ฐ˜๋ฉด, GitLab์—์„œ๋Š” ์ปค๋ฐ‹ ๋กœ๊ทธ๋ฅผ ๊ธฐ๋กํ•ด์ฃผ์ง€ ์•Š๋Š”๋‹ค. Merge Request์˜ ๋‚ด์šฉ์ด ์žˆ๋‹ค๋ฉด์ด ๋‚ด์šฉ์„ ๋‹ด์„ ์ˆ˜ ์žˆ๊ณ , Modify commit message ๋ฒ„ํŠผ์„ ์‚ฌ์šฉํ•˜์—ฌ ์ง์ ‘ ์ˆ˜์ •ํ•˜๋Š” ๊ฒƒ๋„๊ฐ€๋Šฅํ•˜๋‹ค.

2021-01-03-210103-image-6

์ฐธ๊ณ ์ž๋ฃŒ#

Merging a pull request

Merge requests

ยท ์•ฝ 7๋ถ„

TypeScript + React + Storybook์œผ๋กœ ๋””์ž์ธ ์‹œ์Šคํ…œ ๊ตฌ์ถ•ํ•˜๊ธฐ#

Design System vs Component Library#

โ˜ ๋””์ž์ธ ์‹œ์Šคํ…œ์€ ๊ณ„์† ์ง„ํ™”ํ•˜๋Š” ์žฌ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ๊ตฌ์„ฑ ์š”์†Œ ๋ชจ์Œ์ด๊ณ , ์ผ๊ด€์„ฑ๊ณผ ์†๋„๋ฅผ ๋ณด์žฅํ•˜๋Š” ๊ทœ์น™์„ ๋”ฐ๋ฅด๋Š” ๋ชจ๋“  ์ œํ’ˆ์„ ๊ฐœ๋ฐœํ•˜๊ธฐ ์œ„ํ•œ ๋‹จ์ผ ์ง„์‹ค ๊ณต๊ธ‰์›(SSOT)์ด๋‹ค.

  • ๋””์ž์ธ ์‹œ์Šคํ…œ์€ ์ปดํฌ๋„ŒํŠธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๋„˜์–ด์„œ ๋””์ž์ธ ์›์น™, ์Šคํƒ€์ผ ๊ฐ€์ด๋“œ, ํŒจํ„ด, ํ†ค, ๊ทœ์น™๊ณผ ๋ช…์„ธ์„œ ๋“ฑ์„ ํฌํ•จํ•œ๋‹ค.

ํ”„๋กœ์ ํŠธ ์ƒ์„ฑ#

  • .gitignore , package.json ์ƒ์„ฑ

Storybook ์„ค์น˜ํ•˜๊ธฐ#

npx -p @storybook/cli sb init --type react
  • storybook ์‹œ์ž‘ํ•˜๊ธฐ
yarn storybook

React peer dependencies#

@storybook/react ๊ฐ€ react , react-dom ์„ peer-dependency๋กœ ๊ฐ€์ง€๋ฏ€๋กœ react, react-dom ์„ ์„ค์น˜ํ•ด์•ผ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค. ์„ค์น˜ํ•˜์ง€ ์•Š์œผ๋ฉด ๋‹ค์Œ์˜ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.

Error: Cannot find module 'react-dom/package.json'

ํ•˜์ง€๋งŒ, dependency ์— ์ง์ ‘ ์ถ”๊ฐ€ํ•˜๋ฉด, ๊ฐœ๋ฐœํ•œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์„ค์น˜ํ•œ ์œ ์ €๊ฐ€ react , react-dom ์—ญ์‹œ ์„ค์น˜ ๋ฐ›๊ฒŒ ๋œ๋‹ค. (๊ฒŒ๋‹ค๊ฐ€ ์ •ํ•ด์ง„ ๋ฒ„์ „์œผ๋กœ)

๋”ฐ๋ผ์„œ ์ปดํฌ๋„ŒํŠธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์ž‘์„ฑํ•˜๋Š” ์ž‘์„ฑ์ž ์ž…์žฅ์—์„œ๋Š” storybook์„ ์‹คํ–‰ํ•˜๋Š” ๊ฐœ๋ฐœ ์‹œ์—๋งŒ ์ด ์˜์กด์„ฑ์ด ํ•„์š”ํ•˜๋ฏ€๋กœ devDependency์— ๋ช…์‹œํ•ด์•ผํ•œ๋‹ค.

๋˜ํ•œ, ์ด ์ปดํฌ๋„ŒํŠธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์‚ฌ์šฉ์ž ์ž…์žฅ์—์„œ๋Š” react , react-dom ๊ณผ ํ•จ๊ป˜ ์‚ฌ์šฉํ•ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋”ฐ๋ผ์„œ peerDependency์—๋„ ๋ช…์‹œํ•ด์•ผํ•œ๋‹ค.

peerDependency๋Š” ์ด ์˜์กด์„ฑ๊ณผ ํ•จ๊ป˜ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค๋Š” ๋œป์ด๊ณ , ์œ ์ €๊ฐ€ ์ง์ ‘ ์„ค์น˜ ํ•ด์•ผํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

devDependency๋Š” ํ”„๋กœ์ ํŠธ์˜ ๋กœ์ปฌ์—๋งŒ ์„ค์น˜๋˜๊ณ  ๋ฐฐํฌ์‹œ์—๋Š” ์œ ์ €๊ฐ€ ๋‹ค์šด๋กœ๋“œํ•˜์ง€ ์•Š๊ธฐ๋•Œ๋ฌธ์— peerDependency์™€ devDependency์— ๊ฐ™์€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๋„ ์ถ”๊ฐ€ํ•ด๋„ ๋ฌด๋ฐฉํ•˜๋‹ค.

yarn add -D react react-dom
// package.json"peerDependencies": {  "react": "17.0.1",  "react-dom": "17.0.1",  "styled-components": "5.2.1"}

storybookjs/storybook

Yarn

Duplicate same dependency in package.json devDependencies and peerDependencies?

TypeScript๋กœ ์ด์ „ํ•˜๊ธฐ#

  • typescript, react-docgen-typescript-loader ์„ค์น˜

    yarn add -D typescript react-docgen-typescript-loader
  • stories typescript ๋ฒ„์ „์œผ๋กœ ๋ณ€๊ฒฝ

    create-react-app typescript ํ…œํ”Œ๋ฆฟ์— sb init ์œผ๋กœ ์ƒ์„ฑํ•œ ts ๋ฒ„์ „ stories๋กœ ํ…Œ์ŠคํŠธ

  • .storybook/main.js ๋ณ€๊ฒฝ

    module.exports = {    stories: [        '../stories/**/*.stories.mdx',        '../stories/**/*.stories.@(js|jsx|ts|tsx)',    ],    addons: ['@storybook/addon-links', '@storybook/addon-essentials'],    typescript: {        check: false,        checkOptions: {},        reactDocgen: 'react-docgen-typescript',        reactDocgenTypescriptOptions: {            shouldExtractLiteralValuesFromEnum: true,            propFilter: (prop) =>                prop.parent ? !/node_modules/.test(prop.parent.fileName) : true,        },    },};
  • 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": true,        "jsx": "react-jsx"    },    "include": ["stories"]}

TypeScript

Rollup์œผ๋กœ ๋ฒˆ๋“ค๋งํ•˜๊ธฐ#

โ˜ ์›นํŒฉ์ด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์œ„ํ•œ ๋ฒˆ๋“ค๋Ÿฌ๋ผ๋ฉด, ๋กค์—…์€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์œ„ํ•œ ๋ฒˆ๋“ค๋Ÿฌ๋‹ค.

Webpack and Rollup: the same but different

Rollup ์„ค์ •#

  • ์‚ฌ์šฉํ•˜๋Š” ํ”Œ๋Ÿฌ๊ทธ์ธ
"devDependencies": {  "babel-preset-react-app": "10.0.0", // create-react-app์—์„œ ์‚ฌ์šฉํ•˜๋Š” babel ์„ค์ •  "rollup": "2.35.1",  "rollup-plugin-babel": "4.4.0", // babel ์‚ฌ์šฉ์„ ์œ„ํ•œ ํ”Œ๋กœ๊ทธ์ธ  "rollup-plugin-cleaner": "1.0.0", // build ์ „์— dist ํด๋” ์‚ญ์ œ  "rollup-plugin-commonjs": "10.1.0", // CommonJS์˜ ๋ชจ๋“ˆ ์ฝ”๋“œ๋ฅผ ES6๋กœ ๋ณ€ํ™˜ํ•˜์—ฌ ๊ฒฐ๊ณผ๋ฌผ์— ํฌํ•จ  "rollup-plugin-node-resolve": "5.2.0", // ์จ๋“œํŒŒํ‹ฐ ๋ชจ๋“ˆ์„ ์‚ฌ์šฉํ•˜๊ธฐ์œ„ํ•œ ์šฉ๋„  "rollup-plugin-peer-deps-external": "2.2.4", // peerDependencies๋ฅผ ๋ฒˆ๋“ค๋ง๋œ ๊ฒฐ๊ณผ์— ํฌํ•จํ•˜์ง€ ์•Š์Œ}
  • rollup.config.js
import commonjs from 'rollup-plugin-commonjs';import cleaner from 'rollup-plugin-cleaner';import resolve from 'rollup-plugin-node-resolve';import babel from 'rollup-plugin-babel';import external from 'rollup-plugin-peer-deps-external';import peerDepsExternal from 'rollup-plugin-peer-deps-external';
import pkg from './package.json';
const extensions = ['.js', '.jsx', '.ts', '.tsx'];
process.env.BABEL_ENV = 'production';
export default {    input: './src/index.ts',    plugins: [        cleaner({targets: ['./dist/']}),        peerDepsExternal(),        resolve({extensions}),        commonjs({            include: 'node_modules/**',        }),        babel({            extensions,            include: ['src/**/*'],            presets: [['react-app', {flow: false, typescript: true}]],            runtimeHelpers: true,        }),    ],    output: [        {            file: pkg.module,            format: 'es',        },    ],};

tsconfig.json & package.json ์„ค์ •#

declaration์ด๋ž€, ์ปดํฌ๋„ŒํŠธ๋“ค์—์„œ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋Š” ํƒ€์ž… ์ •๋ณด๋“ค์„ ์ง€๋‹ˆ๊ณ  ์žˆ๋Š” ํŒŒ์ผ.

์ด๋Š” ๋‹ค์Œ ๋ช…๋ น์–ด๋กœ ์ƒ์„ฑ์„ ํ•  ์ˆ˜ ์žˆ๋‹ค.

tsc --emitDeclarationOnly

์ด ๋ช…๋ น์–ด๋ฅผ ์‹คํ–‰ํ•˜๊ธฐ ์ „์— tsconfig.json ์„ ์ˆ˜์ •ํ•ด์ฃผ์–ด์•ผ ํ•œ๋‹ค.

{    "compilerOptions": {        "target": "es5",        "lib": ["dom", "dom.iterable", "esnext"],        "skipLibCheck": true,        "esModuleInterop": true,        "allowSyntheticDefaultImports": true,        "strict": true,        "forceConsistentCasingInFileNames": true,        "module": "esnext",        "moduleResolution": "node",        "resolveJsonModule": true,        "jsx": "react",        "declaration": true,        "declarationDir": "dist/types"    },    "include": ["src"],    "exclude": ["**/*.stories.tsx"]}
  • declarationย ๊ฐ’์„ย trueย ,ย declarationDirย ๊ฒฝ๋กœ๋ฅผย "dist/types"ย ๋กœ,

  • allowJs: ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์™€ ํ˜ผ์šฉ์„ ํ•˜๊ณ  ์žˆ๋‹ค๋ฉด declaration ํŒŒ์ผ์„ ๋งŒ๋“ค์ง€ ๋ชปํ•˜๋ฏ€๋กœ์ œ๊ฑฐ.

  • noEmit: ๊ฒฐ๊ณผ๋ฌผ์„ ๋งŒ๋“ค์ง€ ์•Š๋Š”๋‹ค๋Š” ์˜ต์…˜์œผ๋กœ ์ œ๊ฑฐ.

  • isolatedModules: ์•„๋ฌด ๊ฐ’๋„ ๋‚ด๋ณด๋‚ด์ง€ ์•Š๋Š” ํŒŒ์ผ์„ ๋ฐฉ์ง€ํ•˜๋Š” ์˜ต์…˜. ์ œ๊ฑฐ

stories.tsxย ํ™•์žฅ์ž๋Š” ๋ชจ๋‘ ๋ฌด์‹œํ•˜๋„๋กย excludeย ์˜ต์…˜์„ ์„ค์ •

package.json์—๋Š” Build ์ปค๋งจ๋“œ๋ฅผ ์ถ”๊ฐ€ํ•œ๋‹ค.

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

package.json์—์„œ module, types, files ๋ฅผ ์ถ”๊ฐ€ํ•œ๋‹ค. name์€ scope๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

{    "name": "@younho9/design-system",    "module": "dist/index.js",    "types": "dist/types/index.d.ts",    "files": ["/dist"]}

๋ฐฐํฌ ๋ช…๋ น์–ด

# npm publishnpm publish --access public # scope๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ

์ฐธ๊ณ ์ž๋ฃŒ#

Do you think your component library is your design system? Think again

TypeScript์™€ Storybook์„ ์‚ฌ์šฉํ•œ ๋ฆฌ์•กํŠธ ๋””์ž์ธ ์‹œ์Šคํ…œ ๊ตฌ์ถ•ํ•˜๊ธฐ

๋””์ž์ธ ์‹œ์Šคํ…œ ์†Œ๊ฐœ

storybookjs/design-system

storybookjs/storybook

How to create a react component library with TypeScript, rollup.js and Storybook

Building a Design System Package With Storybook, TypeScript, and React in 15 Minutes

Creating and publishing scoped public packages | npm Docs