๐Ÿ“‹ package.json ์™„์ „ ํ•ด๋ถ€ โ€” ๋ชจ๋“  ํ•„๋“œ์˜ ๋ชฉ์ ๊ณผ ์‹ค์ „ ํŒจํ„ด

2026๋…„ 3์›” 5์ผ ์ˆ˜์ •๋จ

๐Ÿ“‹ ๊ฐœ์š”

package.json ์˜ ๋ชจ๋“  ์ฃผ์š” ํ•„๋“œ๋ฅผ ํ•ด๋ถ€ํ•œ๋‹ค. private, engines, exports, sideEffects, browserslist โ€” Next.js ์‹œ๋‹ˆ์–ด๊ฐ€ ๋ฐ˜๋“œ์‹œ ์•Œ์•„์•ผ ํ•  ์„ค์ •์„ ์ „๋ถ€ ๋‹ค๋ฃฌ๋‹ค.

๐Ÿ“‹ ๋ชฉ์ฐจ


๐Ÿ“Œ ์ด ๋ฌธ์„œ๋ฅผ ์ฝ๊ธฐ ์ „์—

โฑ๏ธ ์˜ˆ์ƒ ์ฝ๊ธฐ ์‹œ๊ฐ„: 20๋ถ„(์ „์ฒด) / ํ•ต์‹ฌ ํŒŒํŠธ๋งŒ: 10๋ถ„ (private, engines, exports)

๐Ÿ—บ๏ธ ์ด ๋ฌธ์„œ์˜ ํ๋ฆ„
์ •์ฒด์„ฑ ํ•„๋“œ โ†’ ์‹ค์ˆ˜ ๋ฐฉ์ง€ ํ•„๋“œ โ†’ ์‹คํ–‰ ํ™˜๊ฒฝ ์„ ์–ธ โ†’ ์ง„์ž…์  ์„ค๊ณ„ โ†’ Tree Shaking ํžŒํŠธ โ†’ ๋ฐฐํฌ ํŒŒ์ผ ์ œ์–ด

๐ŸŽฏ ์ด ๋ฌธ์„œ๋ฅผ ๋‹ค ์ฝ์œผ๋ฉด ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ

  • "private": true ๊ฐ€ ์™œ Next.js ์•ฑ์— ํ•„์ˆ˜์ธ์ง€ ์„ค๋ช…ํ•  ์ˆ˜ ์žˆ๋‹ค
  • engines ํ•„๋“œ๋กœ ํŒ€ ์ „์ฒด์˜ Node.js ๋ฒ„์ „์„ ๊ฐ•์ œํ•  ์ˆ˜ ์žˆ๋‹ค
  • main, module, exports ์˜ ์ฐจ์ด๋ฅผ ์ •ํ™•ํžˆ ๊ตฌ๋ถ„ํ•  ์ˆ˜ ์žˆ๋‹ค
  • "type": "module" ์ด ๋ฌด์—‡์„ ๋ฐ”๊พธ๋Š”์ง€ ์•Œ๊ณ  Next.js ์—์„œ ์–ด๋–ป๊ฒŒ ์ ์šฉ๋˜๋Š”์ง€ ์ดํ•ดํ•œ๋‹ค
  • sideEffects ๋กœ Tree Shaking ์„ ์ตœ์ ํ™”ํ•  ์ˆ˜ ์žˆ๋‹ค

๐Ÿ—บ๏ธ ์ด ๋ฌธ์„œ์˜ ๋ฐฐ๊ฒฝ ์„ธ๊ณ„๊ด€: '์˜์ˆ˜๋„ค ์ปค๋ฎค๋‹ˆํ‹ฐ'

๋ฌด๊ฑฐ์šด ๋ฒˆ๋“ค ๋ฐ•์Šค๋ฅผ ์งŠ์–ด์ง„ ์˜์ฒ ๊ณผ exports๋ฅผ ์„ค๋ช…ํ•˜๋Š” ์˜ํ˜ธ
  • ๐Ÿฃ ์˜์ฒ  ( ์‹ ์ž… ): "์˜ํ˜ธ ๋ฆฌ๋“œ ๋‹˜, package.json ์— ์žˆ๋Š” ํ•„๋“œ ์ค‘์— name, version, dependencies ๋นผ๊ณ ๋Š” ์™œ ์žˆ๋Š”์ง€ ๋ชจ๋ฅด๊ฒ ์–ด์š”. private, engines, sideEffects, exports ๊ฐ™์€ ๊ฑด ์ง„์งœ ํ•„์š”ํ•œ ๊ฑด๊ฐ€์š”? ๊ทธ๋ƒฅ ์—†์–ด๋„ ๋˜๋Š” ๊ฑฐ ์•„๋‹Œ๊ฐ€์š”? ํŠนํžˆ ๋‚ด๋ถ€ UI ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ(@youngsoo/ui) ๋งŒ๋“ค ๋•Œ exports ๋ฅผ ์–ด๋–ป๊ฒŒ ์„ค์ •ํ•ด์•ผ ํ•˜๋Š”์ง€ ๋ชจ๋ฅด๊ฒ ์–ด์„œ ๊ทธ๋ƒฅ main ํ•˜๋‚˜๋งŒ ๋„ฃ์—ˆ๋Š”๋ฐ ๋ฒˆ๋“ค ์‚ฌ์ด์ฆˆ๊ฐ€ ๋„ˆ๋ฌด ํฌ๊ฒŒ ๋‚˜์™”์–ด์š”."
  • ๐Ÿฆ ์˜ํ˜ธ ( ๋ฆฌ๋“œ ): "์˜์ฒ  ๋‹˜, exports ๋ฅผ ์„ค์ • ์•ˆ ํ•˜๋ฉด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ „์ฒด๊ฐ€ ๋ฒˆ๋“ค์— ๋“ค์–ด๊ฐ€์š”. ์˜ˆ๋ฅผ ๋“ค์–ด @youngsoo/ui ์—์„œ ๋ฒ„ํŠผ ์ปดํฌ๋„ŒํŠธ ํ•˜๋‚˜๋งŒ ์“ฐ๋Š”๋ฐ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ฝ”๋“œ ์ „๋ถ€๊ฐ€ ๋“ค์–ด์˜ค๋Š” ๊ฑฐ์˜ˆ์š”. sideEffects: false ์™€ exports ๋ฅผ ์ œ๋Œ€๋กœ ์„ธํŒ…ํ•˜๋ฉด Tree Shaking ์ด ์ž‘๋™ํ•ด์„œ ์“ฐ๋Š” ๊ฒƒ๋งŒ ๋ฒˆ๋“ค์— ๋“ค์–ด๊ฐ€์š”. ๊ทธ๋ฆฌ๊ณ  private: true ์—†์œผ๋ฉด ์‹ค์ˆ˜๋กœ npm ์— ์˜ฌ๋ฆด ์ˆ˜๋„ ์žˆ์–ด์š”."

