Yarn

Yarn์€ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ ํŒจํ‚ค์ง€ ๋งค๋‹ˆ์ €๋‹ค. Yarn์€ npm์— ๋Œ€ํ•œ ๋น„ํŒ์œผ๋กœ๋ถ€ํ„ฐ ์ถœ๋ฐœํ–ˆ๋‹ค. 2017๋…„ ๋ฆด๋ฆฌ์ฆˆ๋œ Yarn 1์€ yarn.lock ํŒŒ์ผ์„ ์ด์šฉํ•œ ์ข…์†์„ฑ ํŠธ๋ฆฌ ๊ณ ์ •, ์บ์‹œ๋ฅผ ํ†ตํ•œ ์†๋„ ํ–ฅ์ƒ ๋“ฑ npm๋ณด๋‹ค ๊ฐœ์„ ๋œ ํŒจํ‚ค์ง€ ๊ด€๋ฆฌ ํ™˜๊ฒฝ์„ ์ œ๊ณตํ–ˆ๋‹ค. ์ดํ›„ 2020๋…„ ๋ฆด๋ฆฌ์ฆˆ๋œ Yarn 2๋Š” Berry ๋˜๋Š” Yarn Berry๋กœ ๋ถˆ๋ฆฌ๋ฉฐ, Plugโ€™nโ€™Play(PnP) ์•„ํ‚คํ…์ฒ˜๋ฅผ ๋„์ž…ํ•ด node_modules ๋””๋ ‰ํ† ๋ฆฌ๋ฅผ ์ œ๊ฑฐํ•˜๊ณ , ๊ฐ ์˜์กด์„ฑ์˜ ์œ„์น˜์™€ ๋ฒ„์ „์„ .pnp.js ํŒŒ์ผ๋กœ ์ถ”์ ํ•จ์œผ๋กœ์จ ๋”์šฑ ๋น ๋ฅธ ์„ฑ๋Šฅ์„ ๋‹ฌ์„ฑํ•œ๋‹ค.

Workspaces

์›Œํฌ์ŠคํŽ˜์ด์Šค๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ํ•˜๋‚˜์˜ ํ”„๋กœ์ ํŠธ ๋‚ด์—์„œ ์—ฌ๋Ÿฌ ํŒจํ‚ค์ง€๋ฅผ ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๋‹ค. ํŠนํžˆ ์ด๋Š” ๋ชจ๋…ธ๋ ˆํฌ์—์„œ ๋งค์šฐ ์œ ์šฉํ•˜๋‹ค. ๋ชจ๋…ธ๋ ˆํฌ์˜ ํŒจํ‚ค์ง€๋Š” ์„œ๋กœ ์ข…์†๋˜์–ด์•ผ ํ•˜๋Š” ์ƒํ™ฉ์ด ๋งŽ์€๋ฐ, ๊ฐ€๋ น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ํŒจํ‚ค์ง€(app)๊ฐ€ ๊ฐ™์€ ์ €์žฅ์†Œ์— ์žˆ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ํŒจํ‚ค์ง€(utils)๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ์žˆ๋‹ค. ์ด๋•Œ Yarn์€ ํ”„๋กœ์ ํŠธ์—์„œ ์›Œํฌ์ŠคํŽ˜์ด์Šค๋ฅผ ์‚ฌ์šฉํ•ด ์˜์กด์„ฑ์„ ์ฐพ์„ ์ˆ˜ ์ž‡๋‹ค.

{
  "name": "app",
  "dependencies": {
    "utils": "workspace:^"
  }
}

yarn workspaces focus ๋ช…๋ น์„ ์‚ฌ์šฉํ•˜๋ฉด ํŠน์ • ์›Œํฌ์ŠคํŽ˜์ด์Šค์—๋งŒ ์˜์กด์„ฑ์„ ์„ค์น˜ํ•  ์ˆ˜ ์žˆ๋‹ค. ๋˜ํ•œ yarn workspaces foreach ๋ช…๋ น์„ ์‚ฌ์šฉํ•˜๋ฉด ์—ฌ๋Ÿฌ ์›Œํฌ์ŠคํŽ˜์ด์Šค์—์„œ ๋ช…๋ น์„ ๋ณ‘๋ ฌ๋กœ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋‹ค.

Constraints