๐Ÿค” ์™œ ์•Œ์•„์•ผ ํ•˜๋Š”๊ฐ€

์˜์ฒ ์ด๊ฐ€ ์˜์ˆ˜๋„ค ์ปค๋ฎค๋‹ˆํ‹ฐ ํŒ€์˜ ๊ณต์œ  UI ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ @youngsoo/ui ๋ฅผ ๋งŒ๋“ค์—ˆ๋‹ค. ๋ฒ„ํŠผ, ๋ชจ๋‹ฌ, ์ธํ’‹ ๋“ฑ 20๊ฐœ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋“ค์–ด์žˆ๋‹ค. ๋ฉ”์ธ ์•ฑ์—์„œ ๋ฒ„ํŠผ ํ•˜๋‚˜๋ฅผ ๊ฐ€์ ธ์™€ ์“ฐ๋Š”๋ฐ, ๋ฒˆ๋“ค ๋ถ„์„๊ธฐ๋ฅผ ๋Œ๋ ค๋ณด๋‹ˆ @youngsoo/ui ์˜ ๋ชจ๋“  ์ปดํฌ๋„ŒํŠธ ์ฝ”๋“œ๊ฐ€ ๋ฒˆ๋“ค์— ๋“ค์–ด์žˆ์—ˆ๋‹ค.

์›์ธ์€ package.json ์˜ exports ์™€ sideEffects ์„ค์ •์ด ์—†์—ˆ๊ธฐ ๋•Œ๋ฌธ์ด์—ˆ๋‹ค. ๋ฒˆ๋“ค๋Ÿฌ๊ฐ€ "์ด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ์–ด๋А ํŒŒ์ผ์„ ์“ฐ์ง€ ์•Š์•„๋„ ๋˜๋Š”์ง€" ํŒ๋‹จํ•  ์ˆ˜ ์—†์–ด์„œ ์ „๋ถ€ ํฌํ•จ์‹œ์ผœ๋ฒ„๋ฆฐ ๊ฒƒ์ด๋‹ค.

package.json ์˜ ๊ฐ ํ•„๋“œ๋Š” ๋‹จ์ˆœํ•œ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๊ฐ€ ์•„๋‹ˆ๋‹ค. ๋ฒˆ๋“ค ์ตœ์ ํ™”, ์‹ค์ˆ˜ ๋ฐฉ์ง€, ํŒ€ ํ˜‘์—…, ๋Ÿฐํƒ€์ž„ ํ™˜๊ฒฝ ๊ฐ•์ œ์— ์ง์ ‘ ์˜ํ–ฅ์„ ๋ฏธ์น˜๋Š” ์„ค์ •๋“ค์ด๋‹ค.


๐Ÿท๏ธ ์ •์ฒด์„ฑ ํ•„๋“œ โ€” name, version, description, keywords

{
  "name": "@youngsoo/ui",
  "version": "1.4.2",
  "description": "์˜์ˆ˜๋„ค ์ปค๋ฎค๋‹ˆํ‹ฐ ๊ณต์œ  UI ์ปดํฌ๋„ŒํŠธ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ",
  "keywords": ["react", "ui", "components", "youngsoo"],
  "homepage": "https://ui.youngsoo.dev",
  "bugs": {
    "url": "https://github.com/youngsoo-team/ui/issues"
  },
  "repository": {
    "type": "git",
    "url": "https://github.com/youngsoo-team/ui.git"
  },
  "license": "MIT"
}

name ๊ทœ์น™

โœ… ์˜ฌ๋ฐ”๋ฅธ ์ด๋ฆ„:
  youngsoo-community     (์†Œ๋ฌธ์ž, ํ•˜์ดํ”ˆ)
  @youngsoo/ui           (์Šค์ฝ”ํ”„ ํŒจํ‚ค์ง€)
  my-next-app            (์†Œ๋ฌธ์ž, ํ•˜์ดํ”ˆ)

โŒ ์ž˜๋ชป๋œ ์ด๋ฆ„:
  YoungsooCommunity      (๋Œ€๋ฌธ์ž ๊ธˆ์ง€)
  youngsoo community     (๊ณต๋ฐฑ ๊ธˆ์ง€)
  my_app                 (์–ธ๋”์Šค์ฝ”์–ด๋Š” ์ง€์–‘)
  • 214์ž ์ดํ•˜
  • URL-safe ๋ฌธ์ž๋งŒ ์‚ฌ์šฉ
  • ๋Œ€๋ฌธ์ž ์‚ฌ์šฉ ๋ถˆ๊ฐ€ (์Šค์ฝ”ํ”„ ํŒจํ‚ค์ง€๋„ ๋™์ผ)

version โ€” SemVer ํ•„์ˆ˜

"version": "1.4.2"
//          ^ ^ ^
//          | | โ””โ”€ PATCH: ๋ฒ„๊ทธ ์ˆ˜์ •
//          | โ””โ”€โ”€โ”€ MINOR: ๊ธฐ๋Šฅ ์ถ”๊ฐ€ (ํ•˜์œ„ ํ˜ธํ™˜)
//          โ””โ”€โ”€โ”€โ”€โ”€ MAJOR: ํŒŒ๊ดด์  ๋ณ€๊ฒฝ (Breaking Change)

๐Ÿ’ก ๋ฒ„์ „ ์˜ฌ๋ฆฌ๋Š” ๋ช…๋ น์–ด:

npm version patch    # 1.4.2 โ†’ 1.4.3
npm version minor    # 1.4.2 โ†’ 1.5.0
npm version major    # 1.4.2 โ†’ 2.0.0

์ด ๋ช…๋ น์–ด๋Š” package.json ์˜ ๋ฒ„์ „์„ ์ˆ˜์ •ํ•˜๊ณ  git ํƒœ๊ทธ๋„ ์ž๋™์œผ๋กœ ์ƒ์„ฑํ•œ๋‹ค.


๐Ÿ”’ private & repository โ€” ์‹ค์ˆ˜ ๋ฐฉ์ง€์™€ ํŒ€ ํ˜‘์—…

private โ€” ๊ณต๊ฐœ ๋ฐฐํฌ ์‚ฌ๊ณ  ๋ฐฉ์ง€

{
  // ๐Ÿฆ [์ดˆํ•ต์‹ฌ] ์ด ๋ ˆํฌ์ง€ํ† ๋ฆฌ๋Š” "์ตœ์ข… ์•ฑ(์„œ๋น„์Šค)" ์ด๊ณ  ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๊ฐ€ ์•„๋‹ˆ๋ฏ€๋กœ
  // ์ ˆ๋Œ€๋กœ npm ํผ๋ธ”๋ฆญ ์ €์žฅ์†Œ์— ๋ฐฐํฌ(publish)๋˜๋ฉด ์•ˆ ๋œ๋‹ค๋Š” ๊ฐ•ํ•œ ์„ ์–ธ์ž…๋‹ˆ๋‹ค!
  // ์ด๊ฑฐ ํ•œ ์ค„ ์—†์œผ๋ฉด ์†Œ์Šค ์ฝ”๋“œ๊ฐ€ ์™ธ๋ถ€์— ์œ ์ถœ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  "private": true
}

์ด ํ•œ ์ค„์ด ๋ง‰์•„์ฃผ๋Š” ์žฌ์•™:

# "private": true ๊ฐ€ ์—†๋Š” ์ƒํƒœ์—์„œ
npm publish
# โ†’ ํšŒ์‚ฌ ๋‚ด๋ถ€ Next.js ์•ฑ ์ „์ฒด๊ฐ€ ๊ณต๊ฐœ npm ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ์— ์˜ฌ๋ผ๊ฐ
# โ†’ ์†Œ์Šค์ฝ”๋“œ, ํ™˜๊ฒฝ๋ณ€์ˆ˜ ํžŒํŠธ, ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง ์ „๋ถ€ ๊ณต๊ฐœ

๐Ÿ”ฅ ํ™ฉ๊ธˆ ๊ทœ์น™: Next.js ์•ฑ(์ตœ์ข… ๊ฒฐ๊ณผ๋ฌผ)์—๋Š” ํ•ญ์ƒ "private": true ๋ฅผ ๋„ฃ์–ด๋ผ. npm ์— ๋ฐฐํฌํ•  ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—๋งŒ private ๋ฅผ ๋นผ๋ฉด ๋œ๋‹ค.

repository โ€” ํŒ€ ๋„๊ตฌ์™€ ์—ฐ๋™

{
  "repository": {
    "type": "git",
    "url": "https://github.com/youngsoo-team/community.git",
    "directory": "packages/ui"
  }
}

์ด ํ•„๋“œ๊ฐ€ ์ฑ„์›Œ์ง€๋ฉด ๋‹ค์Œ์ด ๊ฐ€๋Šฅํ•ด์ง„๋‹ค:

npm docs           # repository ์˜ docs ๋งํฌ ์ž๋™ ์—ด๊ธฐ
npm bugs           # bugs.url ์ž๋™ ์—ด๊ธฐ
npm repo           # repository URL ์ž๋™ ์—ด๊ธฐ

๋ชจ๋…ธ๋ ˆํฌ ๊ตฌ์กฐ์—์„œ๋Š” "directory" ๋กœ ์„œ๋ธŒ ํŒจํ‚ค์ง€ ๊ฒฝ๋กœ๋ฅผ ๋ช…์‹œํ•œ๋‹ค.


โš™๏ธ engines & browserslist โ€” ์‹คํ–‰ ํ™˜๊ฒฝ ์„ ์–ธ

engines โ€” Node.js / npm ๋ฒ„์ „ ๊ฐ•์ œ

{
  "engines": {
    "node": ">=18.17.0",
    "npm": ">=9.0.0"
  }
}

์ด ํ•„๋“œ๋งŒ์œผ๋กœ๋Š” ๊ฒฝ๊ณ ๋งŒ ์ถœ๋ ฅ๋œ๋‹ค. ์‹ค์ œ๋กœ ๋ฒ„์ „์„ ๊ฐ•์ œํ•˜๋ ค๋ฉด .npmrc ์„ค์ •์ด ํ•„์š”ํ•˜๋‹ค:

# .npmrc
engine-strict=true

์ด์ œ Node ๋ฒ„์ „์ด ๋งž์ง€ ์•Š์œผ๋ฉด npm install ์ž์ฒด๊ฐ€ ์‹คํŒจํ•œ๋‹ค:

npm warn EBADENGINE Unsupported engine {
npm warn EBADENGINE   package: 'youngsoo-community@1.0.0',
npm warn EBADENGINE   required: { node: '>=18.17.0' },
npm warn EBADENGINE   current: { node: 'v16.20.0', npm: '8.19.4' }
npm warn EBADENGINE }
npm error code EBADENGINE

.nvmrc ์™€ ํ•จ๊ป˜ ์™„๋ฒฝํ•œ ํŒ€ ํ™˜๊ฒฝ ํ†ต์ผ:

# .nvmrc (ํ”„๋กœ์ ํŠธ ๋ฃจํŠธ)
18.17.0
# ํŒ€์›์ด ํ”„๋กœ์ ํŠธ ํด๋ก  ํ›„ ์‹คํ–‰ํ•˜๋Š” ์ˆœ์„œ
nvm use          # .nvmrc ์— ๋งž๋Š” Node ์ž๋™ ์‚ฌ์šฉ
npm install      # engines ์ฒดํฌ ํ†ต๊ณผ

browserslist โ€” ์ง€์› ๋ธŒ๋ผ์šฐ์ € ์„ ์–ธ