์ œ์•ฝ์„ ์‚ฌ์šฉํ•˜๋ฉด ์›Œํฌ์ŠคํŽ˜์ด์Šค์— ํŠน์ • ๊ทœ์น™์„ ์ ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. ๊ฐ€๋ น ๋™์ผํ•œ ๋ฒ„์ „์˜ ์˜์กด์„ฑ์„ ๋ณด์žฅํ•˜๊ฑฐ๋‚˜, ํŠน์ • ์˜์กด์„ฑ ์‚ฌ์šฉ์„ ๊ธˆ์ง€ํ•  ์ˆ˜ ์žˆ๋‹ค. ์ œ์•ฝ์€ ํ”„๋กœ์ ํŠธ์˜ ๋ฃจํŠธ์— yarn.config.cjs ํŒŒ์ผ์„ ๋งŒ๋“ค์–ด ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋‹ค. ๋งŒ์•ฝ ๋ชจ๋“  react ์˜์กด์„ฑ์„ 18.0.0์œผ๋กœ ์„ค์ •๋˜๋„๋ก ๊ฐ•์ œํ•˜๋ ค๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ž‘์„ฑํ•œ๋‹ค.

module.exports = {
  async constraints({Yarn}) {
    for (const dep of Yarn.dependencies({ ident: 'react' })) {
      dep.update(`18.0.0`);
    }
  },
};

Plugโ€™nโ€™Play

Yarn PnP ํ”„๋กœ์ ํŠธ์—๋Š” node_modules ๋””๋ ‰ํ† ๋ฆฌ๊ฐ€ ์—†๋‹ค. ๋Œ€์‹  pnp.cjs์ด๋ผ๋Š” ๋กœ๋” ํŒŒ์ผ์ด ์žˆ๋‹ค. ์ด ๋กœ๋” ํŒŒ์ผ์—๋Š” ํŒจํ‚ค์ง€์˜ ์œ„์น˜๋ฅผ ๋น„๋กฏํ•œ ํ”„๋กœ์ ํŠธ์˜ ์˜์กด์„ฑ ํŠธ๋ฆฌ์— ๊ด€ํ•œ ๋ชจ๋“  ์ •๋ณด๊ฐ€ ํฌํ•จ๋˜์–ด์žˆ๋‹ค.

/* react ํŒจํ‚ค์ง€ ์ค‘์—์„œ */
["react", [
  /* npm:18.2.0 ๋ฒ„์ „์€ */
  ["npm:18.2.0", {
    /* ์ด ์œ„์น˜์— ์žˆ๊ณ  */
    "packageLocation": "./.yarn/cache/react-npm-18.2.0-98658812fc-a76d86ec97.zip/node_modules/react/",
    /* ์ด ์˜์กด์„ฑ๋“ค์„ ์ฐธ์กฐํ•œ๋‹ค. */
ย ย ย ย "packageDependencies": [
      ["loose-envify", "npm:1.4.0"]
    ],
  }]
]],

Yarn PnP ํ”„๋กœ์ ํŠธ์— ํŒจํ‚ค์ง€๋ฅผ ์„ค์น˜ํ•˜๋Š” yarn add ๋ช…๋ น์„ ์‹คํ–‰ํ•˜๋ฉด ์ฒซ ๋ฒˆ์งธ๋กœ ์˜์กด์„ฑ์˜ ๋ฒ„์ „์„ ๊ณ ์ •ํ•˜๋Š” Resolution ๋‹จ๊ณ„๋ฅผ ๊ฑฐ์นœ๋‹ค. ์ด ๋‹จ๊ณ„์—์„œ๋Š” ์šฐ์„  package.json ํŒŒ์ผ์— ๋ช…์‹œ๋œ ์˜์กด์„ฑ์˜ ๋ฒ„์ „ ๋ฒ”์œ„์— ๋”ฐ๋ผ ์ •ํ™•ํ•œ ๋ฒ„์ „์„ ๊ฒฐ์ •ํ•œ๋‹ค. ์ด์–ด์„œ ์˜์กด์„ฑ์ด ์˜์กดํ•˜๋Š” ๋˜๋‹ค๋ฅธ ์˜์กด์„ฑ์„ ์ฐพ์•„๋‚ด๊ณ , ์ด๋“ค์˜ ๋ฒ„์ „ ์—ญ์‹œ ๊ณ ์ •ํ•จ์œผ๋กœ์จ ๋ชจ๋“  ๋จธ์‹ ์—์„œ ํ•ญ์ƒ ๊ณ ์ •๋œ ๋ฒ„์ „์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•œ๋‹ค. ์ด ๊ฒฐ๊ณผ๋Š” yarn.lock ํŒŒ์ผ์— ์ €์žฅ๋œ๋‹ค.