{
  "browserslist": {
    "production": [
      ">0.2%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  }
}

์ด ์„ค์ •์€ Babel, PostCSS(Autoprefixer), SWC ๋“ฑ์ด ์ฐธ์กฐํ•˜์—ฌ ์–ด๋А ๋ธŒ๋ผ์šฐ์ €๊นŒ์ง€ ์ง€์›ํ•  ํด๋ฆฌํ•„์„ ๋„ฃ์„์ง€ ๊ฒฐ์ •ํ•œ๋‹ค. Next.js ๋„ ๋‚ด๋ถ€์ ์œผ๋กœ ์ด ์„ค์ •์„ ์ฐธ์กฐํ•œ๋‹ค.


๐Ÿšช ์ง„์ž…์  ํ•„๋“œ โ€” main, module, exports

์ด ์„ธ ํ•„๋“œ๋Š” ์ฃผ๋กœ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ํŒจํ‚ค์ง€๋ฅผ ๋งŒ๋“ค ๋•Œ ์ค‘์š”ํ•˜๋‹ค. @youngsoo/ui ๊ฐ™์€ ๋‚ด๋ถ€ ํŒจํ‚ค์ง€๋ฅผ ๋งŒ๋“ค ๋•Œ ๋ฐ˜๋“œ์‹œ ์•Œ์•„์•ผ ํ•œ๋‹ค.

main โ€” CommonJS ์ง„์ž…์  (๋ ˆ๊ฑฐ์‹œ)

{
  "main": "./dist/index.js"
}

require('@youngsoo/ui') ๋ฅผ ์‹คํ–‰ํ•˜๋ฉด ์—ฌ๊ธฐ์„œ ์ง€์ •ํ•œ ํŒŒ์ผ์„ ์ฝ๋Š”๋‹ค. ๋‹จ, ์ด๊ฒƒ๋งŒ ์žˆ์œผ๋ฉด Tree Shaking ์ด ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค. ์ง„์ž…์  ํ•˜๋‚˜์—์„œ ๋ชจ๋“  ๊ฒƒ์„ export ํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

module โ€” ESM ์ง„์ž…์  (๋ฒˆ๋“ค๋Ÿฌ์šฉ)

{
  "main": "./dist/index.cjs.js",
  "module": "./dist/index.esm.js"
}

module ํ•„๋“œ๋Š” Node.js ํ‘œ์ค€์€ ์•„๋‹ˆ์ง€๋งŒ Webpack, Rollup, Vite ๊ฐ™์€ ๋ฒˆ๋“ค๋Ÿฌ๊ฐ€ ์ฐธ์กฐํ•œ๋‹ค. ESM ํ˜•์‹์˜ ํŒŒ์ผ์„ ์ง€์ •ํ•˜๋ฉด Tree Shaking ๊ฐ€๋Šฅ์„ฑ์ด ์—ด๋ฆฐ๋‹ค.

exports โ€” ํ˜„๋Œ€์  ์ง„์ž…์  (๊ถŒ์žฅ)

{
  // ๐Ÿ’ก ํŒจํ‚ค์ง€ ๋‚ด๋ถ€์˜ ๊ธธ์„ ํ„ฐ์ฃผ๋Š” ๋„ค๋น„๊ฒŒ์ด์…˜์ž…๋‹ˆ๋‹ค. (์ง„์ž…์  ํ†ต์ œ + ์ตœ์ ํ™”)
  "exports": {
    // 1๏ธโƒฃ import { Button } from '@youngsoo/ui' ํ•  ๋•Œ ์–ด๋””๋กœ ๊ฐˆ์ง€
    ".": {
      "import":  "./dist/index.esm.js", // ์ตœ์‹  ๋ธŒ๋ผ์šฐ์ €/๋ฒˆ๋“ค๋Ÿฌ์šฉ (Tree Shaking ์นœํ™”์ )
      "require": "./dist/index.cjs.js", // ๊ตฌํ˜• ํ™˜๊ฒฝ์ด๋‚˜ require() ๋กœ ๋ถ€๋ฅผ ๋•Œ
      "types":   "./dist/index.d.ts"    // TypeScript ์ž๋™์™„์„ฑ์„ ์œ„ํ•ด ์ฝ์„ ํŒŒ์ผ
    },
    // 2๏ธโƒฃ import { Button } from '@youngsoo/ui/button' ํ•  ๋•Œ ์–ด๋””๋กœ ๊ฐˆ์ง€
    // ๐Ÿฆ ๊ฐ“๋ฒฝํ•œ ์ตœ์ ํ™”๋ฅผ ์œ„ํ•ด ๊ฒฝ๋กœ๋ณ„๋กœ ์ •ํ™•ํ•˜๊ฒŒ ๋ชฉ์ ์ง€ ํŒŒ์ผ์„ ๊ฐ๊ฐ ์•ˆ๋‚ดํ•ด์ค๋‹ˆ๋‹ค!
    "./button": {
      "import":  "./dist/button.esm.js",
      "require": "./dist/button.cjs.js",
      "types":   "./dist/button.d.ts"
    },
    // 3๏ธโƒฃ ๋ชจ๋‹ฌ ์ปดํฌ๋„ŒํŠธ๋ฅผ ์ฐพ์„ ๋•Œ์˜ ๊ฒฝ๋กœ
    "./modal": {
      "import":  "./dist/modal.esm.js",
      "require": "./dist/modal.cjs.js",
      "types":   "./dist/modal.d.ts"
    }
  }
}

exports ์˜ ๊ฐ•๋ ฅํ•œ ์ :

// ๐Ÿฃ ์˜์ฒ  (์ด์ „) โ€” ์ „์ฒด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๊ฐ€์ ธ์˜ด
import { Button } from '@youngsoo/ui'
// โ†’ exports ์—†์œผ๋ฉด dist/index.js ์ „์ฒด ๋ฒˆ๋“ค์— ํฌํ•จ
 
// ๐Ÿฆ ์˜ํ˜ธ (์ดํ›„) โ€” ๋ฒ„ํŠผ๋งŒ ๊ฐ€์ ธ์˜ด
import { Button } from '@youngsoo/ui/button'
// โ†’ exports ์žˆ์œผ๋ฉด dist/button.esm.js ๋งŒ ๋ฒˆ๋“ค์— ํฌํ•จ

์„œ๋ธŒ ๊ฒฝ๋กœ ์ ‘๊ทผ ์ œ์–ด:

{
  "exports": {
    "./internal/*": null
  }
}

exports ์— ๋ช…์‹œ๋˜์ง€ ์•Š์€ ๊ฒฝ๋กœ๋Š” ์™ธ๋ถ€์—์„œ ์ ‘๊ทผ ๋ถˆ๊ฐ€. @youngsoo/ui/internal/secret ์ ‘๊ทผ ์‹œ๋„ ์‹œ ์—๋Ÿฌ.


๐Ÿ“ type โ€” CommonJS vs ESM ์„ ํƒ

{
  "type": "module"
}
๊ฐ’.js ํŒŒ์ผ ํ•ด์„ ๋ฐฉ์‹๊ธฐ๋ณธ๊ฐ’
"commonjs" (๊ธฐ๋ณธ๊ฐ’)require() / module.exportsโœ…
"module"import / export (ESM)โ€”

์ฃผ์˜: Next.js ์•ฑ์—์„œ์˜ ํ•จ์ •

// โŒ Next.js ์•ฑ์˜ package.json ์— ์ด๊ฑธ ์ถ”๊ฐ€ํ•˜๋ฉด ๋ฌธ์ œ ๋ฐœ์ƒ
{
  "type": "module"
}

Next.js ๋Š” ๋‚ด๋ถ€์ ์œผ๋กœ CommonJS ์™€ ESM ์„ ๋ชจ๋‘ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ณต์žกํ•œ ์„ค์ •์„ ๊ฐ–์ถ”๊ณ  ์žˆ๋‹ค. "type": "module" ์„ ์•ฑ ๋ฃจํŠธ์— ์ถ”๊ฐ€ํ•˜๋ฉด Next.js ์„ค์ • ํŒŒ์ผ(next.config.js ๋“ฑ)์˜ ๋™์ž‘์— ์˜ํ–ฅ์„ ์ค„ ์ˆ˜ ์žˆ๋‹ค. Next.js ์•ฑ์—์„œ๋Š” ์ด ํ•„๋“œ๋ฅผ ๊ฑด๋“œ๋ฆฌ์ง€ ์•Š๋Š” ๊ฒƒ์ด ์•ˆ์ „ํ•˜๋‹ค.

๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—์„œ๋Š” ์ ๊ทน ํ™œ์šฉ:

// @youngsoo/ui/package.json
{
  "type": "module",
  "exports": {
    ".": {
      "import": "./dist/index.js",    // type: module ์ด๋ฏ€๋กœ .js ๊ฐ€ ESM
      "require": "./dist/index.cjs"   // .cjs ๋Š” ํ•ญ์ƒ CommonJS
    }
  }
}

๐ŸŒฒ sideEffects โ€” Tree Shaking ์„ ์œ„ํ•œ ํžŒํŠธ

{
  "sideEffects": false
}

Tree Shaking ์ด๋ž€: ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ์ฝ”๋“œ๋ฅผ ๋ฒˆ๋“ค์—์„œ ์ œ๊ฑฐํ•˜๋Š” ์ตœ์ ํ™”.

// @youngsoo/ui/src/index.ts
export { Button } from './button'
export { Modal } from './modal'
export { Input } from './input'
// ... 20๊ฐœ ์ปดํฌ๋„ŒํŠธ
 
// ์•ฑ์—์„œ ๋ฒ„ํŠผ๋งŒ ์‚ฌ์šฉ
import { Button } from '@youngsoo/ui'

sideEffects: false ๊ฐ€ ์—†์œผ๋ฉด ๋ฒˆ๋“ค๋Ÿฌ๋Š” "์ด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ๋‹ค๋ฅธ ํŒŒ์ผ๋“ค์„ import ํ•ด๋„ ๋ถ€์ž‘์šฉ(์ „์—ญ ๋ณ€์ˆ˜ ๋ณ€๊ฒฝ ๋“ฑ)์ด ์ƒ๊ธธ ์ˆ˜ ์žˆ์œผ๋‹ˆ ์ „๋ถ€ ํฌํ•จํ•˜์ž" ๊ณ  ํŒ๋‹จํ•œ๋‹ค.

sideEffects: false ๋ฅผ ์„ ์–ธํ•˜๋ฉด ๋ฒˆ๋“ค๋Ÿฌ๊ฐ€ "์ด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋Š” import ํ•ด๋„ ๋ถ€์ž‘์šฉ์ด ์—†๋‹ค, Tree Shaking ํ•ด๋„ ์•ˆ์ „ํ•˜๋‹ค" ๊ณ  ํŒ๋‹จํ•œ๋‹ค.

CSS ํŒŒ์ผ์€ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ:

{
  "sideEffects": [
    "*.css",
    "*.scss",
    "./src/polyfills.js"
  ]
}

CSS ํŒŒ์ผ์€ import ์ž์ฒด๊ฐ€ ๋ถ€์ž‘์šฉ(์Šคํƒ€์ผ ์ฃผ์ž…)์ด๋ฏ€๋กœ ์˜ˆ์™ธ๋กœ ์„ ์–ธํ•œ๋‹ค.

๐Ÿ”ฅ Before / After:

โŒ sideEffects ์—†์Œ (์˜์ฒ ์˜ ์ดˆ๊ธฐ ์„ค์ •)

{ "name": "@youngsoo/ui", "main": "./dist/index.js" }

๊ฒฐ๊ณผ: Button ํ•˜๋‚˜ import ํ•ด๋„ 20๊ฐœ ์ปดํฌ๋„ŒํŠธ ์ „์ฒด ๋ฒˆ๋“ค ํฌํ•จ โ†’ ๋ถˆํ•„์š”ํ•œ +200kb

โœ… sideEffects + exports ์„ค์ • (์˜ํ˜ธ์˜ ๋ฆฌ๋ทฐ ํ›„)

{
  "sideEffects": ["*.css"],
  "exports": {
    "./button": { "import": "./dist/button.esm.js" }
  }
}

๊ฒฐ๊ณผ: Button ๋งŒ ๋ฒˆ๋“ค์— ํฌํ•จ โ†’ ์ตœ์†Œ ํฌ๊ธฐ


๐Ÿ“ค files โ€” ๋ฐฐํฌํ•  ํŒŒ์ผ ์„ ํƒ

{
  "files": [
    "dist/",
    "src/",
    "README.md"
  ]
}

npm publish ์‹œ files ์— ๋ช…์‹œ๋œ ๊ฒƒ๋งŒ ํŒจํ‚ค์ง€์— ํฌํ•จ๋œ๋‹ค. ์ง€์ •ํ•˜์ง€ ์•Š์œผ๋ฉด .gitignore ์— ์—†๋Š” ๋ชจ๋“  ํŒŒ์ผ์ด ํฌํ•จ๋œ๋‹ค.

ํ•ญ์ƒ ์ œ์™ธ๋˜๋Š” ํŒŒ์ผ (๋ช…์‹œ ๋ถˆํ•„์š”):

  • .git/
  • node_modules/
  • .npmrc

ํ•ญ์ƒ ํฌํ•จ๋˜๋Š” ํŒŒ์ผ (๋ช…์‹œ ๋ถˆํ•„์š”):

  • package.json
  • README.md
  • LICENSE

๐Ÿ’ก ํ™•์ธ ๋ฐฉ๋ฒ•:

npm pack --dry-run    # ์‹ค์ œ ๋ฐฐํฌ ์—†์ด ํฌํ•จ๋  ํŒŒ์ผ ๋ชฉ๋ก ํ™•์ธ

๐Ÿ”ง config & workspaces

config โ€” ์Šคํฌ๋ฆฝํŠธ์—์„œ ์‚ฌ์šฉํ•  ๋ณ€์ˆ˜

{
  "config": {
    "port": "3000"
  },
  "scripts": {
    "dev": "next dev -p $npm_package_config_port"
  }
}
npm run dev    # next dev -p 3000 ์œผ๋กœ ์‹คํ–‰
npm config set youngsoo-community:port 4000   # ๊ฐœ์ธ ์„ค์ •์œผ๋กœ ๋ฎ์–ด์“ฐ๊ธฐ ๊ฐ€๋Šฅ

workspaces โ€” ๋ชจ๋…ธ๋ ˆํฌ ๊ธฐ์ดˆ

{
  "name": "youngsoo-monorepo",
  "private": true,
  "workspaces": [
    "apps/*",
    "packages/*"
  ]
}
youngsoo-monorepo/
  package.json          โ† ๋ฃจํŠธ (์œ„ ์„ค์ •)
  apps/
    community/          โ† Next.js ์•ฑ
    admin/              โ† ๊ด€๋ฆฌ์ž ์•ฑ
  packages/
    ui/                 โ† @youngsoo/ui ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ
    utils/              โ† @youngsoo/utils ๊ณต์œ  ์œ ํ‹ธ

workspaces ์— ๋Œ€ํ•œ ์ƒ์„ธ ๋‚ด์šฉ์€ ๋ณ„๋„ ๊ฐ€์ด๋“œ์—์„œ ๋‹ค๋ฃฌ๋‹ค.


๐Ÿ ์ด๋ฒˆ์— ๋ฐฐ์šด ๋‚ด์šฉ ์ด์ •๋ฆฌ

ํ•„๋“œ๋ชฉ์ Next.js ์•ฑ ํ•„์ˆ˜ ์—ฌ๋ถ€
"private": true์‹ค์ˆ˜๋กœ npm publish ๋ฐฉ์ง€โœ… ํ•„์ˆ˜
"engines"ํŒ€ Node.js ๋ฒ„์ „ ๊ฐ•์ œโœ… ๊ถŒ์žฅ
"browserslist"์ง€์› ๋ธŒ๋ผ์šฐ์ € ์„ ์–ธ๐Ÿ”ถ ๊ถŒ์žฅ
"exports"๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ง„์ž…์  + Tree Shaking๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ œ์ž‘ ์‹œ ํ•„์ˆ˜
"sideEffects"Tree Shaking ์ตœ์ ํ™” ํžŒํŠธ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ œ์ž‘ ์‹œ ํ•„์ˆ˜
"files"๋ฐฐํฌ ํŒŒ์ผ ๋ฒ”์œ„ ์ œ์–ด๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ๋ฐฐํฌ ์‹œ
"type"CommonJS vs ESM ์ „ํ™˜๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ œ์ž‘ ์‹œ

๐Ÿ“ ๋งˆ๋ฌด๋ฆฌ ํ€ด์ฆˆ

Q1. "private": true ํ•„๋“œ์˜ ์—ญํ• ์€?

a) ํŒจํ‚ค์ง€๋ฅผ ๋น„๋ฐ€๋ฒˆํ˜ธ๋กœ ๋ณดํ˜ธํ•œ๋‹ค
b) npm publish ๋ช…๋ น ์‹คํ–‰ ์‹œ ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ์— ์—…๋กœ๋“œ๋˜๋Š” ๊ฒƒ์„ ๋ง‰๋Š”๋‹ค
c) node_modules ํด๋”๋ฅผ ์ˆจ๊ธด๋‹ค
d) ํŒ€์›์ด ํŒจํ‚ค์ง€๋ฅผ ์„ค์น˜ํ•˜์ง€ ๋ชปํ•˜๊ฒŒ ๋ง‰๋Š”๋‹ค

โœ… ์ •๋‹ต: b โ€” npm publish ์‹คํ–‰์„ ๋ง‰๋Š”๋‹ค

๐Ÿ’ก ์ƒ์„ธ ํ•ด์„ค:

  • ์›๋ฆฌ ์„ค๋ช…: "private": true ๊ฐ€ ์žˆ์œผ๋ฉด npm publish ์‹คํ–‰ ์‹œ npm ERR! This package has been marked as private ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉฐ ์ค‘๋‹จ๋œ๋‹ค. ํšŒ์‚ฌ ๋‚ด๋ถ€ Next.js ์•ฑ์ด ์‹ค์ˆ˜๋กœ ๊ณต๊ฐœ ๋ ˆ์ง€์ŠคํŠธ๋ฆฌ์— ์˜ฌ๋ผ๊ฐ€๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€ํ•˜๋Š” ์•ˆ์ „์žฅ์น˜๋‹ค.
  • ์˜ค๋‹ต ํ”ผ๋“œ๋ฐฑ: a โ€” ๋น„๋ฐ€๋ฒˆํ˜ธ์™€ ๋ฌด๊ด€ํ•˜๋‹ค. c โ€” node_modules ๊ฐ€์‹œ์„ฑ๊ณผ ๋ฌด๊ด€ํ•˜๋‹ค. d โ€” ์„ค์น˜ ์ž์ฒด๋Š” ๋ง‰์ง€ ์•Š๋Š”๋‹ค.
  • ๐Ÿ“Œ ํ•ต์‹ฌ ๊ธฐ์–ต๋ฒ•: "private: true = ๊ณต๊ฐœ npm ์— ์˜ฌ๋ผ๊ฐ€์ง€ ์•Š๋Š”๋‹ค."