๋‘ ๋ฒˆ์งธ๋Š” Fetch ๋‹จ๊ณ„๋กœ, Resolution ๋‹จ๊ณ„์—์„œ ๊ฒฐ์ •๋œ ๋ฒ„์ „์˜ ์˜์กด์„ฑ์„ ๋„คํŠธ์›Œํฌ๋ฅผ ํ†ตํ•ด ๋‹ค์šด๋กœ๋“œ๋ฐ›๋Š”๋‹ค. ๋งˆ์ง€๋ง‰์€ Fetch ๋‹จ๊ณ„์—์„œ ๋ฐ›์€ ์˜์กด์„ฑ์„ ์†Œ์Šค์ฝ”๋“œ์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ํ™˜๊ฒฝ์„ ์ œ๊ณตํ•˜๋Š” Link ๋‹จ๊ณ„๋‹ค. npm์˜ ๊ฒฝ์šฐ ๋‹จ์ˆœํžˆ ๋ชจ๋“  ์˜์กด์„ฑ์„ node_modules ๋””๋ ‰ํ† ๋ฆฌ ์•„๋ž˜์— ์„ค์น˜ํ•œ๋‹ค. ๋ฐ˜๋ฉด Yarn PnP๋Š” ์ƒ์ˆ ํ–ˆ๋“ฏ์ด, node_modules ๋””๋ ‰ํ† ๋ฆฌ๋ฅผ ์ˆœํšŒํ•˜์ง€ ์•Š๊ณ  โ€˜์˜์กด์„ฑ์„ ์–ด๋–ค ํŒŒ์ผ์—์„œ importํ•˜๋Š”์ง€, ๊ทธ๋ฆฌ๊ณ  ๋ฌด์—‡์„ importํ•˜๋Š”์ง€โ€™ ์ถ”์ ํ•œ๋‹ค. ์ด๋ ‡๊ฒŒ ์ถ”์ ํ•œ ์ •๋ณด๋Š” ์œ„์™€ ๊ฐ™์ด .pnp.js ํŒŒ์ผ์— ์ €์žฅํ•ด๋‘”๋‹ค.

Yarn PnP ํ”„๋กœ์ ํŠธ๋ฅผ ์‹คํ–‰ํ•˜๋ฉด Node.js ํ”„๋กœ์„ธ์Šค๋Š” .pnp.cjs ํŒŒ์ผ์„ ๋ฐ”ํƒ•์œผ๋กœ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ Map ๊ฐ์ฒด(PnP Map)๋ฅผ ๋งŒ๋“ค์–ด ๋ฉ”๋ชจ๋ฆฌ์— ์ „๋ถ€ ๋กœ๋“œํ•˜๊ณ , import์™€ require ๊ตฌ๋ฌธ์—์„œ ์ด๋ฅผ ์ฐธ์กฐํ•œ๋‹ค. npm์ด๋‚˜ pnpm๊ณผ ๊ฐ™์€ ํŒจํ‚ค์ง€ ๋งค๋‹ˆ์ €๋“ค์€ ๋Œ€๋ถ€๋ถ„์˜ ์‹œ๊ฐ„์„ ํŒŒ์ผ I/O์— ์†Œ๋ชจํ•˜์ง€๋งŒ, Yarn PnP๋Š” ์˜์กด์„ฑ์„ PnP Map์œผ๋กœ ๊ด€๋ฆฌํ•˜๊ธฐ ๋•Œ๋ฌธ์— ํŒŒ์ผ I/O ์—ฐ์‚ฐ์„ ํš๊ธฐ์ ์œผ๋กœ ์ค„์ผ ์ˆ˜ ์žˆ๋‹ค. ๋”ฐ๋ผ์„œ ์ผ๋‹จ ์ฒ˜์Œ์— ๋ฉ”๋ชจ๋ฆฌ์— PnP Map์„ ๋กœ๋“œํ•˜๊ณ  ๋‚˜๋ฉด ์ดํ›„๋กœ๋Š” node_modules ๋””๋ ‰ํ† ๋ฆฌ๋ฅผ ์ˆœํšŒํ•  ํ•„์š”์—†์ด ๋ฉ”๋ชจ๋ฆฌ์—์„œ Map ์—ฐ์‚ฐ๋งŒ ์ˆ˜ํ–‰ํ•˜๋ฉด ๋˜๊ธฐ ๋•Œ๋ฌธ์— ์†๋„๊ฐ€ ๊ต‰์žฅํžˆ ๋น ๋ฅด๋‹ค.

์ฐธ๊ณ ์ž๋ฃŒ

์ด ๋ฌธ์„œ๋ฅผ ์ธ์šฉํ•œ ๋ฌธ์„œ