Q2. ์•„๋ž˜ ์ƒํ™ฉ์—์„œ sideEffects: false ๋ฅผ ์„ค์ •ํ–ˆ์„ ๋•Œ ์˜ฌ๋ฐ”๋ฅธ ๋™์ž‘์€?

// @youngsoo/ui ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—์„œ Button ๋งŒ import
import { Button } from '@youngsoo/ui'

a) ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ „์ฒด๊ฐ€ ๋ฒˆ๋“ค์— ํฌํ•จ๋œ๋‹ค
b) ๋ฒˆ๋“ค๋Ÿฌ๊ฐ€ Button ๊ด€๋ จ ์ฝ”๋“œ๋งŒ ๋ฒˆ๋“ค์— ํฌํ•จํ•˜๊ณ  ๋‚˜๋จธ์ง€๋Š” ์ œ์™ธํ•œ๋‹ค
c) import ๊ฐ€ ์‹คํŒจํ•˜๊ณ  ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค
d) ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์•„์˜ˆ ๋ฒˆ๋“ค์—์„œ ์ œ์™ธํ•œ๋‹ค

โœ… ์ •๋‹ต: b โ€” ๋ฒˆ๋“ค๋Ÿฌ๊ฐ€ Button ๊ด€๋ จ ์ฝ”๋“œ๋งŒ ํฌํ•จํ•œ๋‹ค

๐Ÿ’ก ์ƒ์„ธ ํ•ด์„ค:

  • ์›๋ฆฌ ์„ค๋ช…: sideEffects: false ๋Š” ๋ฒˆ๋“ค๋Ÿฌ์—๊ฒŒ "์ด ํŒจํ‚ค์ง€์˜ ํŒŒ์ผ๋“ค์€ import ํ•ด๋„ ์ „์—ญ ์ƒํƒœ๋ฅผ ๋ณ€๊ฒฝํ•˜๋Š” ๋ถ€์ž‘์šฉ์ด ์—†๋‹ค"๊ณ  ์•Œ๋ ค์ค€๋‹ค. ๋ฒˆ๋“ค๋Ÿฌ๋Š” ์ด ํžŒํŠธ๋ฅผ ๋ฐ›์•„ ์‹ค์ œ๋กœ ์‚ฌ์šฉ๋˜๋Š” Button ์ฝ”๋“œ๋งŒ ๋ฒˆ๋“ค์— ํฌํ•จํ•˜๊ณ , ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” Modal, Input ๋“ฑ์€ ์ œ์™ธ(Tree Shake)ํ•œ๋‹ค.
  • ์˜ค๋‹ต ํ”ผ๋“œ๋ฐฑ: a โ€” sideEffects: false ์—†์ด main ๋งŒ ์„ค์ •ํ–ˆ์„ ๋•Œ์˜ ๋™์ž‘์ด๋‹ค. c โ€” ์„ค์ •์ด ์žˆ์–ด๋„ import ๋Š” ์ •์ƒ ์ž‘๋™ํ•œ๋‹ค. d โ€” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์™„์ „ํžˆ ์ œ์™ธํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ ์‚ฌ์šฉํ•œ ๋ถ€๋ถ„๋งŒ ์„ ํƒ์ ์œผ๋กœ ํฌํ•จํ•œ๋‹ค.
  • ๐Ÿ“Œ ํ•ต์‹ฌ ๊ธฐ์–ต๋ฒ•: "sideEffects: false = ๋ฒˆ๋“ค๋Ÿฌ์—๊ฒŒ 'Tree Shake ํ•ด๋„ ์•ˆ์ „ํ•ด' ๋ผ๋Š” ์‹ ํ˜ธ."

Q3. ๐Ÿฃ ์˜์ฒ ์ด์˜ ํ…Œ์ŠคํŠธ ํƒ€์ž„ โ€” ๊ธด๊ธ‰ ๋””๋ฒ„๊น…

์˜์ˆ˜ PM ์ด ์Šฌ๋ž™์„ ๋ณด๋ƒˆ๋‹ค. "์˜์ฒ  ๋‹˜, @youngsoo/ui ์—์„œ ๋ฒ„ํŠผ ํ•˜๋‚˜๋งŒ ์“ฐ๋Š”๋ฐ Lighthouse ์—์„œ ๋ฒˆ๋“ค ์‚ฌ์ด์ฆˆ ๊ฒฝ๊ณ ๊ฐ€ ๊ณ„์† ๋‚˜์™€์š”. ๋ถ„์„ํ•ด๋ณด๋‹ˆ UI ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ „์ฒด๊ฐ€ ๋ฒˆ๋“ค์— ๋“ค์–ด์žˆ์–ด์š”. ์–ด๋–ป๊ฒŒ ๋œ ๊ฑด๊ฐ€์š”?"

์˜์ฒ ์ด๊ฐ€ @youngsoo/ui/package.json ์„ ๋ณด๋‹ˆ ์ด๋ ‡๊ฒŒ ๋˜์–ด์žˆ์—ˆ๋‹ค:

{
  "name": "@youngsoo/ui",
  "main": "./dist/index.js",
  "version": "1.0.0"
}

๋ฌธ์ œ์˜ ์›์ธ๊ณผ ์˜ฌ๋ฐ”๋ฅธ ์ˆ˜์ • ๋ฐฉ๋ฒ•์„ ์„ค๋ช…ํ•˜๋ผ.

โœ… ์ •๋‹ต: sideEffects ์™€ exports ๊ฐ€ ์—†์–ด์„œ Tree Shaking ์ด ๋ถˆ๊ฐ€๋Šฅํ–ˆ๋‹ค

{
  "name": "@youngsoo/ui",
  "version": "1.0.0",
  "main": "./dist/index.cjs.js",
  "module": "./dist/index.esm.js",
  "sideEffects": ["*.css"],
  "exports": {
    ".": {
      "import":  "./dist/index.esm.js",
      "require": "./dist/index.cjs.js",
      "types":   "./dist/index.d.ts"
    },
    "./button": {
      "import":  "./dist/button.esm.js",
      "require": "./dist/button.cjs.js",
      "types":   "./dist/button.d.ts"
    }
  }
}

๐Ÿ’ก ์ƒ์„ธ ํ•ด์„ค:

  • ์›์ธ: main ๋งŒ ์žˆ์œผ๋ฉด ๋ฒˆ๋“ค๋Ÿฌ๋Š” ./dist/index.js ๋ผ๋Š” ์ง„์ž…์  ํ•˜๋‚˜์—์„œ ๋ชจ๋“  ๊ฒƒ์„ export ํ•˜๋Š” ๊ตฌ์กฐ๋กœ ์ธ์‹ํ•œ๋‹ค. ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ์ฝ”๋“œ๊ฐ€ ์žˆ์–ด๋„ "๋ถ€์ž‘์šฉ์ด ์žˆ์„ ์ˆ˜ ์žˆ์œผ๋‹ˆ" ์ „๋ถ€ ํฌํ•จ์‹œํ‚จ๋‹ค.
  • sideEffects ํšจ๊ณผ: ๋ฒˆ๋“ค๋Ÿฌ์—๊ฒŒ "CSS ๋ฅผ ์ œ์™ธํ•œ ์ฝ”๋“œ์—๋Š” ๋ถ€์ž‘์šฉ์ด ์—†๋‹ค"๊ณ  ์•Œ๋ ค์ค˜ Tree Shaking ์„ ํ™œ์„ฑํ™”ํ•œ๋‹ค.
  • exports ํšจ๊ณผ: ์„œ๋ธŒ ๊ฒฝ๋กœ(./button)๋ฅผ ๋ช…์‹œํ•ด์ฃผ๋ฉด import { Button } from '@youngsoo/ui/button' ์œผ๋กœ ๋ฒ„ํŠผ ๋ฒˆ๋“ค๋งŒ ๋ช…์‹œ์ ์œผ๋กœ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ์–ด, ๋ฒˆ๋“ค๋Ÿฌ๊ฐ€ ๋” ์ •๋ฐ€ํ•˜๊ฒŒ ์ตœ์ ํ™”ํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ๐Ÿ“Œ ํ•ต์‹ฌ ๊ธฐ์–ต๋ฒ•: "๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ๋งŒ๋“ ๋‹ค๋ฉด: exports ๋กœ ์ง„์ž…์  ์„ค๊ณ„ + sideEffects: false ๋กœ Tree Shaking ํ—ˆ์šฉ = ์ตœ์ ํ™” ์™„์„ฑ."

๐Ÿฃ ์˜์ฒ ์ด์˜ ํ‡ด๊ทผ ์ผ๊ธฐ

์˜ค๋Š˜์€ ์ง€ํ•˜์ฒ  ํƒ€๊ธฐ ์ „์— ํšŒ์‚ฌ ๊ทผ์ฒ˜ ์นดํŽ˜์— ์ž ๊น ์•‰์•˜๋‹ค. ์ปคํ”ผ ํ•œ ์ž” ์‹œํ‚ค๊ณ  ์˜ค๋Š˜ ๋ฐฐ์šด ๊ฒƒ ๋จธ๋ฆฟ์†์—์„œ ์ •๋ฆฌํ•˜๋Š” ์ค‘.

package.json ์„ ๊ทธ๋ƒฅ "์ด๋ฆ„์ด๋ž‘ ๋ฒ„์ „ ์“ฐ๋Š” ํŒŒ์ผ" ๋กœ๋งŒ ์•Œ์•˜๋Š”๋ฐ, ์˜ค๋Š˜ ๋ณด๋‹ˆ๊นŒ ๋ฐฐํฌ ์‹ค์ˆ˜ ๋ฐฉ์ง€, ๋ฒˆ๋“ค ์ตœ์ ํ™”, ํŒ€ ํ™˜๊ฒฝ ํ†ต์ผ๊นŒ์ง€ ๋‹ค ์—ฌ๊ธฐ์„œ ์ถœ๋ฐœํ•˜๋Š” ๊ฑฐ์˜€๋‹ค. ํŠนํžˆ sideEffects: false ๋Š” ์ง„์งœ ๋ชฐ๋ž๋‹ค. ๋‚ด๊ฐ€ ๋งŒ๋“  @youngsoo/ui ์—์„œ ๋ฒ„ํŠผ ํ•˜๋‚˜๋งŒ ์“ฐ๋Š”๋ฐ 20๊ฐœ ์ปดํฌ๋„ŒํŠธ๊ฐ€ ๋‹ค ๋ฒˆ๋“ค์— ๋“ค์–ด๊ฐ„ ๊ฒŒ ๊ทธ๊ฒƒ ๋•Œ๋ฌธ์ด์—ˆ๊ตฌ๋‚˜. ์˜์ˆ˜ ๋‹˜์ด ๋ฒˆ๋“ค ์‚ฌ์ด์ฆˆ ์–˜๊ธฐํ•  ๋•Œ ์‚ด์ง ์‹์€๋•€ ๋‚ฌ๋‹ค.

๐Ÿ’ก ์˜ค๋Š˜์˜ ๊ตํ›ˆ: "package.json ์€ ํ”„๋กœ์ ํŠธ์˜ ๊ณ„์•ฝ์„œ๋‹ค. private, engines, exports, sideEffects โ€” ์ด ๋„ค ๊ฐœ๋ฅผ ์ฑ™๊ธฐ๋Š” ๊ฒƒ์ด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์ œ๋Œ€๋กœ ๋งŒ๋“œ๋Š” ์‹œ์ž‘์ด๋‹ค."

๊ทธ๋‚˜์ €๋‚˜ exports ํ•„๋“œ ์„ค์ •ํ•˜๊ณ  ๋‚˜์„œ ๋ฒˆ๋“ค ์‚ฌ์ด์ฆˆ๊ฐ€ ํ™• ์ค„์—ˆ๋‹ค. ๊ดœํžˆ ๋ฟŒ๋“ฏํ•˜๋‹ค. ์˜์ˆ™ ๋‹˜์ด ๋‹ค์Œ์—” ์ข€ ๋น ๋ฅด๋‹ค๊ณ  ํ•  ๊ฒƒ ๊ฐ™์€๋ฐ... ํ—ฌ์Šค์žฅ ๊ฐ€์•ผ์ง€, ๋นก์„ธ๊ฒŒ ํ•˜๋ฃจ ๋ณด๋ƒˆ์œผ๋‹ˆ๊นŒ.


๐Ÿ”— ๋” ์•Œ์•„๋ณด๊ธฐ