Skip to content

How we make npm packages work in the browser

Woo HyeJu edited this page Nov 12, 2019 · 1 revision
2017.10.6 - โœ๏ธIves van Hoorne

CodeSandbox์˜ ์ดˆ๊ธฐ ๊ฐœ๋ฐœ ๊ณผ์ •์—์„œ๋Š” ํ•ญ์ƒ npm ์˜์กด์„ฑ ์ง€์› ๋ฒ”์œ„๋ฅผ ๋ฒ—์–ด๋‚ฌ๋‹ค. ๋ธŒ๋ผ์šฐ์ €์— ์ž„์˜์˜, ๋žœ๋คํ•œ ์–‘์˜ ํŒจํ‚ค์ง€๋ฅผ ์„ค์น˜ํ•˜๋Š” ๊ฒƒ์ด ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค๊ณ  ์ƒ๊ฐํ–ˆ์œผ๋ฉฐ ์‹ฌ์ง€์–ด ๋‚ด ๋‡Œ๊ฐ€ ๋ง‰ํ˜”๋‹ค๊ณ  ์ƒ๊ฐํ–ˆ๋‹ค.

์š”์ฆ˜ npm ์ง€์›์€ CodeSandbox์˜ ๊ฐ€์žฅ ์ •์˜ ๋œ ๊ธฐ๋Šฅ ์ค‘ ํ•˜๋‚˜๋กœ, ์–ด๋–ป๊ฒŒ๋“  ์ž‘๋™ ํ•  ์ˆ˜ ์žˆ๋‹ค. ๋ชจ๋“  ์‹œ๋‚˜๋ฆฌ์˜ค์—์„œ ์ž‘๋™ํ•˜๋ ค๋ฉด ๋งŽ์€ ๋ฐ˜๋ณต์ด ํ•„์š”ํ–ˆ๊ณ , ์—ฌ๋Ÿฌ ๋ฒˆ ๋‹ค์‹œ ์ž‘์„ฑํ–ˆ์œผ๋ฉฐ ์‹ฌ์ง€์–ด ์ด์ œ๋Š” ๋…ผ๋ฆฌ๋ฅผ ๊ฐœ์„  ํ•  ์ˆ˜ ์žˆ๋‹ค. ํ˜„์žฌ ๊ฐ€์ง„ ๊ธฐ๋Šฅ๊ณผ ๊ทธ๊ฒƒ์„ ๊ฐœ์„ ํ•˜๊ธฐ ์œ„ํ•ด ์—ฌ์ „ํžˆ ํ•  ์ˆ˜ ์žˆ๋Š” ์ž‘์—…, ๊ทธ๋ฆฌ๊ณ  npm ์ง€์›์ด ์‹œ์ž‘๋œ ๋ฐฉ๋ฒ•์„ ์„ค๋ช…ํ•˜๊ฒ ๋‹ค.

'First' Version

๋‚˜๋Š” npm ์˜์กด์„ฑ์— ์ ‘๊ทผํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์ •๋ง๋กœ ๋ชฐ๋ž๊ธฐ ๋•Œ๋ฌธ์—, ๋งค์šฐ ๊ฐ„๋‹จํ•œ npm ์ง€์› ๋ฒ„์ „์œผ๋กœ ์‹œ์ž‘ํ–ˆ๋‹ค.

์ด ๋ฒ„์ „์˜ npm ์ง€์›์€ ๋งค์šฐ ๊ฐ„๋‹จํ–ˆ๋‹ค. ์‹ค์ œ๋กœ npm์„ ์ง€์›ํ•˜์ง€๋Š” ์•Š์•˜์œผ๋ฏ€๋กœ ์˜์กด์„ฑ์„ ๋กœ์ปฌ๋กœ ์„ค์น˜ํ•˜๊ณ , ๋ชจ๋“  ์˜์กด์„ฑ ํ˜ธ์ถœ์„ ์ด๋ฏธ ์„ค์น˜๋œ ์˜์กด์„ฑ์œผ๋กœ stub ํ–ˆ๋‹ค. ๋ฌผ๋ก  ์ด๊ฒƒ์€ ๋‹ค๋ฅธ ๋ฒ„์ „์˜ 400,000๊ฐ€์ง€์˜ ํŒจํ‚ค์ง€๋กœ ํ™•์žฅ ํ•  ์ˆ˜๋Š” ์—†์—ˆ๋‹ค.

์ด ๋ฒ„์ „์€ ๊ทธ๋‹ค์ง€ ์œ ์šฉํ•˜์ง€๋Š” ์•Š์•˜์ง€๋งŒ, ํ”„๋กœ์ ํŠธ ํ™˜๊ฒฝ์—์„œ ์ ์–ด๋„ ๋‘ ๊ฐ€์ง€์˜ ์˜์กด์„ฑ์„ ์ž‘๋™์‹œํ‚ฌ ์ˆ˜ ์žˆ์Œ์„ ์•Œ๊ฒŒ๋˜์—ˆ๋‹ค.

webpack Version

์‚ฌ์‹ค ์ฒซ ๋ฒˆ์งธ ๋ฒ„์ „์— ๋งค์šฐ ๋งŒ์กฑํ–ˆ์œผ๋ฉฐ MVP(CodeSandbox์˜ ์ฒซ ๋ฒˆ์งธ ๋ฆด๋ฆฌ์Šค)์—๋Š” ์ถฉ๋ถ„ํ•˜๋‹ค๊ณ  ์ƒ๊ฐํ–ˆ๋‹ค. https://esnextb.in ์„ ์šฐ์—ฐํžˆ ๋ฐœ๊ฒฌํ•˜๊ธฐ ์ „ ๊นŒ์ง€๋Š” ๋งˆ๋ฒ•์„ ๋ถ€๋ฆฌ์ง€ ์•Š๊ณ ์„œ๋Š” ์˜์กด์„ฑ์„ ์„ค์น˜ํ•˜๋Š” ๊ฒƒ์€ ๊ฐ€๋Šฅํ•  ๊ฒƒ์ด๋ผ๊ณ  ์ƒ๊ฐํ•˜์ง€ ์•Š์•˜๋‹ค. ๊ทธ๋“ค์€ ์ด๋ฏธ npm์˜ ๋ชจ๋“  ์ข…์†์„ฑ์„ ์ง€์›ํ–ˆ๊ณ , ์‚ฌ์šฉ์ž๊ฐ€ package.json ์—์„œ ์ •์˜ํ•˜๋ฉด ๋งˆ์ˆ ์ฒ˜๋Ÿผ ์ž‘๋™ํ–ˆ๋‹ค.

์ด๊ฒƒ์€ ๋‚˜์—๊ฒŒ ํฐ ํ•™์Šต ์ˆœ๊ฐ„์ด์—ˆ๋‹ค. ๋‚˜๋Š” ๊ทธ๊ฒƒ์ด ๋ถˆ๊ฐ€๋Šฅํ•˜๋‹ค ๊ณ  ์ƒ๊ฐํ–ˆ๊ธฐ ๋•Œ๋ฌธ์—, ์ ์ ˆํ•œ npm ์ง€์›์„ ์ƒ๊ฐ๋„ ํ•˜์ง€์•Š์•˜๋‹ค. ๊ฐ€๋Šฅ์„ฑ ์— ๋Œ€ํ•œ ์‚ด์•„์žˆ๋Š” ์ฆ๊ฑฐ๋ฅผ ๋ณธ ํ›„์—์•ผ ๋” ๊นŠ์ด ์ƒ๊ฐํ•˜๊ธฐ ์‹œ์ž‘ํ–ˆ๋‹ค. ์•„์ด๋””์–ด๋ฅผ ๊ธฐ๊ฐํ•˜๊ธฐ ์ „์—, ๋จผ์ € ๊ฐ€๋Šฅ์„ฑ์„ ์‚ดํŽด ๋ดค์–ด์•ผํ•œ๋‹ค.

๊ทธ๋ž˜์„œ, ๋‚˜๋Š” ์ด๊ฒƒ์— ์ ‘๊ทผํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ์ƒ๊ฐํ•˜๊ธฐ ์‹œ์ž‘ํ–ˆ๋‹ค. ๋‚˜๋Š” ๊ทธ๊ฒƒ์„ ๋„ˆ๋ฌด ๋ณต์žกํ•˜๊ฒŒ ์ƒ๊ฐํ–ˆ๋‹ค. ์ฒซ ๋ฒˆ์งธ ๋ฒ„์ „์€ ๋‚ด ๋จธ๋ฆฌ๋กœ๋Š” ๋ถˆ๊ฐ€๋Šฅ ํ–ˆ์œผ๋ฏ€๋กœ ๋‹ค์ด์–ด๊ทธ๋žจ์„ ๊ทธ๋ ค์•ผํ–ˆ๋‹ค.

์ด ์ง€๋‚˜์น˜๊ฒŒ ๋ณต์žกํ•œ ์ ‘๊ทผ๋ฒ•์˜ ํ•œ ๊ฐ€์ง€ ์žฅ์ ์ด ์žˆ์—ˆ๋‹ค. ์‹ค์ œ ๊ตฌํ˜„์€ ์˜ˆ์ƒ๋ณด๋‹ค ํ›จ์”ฌ ์‰ฌ์› ๋‹ค.

webpack ์˜ DllPlugin ์ด ์˜์กด์„ฑ์„ bundle ํ•˜๊ณ , JS ๋ฒˆ๋“ค์„ manifest ๋กœ ๋ฑ‰์–ด ๋‚ผ ์ˆ˜ ์žˆ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๊ฒŒ๋˜์—ˆ๋‹ค. ์ด manifest ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

{
  "name": "dll_bundle",
  "content": {
    "./node_modules/fbjs/lib/emptyFunction.js": 0,
    "./node_modules/fbjs/lib/invariant.js": 1,
    "./node_modules/fbjs/lib/warning.js": 2,
    "./node_modules/react": 3,
    "./node_modules/fbjs/lib/emptyObject.js": 4,
    "./node_modules/object-assign/index.js": 5,
    "./node_modules/prop-types/checkPropTypes.js": 6,
    "./node_modules/prop-types/lib/ReactPropTypesSecret.js": 7,
    "./node_modules/react/cjs/react.development.js": 8
  }
}

๋ชจ๋“  ๊ฒฝ๋กœ๋Š” module id ์— ๋งคํ•‘๋œ๋‹ค. React๊ฐ€ ํ•„์š”ํ•œ ๊ฒฝ์šฐ dll_bundle (3) - ์ฆ‰, ./node_modules/react ๋งŒ ํ˜ธ์ถœํ•˜๋ฉด React๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ๋‹ค. ์ด๊ฒƒ์€ ์šฐ๋ฆฌ์˜ use case ์— ์™„๋ฒฝํ–ˆ๊ธฐ ๋•Œ๋ฌธ์—, ์ž…๋ ฅ์„ ์‹œ์ž‘ํ•˜๊ณ  ์ด ์‹ค์ œ ์‹œ์Šคํ…œ์„ ์ƒ๊ฐํ•ด๋ƒˆ๋‹ค.

packager ์— ๋Œ€ํ•œ ๋ชจ๋“  ์š”์ฒญ์— ๋Œ€ํ•ด /tmp/:hash ์— ์ƒˆ ๋””๋ ‰ํ† ๋ฆฌ๋ฅผ ์ž‘์„ฑํ•˜๊ณ , yarn add $ {dependencyList} ๋ฅผ ์‹คํ–‰ํ•œ ๋‹ค์Œ, webpack bundle ์„ ๋‚˜์ค‘์— ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค. ๋‚˜๋Š” ์บ์‹ฑ ๋ฐฉ๋ฒ•์œผ๋กœ ์ƒˆ ๋ฒˆ๋“ค์„ gcloud ์— ์ €์žฅํ•œ๋‹ค. ์ฃผ๋กœ ์˜์กด์„ฑ ์„ค์น˜๋ฅผ yarn ์œผ๋กœ ๋Œ€์ฒดํ•˜๊ณ  webpack ์œผ๋กœ bundling ํ•˜๊ธฐ ๋•Œ๋ฌธ์—, ๋‹ค์ด์–ด๊ทธ๋žจ๋ณด๋‹ค ํ›จ์”ฌ ๊ฐ„๋‹จํ•˜๋‹ค.

ํ”„๋กœ์ ํŠธ๋ฅผ load ํ•  ๋•Œ, ๋จผ์ € evaluation ์ „์— manifest ์™€ bundle ์ด ์žˆ๋Š”์ง€ ํ™•์ธํ•œ๋‹ค. evaluation ํ•˜๋Š” ๋™์•ˆ ๋ชจ๋“  ์˜์กด์„ฑ์— ๋Œ€ํ•ด dll_bundle (id) ๋ฅผ ํ˜ธ์ถœํ•œ๋‹ค. ์ด๊ฒƒ์€ ๋งค์šฐ ์ž˜ ์ž‘๋™ํ–ˆ์œผ๋ฉฐ, ์ ์ ˆํ•œ npm ์˜์กด์„ฑ์ด์žˆ๋Š” ์ฒซ ๋ฒˆ์งธ ๋ฒ„์ „์ด ๋˜์—ˆ๋‹ค.

์ด ์‹œ์Šคํ…œ์—๋Š” ์—ฌ์ „ํžˆ ํฐ ํ•œ๊ณ„๊ฐ€ ์žˆ์—ˆ๋‹ค. webpack ์˜ ์˜์กด์„ฑ ๊ทธ๋ž˜ํ”„์— ์—†๋Š” ๋ชจ๋“ˆ์€ ์ง€์›ํ•˜์ง€ ์•Š์•˜๋‹ค. ์ฒ˜์Œ์—๋Š” ์˜์กด์„ฑ์˜ entry point ์ด ํ•„์š”ํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ์˜ˆ๋ฅผ ๋“ค์–ด, require ( 'react-icons / lib / fa / fa-beer') ์™€ ๊ฐ™์€ ๊ฒƒ์ด ์ž‘๋™ํ•˜์ง€ ์•Š๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•œ๋‹ค.

๋‚˜๋Š” ์ด ๋ฒ„์ „์œผ๋กœ CodeSandbox๋ฅผ ๋ฐฐํฌํ–ˆ์œผ๋ฉฐ, WebpackBin Christian Alfoni ์˜ ์ €์ž์™€ ์—ฐ๋ฝํ–ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” npm ์˜์กด์„ฑ์„ ์ง€์›ํ•˜๊ธฐ ์œ„ํ•ด ๋งค์šฐ ์œ ์‚ฌํ•œ ์‹œ์Šคํ…œ์„ ์‚ฌ์šฉํ–ˆ์œผ๋ฉฐ ๋™์ผํ•œ ํ•œ๊ณ„๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์—ˆ๋‹ค. ๊ทธ๋ž˜์„œ ์šฐ๋ฆฌ๋Š” ํž˜์„ ํ•ฉ์ณ ๊ถ๊ทน์ ์ธ pacakger ๋ฅผ ๋งŒ๋“ค๊ธฐ๋กœ ๊ฒฐ์ •ํ–ˆ๋‹ค.

webpack with entries

Christian์ด ์ค‘์š”๋„์— ๋”ฐ๋ผ ๋ฒˆ๋“ค์— ํŒŒ์ผ์„ ์ถ”๊ฐ€ํ•˜๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์ƒ์„ฑ ํ•œ ๊ฒƒ์„ ์ œ์™ธํ•˜๊ณ ๋Š”, ๊ถ๊ทน์ ์ธ ํŒจํ‚ค์ง€ ํ”„๋กœ๊ทธ๋žจ์€ ์ด์ „ ํŒจํ‚ค์ง€ ํ”„๋กœ๊ทธ๋žจ๊ณผ ๋™์ผํ•œ ๊ธฐ๋Šฅ์„ ์œ ์ง€ํ–ˆ๋‹ค. ์ด๋Š” webpack ์ด ํ•ด๋‹น ํŒŒ์ผ๋“ค๋„ bundle ๋กœ ์ œ๊ณตํ•  ์ˆ˜ ์žˆ๋„๋ก entry potin ๋ฅผ ์ˆ˜๋™์œผ๋กœ ์ถ”๊ฐ€ํ–ˆ์Œ์„ ์˜๋ฏธํ•œ๋‹ค. ์ด ์‹œ์Šคํ…œ์„ ๋งŽ์ด ์กฐ์ • ํ•œ ํ›„์—๋Š” ๋ชจ๋“ (?) ์กฐํ•ฉ์—์„œ ์ž‘๋™ํ•˜๊ฒŒ ๋˜์—ˆ๋‹ค. ๋”ฐ๋ผ์„œ react-icons์™€ CSS ํŒŒ์ผ๋„ ์ž‘๋™ํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค ๐ŸŽ‰.

์ƒˆ๋กœ์šด ์‹œ์Šคํ…œ์—๋Š” ๋˜ํ•œ ์•„ํ‚คํ…์ฒ˜ ์—…๊ทธ๋ ˆ์ด๋“œ๊ฐ€ ์žˆ์—ˆ๋‹ค. load balancer ๋ฐ ์บ์‹œ ์—ญํ• ์„ํ•˜๋Š” DLL ์„œ๋น„์Šค ๊ฐ€ ํ•˜๋‚˜ ์žˆ๋‹ค. ๊ทธ ๋‹ค์Œ, ๋ฒˆ๋“ค๋ง์„ ์ˆ˜ํ–‰ํ•˜๋Š” ์—ฌ๋Ÿฌ ํŒจํ‚ค์ง€ ๊ด€๋ฆฌ์ž(packager) ๊ฐ€ ์žˆ์œผ๋ฉฐ, ์ด ํŒจํ‚ค์ง€ ๊ด€๋ฆฌ์ž๋ฅผ ๋™์ ์œผ๋กœ ์ถ”๊ฐ€ ํ•  ์ˆ˜ ์žˆ๋‹ค.

์šฐ๋ฆฌ๋Š” ๋ชจ๋“  ์‚ฌ๋žŒ์ด packager service ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋กํ•˜๊ณ ์žํ–ˆ๋‹ค. ๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— ์„œ๋น„์Šค ์ž‘๋™ ๋ฐฉ์‹๊ณผ ์„œ๋น„์Šค ํ™œ์šฉ ๋ฐฉ๋ฒ•์„ ์„ค๋ช…ํ•˜๋Š” ์›น ์‚ฌ์ดํŠธ๋ฅผ ๊ตฌ์ถ•ํ–ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” codePen ๋ธ”๋กœ๊ทธ ์—์„œ๋„ ์–ธ๊ธ‰๋˜๋‹ค!

์ด ๊ถ๊ทน์ ์ธ ํŒจํ‚ค์ง€ ํ”„๋กœ๊ทธ๋žจ์—๋Š” ์—ฌ์ „ํžˆ ๋ช‡ ๊ฐ€์ง€ ์ œํ•œ๊ณผ ๋‹จ์ ์ด ์žˆ๋‹ค. ์ธ๊ธฐ๊ฐ€ ๋†’์•„์ง€๋ฉด์„œ ๋น„์šฉ์ด ๊ธฐํ•˜ ๊ธ‰์ˆ˜์ ์œผ๋กœ ์ฆ๊ฐ€ํ–ˆ์œผ๋ฉฐ, ํŒจํ‚ค์ง€ ์กฐํ•ฉ์„ ํ†ตํ•ด ์บ์‹ฑํ•˜๊ณ  ์žˆ์—ˆ๋‹ค. ์ด๊ฒƒ์€ ์˜์กด์„ฑ(๋ชจ๋“ˆ) ์„ ์ถ”๊ฐ€ ํ•œ ๊ฒฝ์šฐ ์ „์ฒด ํŒจํ‚ค์ง€ ์กฐํ•ฉ์„ ๋‹ค์‹œ ๋ฌถ์–ด์•ผํ•œ๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•œ๋‹ค.

Going Serverless

๋‚˜๋Š” ํ•ญ์ƒ serverless ๋ผ๋Š” ๋ฉ‹์ง„ ๊ธฐ์ˆ ์„ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ์—ˆ๋‹ค. serverless ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์š”์ฒญ์‹œ ์‹คํ–‰ํ•  ํ•จ์ˆ˜๋ฅผ ์ •์˜ํ•˜๊ณ , ํ•จ์ˆ˜๊ฐ€ spin up(๊ฐ€๋™) ๋˜๊ณ , ์š”์ฒญ์„ ์ฒ˜๋ฆฌ ํ•œ ๋‹ค์Œ ์ผ์ • ์‹œ๊ฐ„์ด ์ง€๋‚˜๋ฉด ์ž์ฒด์ ์œผ๋กœ ์ข…๋ฃŒ๋œ๋‹ค. ์ด๋Š” ํ™•์žฅ์„ฑ์ด ๋งค์šฐ ๋†’๋‹ค๋Š” ๊ฒƒ์„ ์˜๋ฏธํ•œ๋‹ค. ์ฆ‰, 1000๊ฐœ์˜ ๋™์‹œ ์š”์ฒญ์„ ๋ฐ›์œผ๋ฉด 1000๋Œ€์˜ ์„œ๋ฒ„๋ฅผ ์ฆ‰์‹œ ๊ฐ€๋™ ํ•  ์ˆ˜ ์žˆ๋‹ค. ๋˜ํ•œ ์„œ๋ฒ„๊ฐ€ ์‹ค์ œ๋กœ ์‹คํ–‰๋˜๋Š” ์‹œ๊ฐ„์— ๋Œ€ํ•ด์„œ๋งŒ ๋น„์šฉ์„ ์ง€๋ถˆํ•œ๋‹ค๋Š” ์˜๋ฏธ์ด๋‹ค.

Serverless sounds ๋Š” ์šฐ๋ฆฌ์˜ ์„œ๋น„์Šค์— ์™„๋ฒฝํ•˜๋‹ค. ํ’€ํƒ€์ž„์œผ๋กœ ์‹คํ–‰๋˜์ง€ ์•Š์œผ๋ฉฐ, ๋™์‹œ์— ์—ฌ๋Ÿฌ ์š”์ฒญ์ด ์žˆ๋Š” ๊ฒฝ์šฐ ๋†’์€ ๋™์‹œ์„ฑ์ด ํ•„์š”ํ•˜๋‹ค. ๊ทธ๋ž˜์„œ Serverless ๋ผ๋Š” ์ ์ ˆํ•œ ์ด๋ฆ„์˜ ํ”„๋ ˆ์ž„ ์›Œํฌ๋กœ ์—ด์‹ฌํžˆ ๊ฐœ๋ฐœ์„ ์‹œ์ž‘ํ–ˆ๋‹ค.

Serverless ๋•๋ถ„์— ์„œ๋น„์Šค๊ฐ€ ์ˆœ์กฐ๋กญ๊ฒŒ ์ง„ํ–‰๋˜์—ˆ๋‹ค. 2์ผ ์ด๋‚ด์— ์ž‘๋™ํ•˜๋Š” ๋ฒ„์ „์ด ์žˆ์—ˆ๊ณ , ๋‚˜๋Š” serverless ํ•จ์ˆ˜ 3๊ฐœ๋ฅผ ๋งŒ๋“ค์—ˆ๋‹ค.

  1. A metadata resolve: ์ด ์„œ๋น„์Šค๋Š” ๋ฒ„์ „ ๋ฐ peerDependencies๋ฅผ ํ™•์ธํ•˜๊ณ , ํŒจํ‚ค์ง€ ๊ธฐ๋Šฅ์„ ์š”์ฒญํ•œ๋‹ค.
  2. A packager: ์ด ์„œ๋น„์Šค๋Š” ์˜์กด์„ฑ์˜ ๋ฒˆ๋“ค๋ง ๋ฐ ์‹ค์ œ ์„ค์น˜๋ฅผ ์ˆ˜ํ–‰ํ•œ๋‹ค.
  3. An uglifier: ๊ฒฐ๊ณผ ๋ฒˆ๋“ค์„ ๋น„๋™๊ธฐ ์ ์œผ๋กœ uglifling ํ•œ๋‹ค.

์ด์ „ ์„œ๋น„์Šค์™€ ํ•จ๊ป˜ ์ƒˆ ์„œ๋น„์Šค๋ฅผ ์‹คํ–‰ํ–ˆ๋Š”๋ฐ ์‹ค์ œ๋กœ ํšจ๊ณผ๊ฐ€ ์žˆ์—ˆ๋‹ค! ์ด์ „์— $100์˜€๋˜ ๊ฒƒ์— ๋น„ํ•ด, ์˜ˆ์ƒ ๋น„์šฉ์€ ํ•œ ๋‹ฌ์— $0.18๋กœ ์ค„์—ˆ๊ณ  ์‘๋‹ต ์‹œ๊ฐ„์€ 40% ์—์„œ 700% ๋กœ ํ–ฅ์ƒ๋˜์—ˆ๋‹ค.

๋ฉฐ์น  ํ›„ ์ œํ•œ ์‚ฌํ•ญ์— ์ฃผ๋ชฉํ•˜๊ธฐ ์‹œ์ž‘ํ–ˆ๋‹ค. lambda ํ•จ์ˆ˜์—๋Š” ์ตœ๋Œ€ 500MB ์˜ ๋””์Šคํฌ ๊ณต๊ฐ„๋งŒ ์žˆ์œผ๋ฏ€๋กœ ์ผ๋ถ€ ์˜์กด์„ฑ ์กฐํ•ฉ์„ ์„ค์น˜ํ•  ์ˆ˜ ์—†์—ˆ๋‹ค. ์ด๊ฒƒ์€ deal breaker ์˜€๊ณ  ๋‚˜๋Š” drawing board ๋กœ ๋Œ์•„์™€์•ผํ–ˆ๋‹ค.

Serverless Revisited

๋ช‡ ๋‹ฌ์ด ์ง€๋‚˜์„œ CodeSandbox ์šฉ ์ƒˆ ๋ฒˆ๋“ค๋Ÿฌ๋ฅผ ์ถœ์‹œํ–ˆ๋‹ค. ์ด ๋ฒˆ๋“ค๋Ÿฌ๋Š” ๋งค์šฐ ๊ฐ•๋ ฅํ•˜์—ฌ, Vue ๋ฐ Preact ์™€ ๊ฐ™์€ ๋” ๋งŽ์€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‰ฝ๊ฒŒ ์ง€์›ํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์ง€์›ํ•จ์œผ๋กœ์จ ํฅ๋ฏธ๋กœ์šด ์š”์ฒญ์„ ๋ฐ›์•˜๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, Preact ์—์„œ React ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋ฉด require ( 'react') ๋ฅผ require ( 'preact-compat') ๋ผ๋Š” ๋ณ„์นญ์œผ๋กœ ์ง€์ •ํ•ด์•ผํ•œ๋‹ค. Vue ์˜ ๊ฒฝ์šฐ, @/components/App.vue ๋ฅผ ์ƒŒ๋“œ ๋ฐ•์Šค ํŒŒ์ผ๋กœ ํ•ด์„ ํ•  ์ˆ˜ ์žˆ๋‹ค. packager ๋Š” ์˜์กด์„ฑ์„ ์œ„ํ•ด, ์ด ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜์ง€ ์•Š์ง€๋งŒ, ๋ฒˆ๋“ค๋Ÿฌ๋Š” ์ด ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•œ๋‹ค.

๊ทธ๋•Œ, ๋ธŒ๋ผ์šฐ์ € ๋ฒˆ๋“ค๋Ÿฌ๊ฐ€ ์‹ค์ œ๋กœ packaging ์„ ํ•  ์ˆ˜ ์žˆ๋‹ค๊ณ  ์ƒ๊ฐํ•˜๊ธฐ ์‹œ์ž‘ํ–ˆ๋‹ค. ๊ด€๋ จ ํŒŒ์ผ์„ ๋ธŒ๋ผ์šฐ์ €๋กœ ๋ณด๋‚ด๋ฉด, ๋ฒˆ๋“ค๋Ÿฌ๊ฐ€ ์˜์กด์„ฑ์˜ ์‹ค์ œ ๋ฒˆ๋“ค๋ง์„ ์ˆ˜ํ–‰ํ•˜๊ฒŒ ํ•œ๋‹ค. ์ „์ฒด ๋ฒˆ๋“ค์„ evaluating ํ•˜์ง€ ์•Š๊ณ  ์ผ๋ถ€๋งŒ evaluating ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋” ๋น ๋ฅด๋‹ค.

์ด ์ ‘๊ทผ ๋ฐฉ์‹์—๋Š” ๋…๋ฆฝ์ ์œผ๋กœ ์˜์กด์„ฑ์„ ์„ค์น˜ํ•˜๊ณ  ์บ์‹œ ํ•  ์ˆ˜ ์žˆ๋‹ค๋Š” ํฐ ์ด์ ์ด ์žˆ๋‹ค. ์˜์กด์„ฑ ํŒŒ์ผ์„ ํด๋ผ์ด์–ธํŠธ์— merge ํ•  ์ˆ˜ ์žˆ๋‹ค. ์ฆ‰, ๊ธฐ์กด์˜ ์˜์กด์„ฑ ์œ„์— ์ƒˆ๋กœ์šด ์ข…์†์„ฑ์„ ์š”์ฒญํ•˜๋ฉด ์ƒˆ ์ข…์†์„ฑ์— ๋Œ€ํ•œ ํŒŒ์ผ๋งŒ ์ˆ˜์ง‘ํ•˜๋ฉด ๋œ๋‹ค. ์šฐ๋ฆฌ๋Š” ํ•˜๋‚˜์˜ ์ข…์†์„ฑ๋งŒ ์„ค์น˜ํ•˜๊ธฐ ๋•Œ๋ฌธ์—, AWS Lambda ์˜ 500MB ์ œํ•œ์„ ํ•ด๊ฒฐํ•œ๋‹ค. ์ด์ œ packager ๋Š” ์–ด๋–ค ํŒŒ์ผ์ด ๊ด€๋ จ์„ฑ์ด ์žˆ๋Š”์ง€ ์•Œ์•„๋‚ด๊ณ  ์ „์†กํ•ด์•ผ ํ•  ์ฑ…์ž„์ด ์žˆ๊ธฐ๋•Œ๋ฌธ์— packager ์—์„œ ์›นํŒฉ์„ ์‚ญ์ œํ•  ์ˆ˜๋„ ์žˆ๋‹ค.

์ฐธ๊ณ  : ํŒจํ‚ค์ €๋ฅผ ์‚ญ์ œํ•˜๊ณ  unpkg.com ์—์„œ ๋ชจ๋“  ํŒŒ์ผ์„ ๋™์ ์œผ๋กœ ์š”์ฒญํ•  ์ˆ˜๋„ ์žˆ๋‹ค. ์ด๊ฒƒ์€ ์•„๋งˆ๋„ ์•ž์„œ ๋งํ•œ ์ƒˆ๋กœ์šด ์ ‘๊ทผ๋ฒ•๋ณด๋‹ค ํ›จ์”ฌ ๋น ๋ฅด๋‹ค. ํ•˜์ง€๋งŒ ์šฐ๋ฆฌ๋Š” ์˜คํ”„๋ผ์ธ ์ง€์›์„ ์ œ๊ณตํ•˜๊ณ  ์‹ถ๊ธฐ ๋•Œ๋ฌธ์—, ํŒจํ‚ค์ € (์ ์–ด๋„ ํŽธ์ง‘๊ธฐ์˜ ๊ฒฝ์šฐ)๋ฅผ ๊ณ„์† ์œ ์ง€ํ•˜๊ธฐ๋กœ ๊ฒฐ์ •ํ–ˆ๋‹ค. ๊ฐ€๋Šฅํ•œ ๋ชจ๋“  ๊ด€๋ จ ํŒŒ์ผ์ด์žˆ๋Š” ๊ฒฝ์šฐ์—๋งŒ ๊ฐ€๋Šฅํ•˜๋‹ค.

How it works in practice

์ข…์†์„ฑ ์กฐํ•ฉ์„ ์š”์ฒญํ•˜๋ฉด ๋จผ์ €์ด ์กฐํ•ฉ์ด S3์— ์ €์žฅ๋˜์–ด ์žˆ๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. S3์— ์—†์œผ๋ฉด API ์„œ๋น„์Šค์—์„œ ์กฐํ•ฉ์„ ์š”์ฒญํ•ฉ๋‹ˆ๋‹ค. ์ด ์„œ๋น„์Šค๋Š” ๋ชจ๋“  ์ข…์†์„ฑ์— ๋Œ€ํ•ด ๋ชจ๋“  ํŒจํ‚ค์ €๋ฅผ ๋…๋ฆฝ์ ์œผ๋กœ ์š”์ฒญํ•ฉ๋‹ˆ๋‹ค. 200 OK๋ฅผ ๋˜์ฐพ์ž ๋งˆ์ž S3์„ ๋‹ค์‹œ ์š”์ฒญํ•ฉ๋‹ˆ๋‹ค.

ํŒจํ‚ค์ €๋Š” yarn์„ ์‚ฌ์šฉํ•˜์—ฌ ์ข…์†์„ฑ์„ ์„ค์น˜ํ•˜๊ณ  ์ง„์ž… ์  ๋””๋ ‰ํ† ๋ฆฌ์—์žˆ๋Š” ๋ชจ๋“  ํŒŒ์ผ์˜ AST๋ฅผ ํ†ต๊ณผํ•˜์—ฌ ๋ชจ๋“  ๊ด€๋ จ ํŒŒ์ผ์„ ์ฐพ์Šต๋‹ˆ๋‹ค. require ๋ฌธ์„ ๊ฒ€์ƒ‰ํ•˜์—ฌ ํŒŒ์ผ ๋ชฉ๋ก์— ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ์žฌ๊ท€ ์ ์œผ๋กœ ๋ฐœ์ƒํ•˜๋ฏ€๋กœ ์˜์กด์„ฑ ๊ทธ๋ž˜ํ”„๋ฅผ ์–ป์Šต๋‹ˆ๋‹ค.

Advatages

Save in cost

์ดํ‹€ ์ „์— ์ƒˆ๋กœ์šด ํŒจํ‚ค์ง€๋ฅผ ๋ฐฐํฌํ–ˆ๊ณ , ๊ทธ๋™์•ˆ $0.02 ๋ฅผ ์ง€๋ถˆํ–ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์ด๊ฒƒ์€ ์บ์‹œ๋ฅผ ๊ตฌ์ถ•ํ•˜๊ธฐ์œ„ํ•œ ๊ฒƒ์ด๋‹ค. ์ด๋Š” ํ•œ ๋‹ฌ์— $100๋‹ฌ๋Ÿฌ ์— ์ •๋„ ํฌ๊ฒŒ ์ ˆ์•ฝ๋œ๋‹ค.

Higher performance

์ด์ œ ๋ชจ๋“  ์กฐํ•ฉ์— ๋Œ€ํ•ด 3์ดˆ ์ด๋‚ด์— ์ƒˆ๋กœ์šด ์ข…์†์„ฑ ์กฐํ•ฉ์„ ์–ป์„ ์ˆ˜ ์žˆ๋‹ค. ๊ธฐ์กด ์‹œ์Šคํ…œ์—์„œ๋Š” ๋•Œ๋•Œ๋กœ 1๋ถ„์ด ์†Œ์š”๋œ๋‹ค. ์กฐํ•ฉ์ด ์บ์‹œ๋˜๋ฉด ์—ฐ๊ฒฐ์ด ๋น ๋ฅธ ์ƒํƒœ์—์„œ๋Š” 50ms ์ด๋‚ด์— ์–ป์„ ์ˆ˜ ์žˆ๋‹ค. Amazon Cloudfront ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์˜์กด์„ฑ์„ ์บ์‹œํ•œ๋‹ค. ํ”„๋กœ์ ํŠธ์— ๋Œ€ํ•œ ๊ด€๋ จ JS ํŒŒ์ผ๋งŒ ํŒŒ์‹ฑํ•˜๊ณ  ์‹คํ–‰ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ํ”„๋กœ์ ํŠธ๋„ ๋” ๋น ๋ฅด๊ฒŒ ์‹คํ–‰๋œ๋‹ค.

More flexibility

๋ฒˆ๋“ค๋Ÿฌ๋Š” ์ด์ œ ๋กœ์ปฌ ํŒŒ์ผ์ธ ๊ฒƒ์ฒ˜๋Ÿผ ์˜์กด์„ฑ์„ ์ฒ˜๋ฆฌํ•œ๋‹ค. ์ฆ‰, ์˜ค๋ฅ˜ ์Šคํƒ ์ถ”์ ์ด ํ›จ์”ฌ ๋ช…ํ™•ํ•ด์กŒ์œผ๋ฉฐ ์ด์ œ .scss, .vue ๋“ฑ๊ณผ ๊ฐ™์€ ์˜์กด์„ฑ์œผ๋กœ ๋ถ€ํ„ฐ ๋ชจ๋“  ํŒŒ์ผ์„ ํฌํ•จํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ๋ณ„์นญ๊ณผ ๊ฐ™์€ ํ•ญ๋ชฉ์„ ์‰ฝ๊ฒŒ ์ง€์›ํ•  ์ˆ˜ ์žˆ๋‹ค. ์˜์กด์„ฑ์ด ๋กœ์ปฌ์— ์„ค์น˜๋œ ๊ฒƒ์ฒ˜๋Ÿผ ์ž‘๋™ํ•œ๋‹ค.

Release

์ดํ‹€ ์ „์— ์บ์‹œ๋ฅผ ๊ตฌ์ถ•ํ•˜๊ธฐ ์œ„ํ•ด ์ด์ „ ํŒจํ‚ค์ง€์™€ ํ•จ๊ป˜ ์ƒˆ๋กœ์šด ํŒจํ‚ค์ง€๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์‹œ์ž‘ํ–ˆ๋‹ค. ์ด๋ฏธ 2,000๊ฐœ์˜ ์„œ๋กœ ๋‹ค๋ฅธ ์กฐํ•ฉ๊ณผ, 1400๊ฐœ์˜ ์„œ๋กœ ๋‹ค๋ฅธ ์ข…์†์„ฑ์„ ์บ์‹œํ–ˆ๋‹ค. ์‹ค์ œ๋กœ ์ด๋™ํ•˜๊ธฐ ์ „์—, ์ƒˆ ๋ฒ„์ „์„ ๊ด‘๋ฒ”์œ„ํ•˜๊ฒŒ ํ…Œ์ŠคํŠธํ•˜๊ณ  ์‹ถ์—ˆ๋‹ค.

๋˜ํ•œ ์†Œ์Šค์— ๊ด€์‹ฌ์ด์žˆ๋Š” ๊ฒฝ์šฐ ์—ฌ๊ธฐ์—์„œ ์ฐพ์„ ์ˆ˜ ์žˆ๋‹ค.

Go Serverless!

serverless ์— ๊นŠ์€ ์ธ์ƒ์„ ๋ฐ›์•˜๊ธฐ ๋•Œ๋ฌธ์— ์„œ๋ฒ„ ํ™•์žฅ์„ฑ๊ณผ ๊ด€๋ฆฌ๊ฐ€ ๋งค์šฐ ์‰ฌ์›Œ์กŒ๋‹ค. ํ•ญ์ƒ serverless ์—์„œ ๋‚˜๋ฅผ ๋ฐฉํ•ดํ•˜๋Š” ์œ ์ผํ•œ ๊ฒƒ์€ ๋งค์šฐ ๋ณต์žกํ•œ ์„ค์ •์ด์ง€๋งŒ, serverless.com ์˜ ์‚ฌ๋žŒ๋“ค์€ ์ด๊ฒƒ์„ ์–ด๋ฆฐ์ด๋„ ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋งŒ๋“ค์—ˆ๋‹ค. ๊ทธ๋“ค์˜ ์ž‘์—…์— ๋งค์šฐ ๊ฐ์‚ฌํ•˜๋ฉฐ, serverless ๋Š” ๋งŽ์€ ๋‹ค๋ฅธ ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ ์–‘์‹์˜ ๋ฏธ๋ž˜๋ผ๊ณ  ์ƒ๊ฐํ•œ๋‹ค.

Future

์šฐ๋ฆฌ๋Š” ์—ฌ์ „ํžˆ ๋งŽ์€ ๋ฐฉ๋ฒ•์œผ๋กœ ์‹œ์Šคํ…œ์„ ๊ฐœ์„  ํ•  ์ˆ˜ ์žˆ๋‹ค. ๋‚˜๋Š” embede ์—์„œ ์š”๊ตฌ๋ฅผ ๋™์ ์œผ๋กœ ์š”์ฒญํ•˜๊ณ , ์˜คํ”„๋ผ์ธ์„ ๋ณด์กดํ•˜๊ธฐ ์œ„ํ•ด ๋…ธ๋ ฅํ•˜๊ณ  ์‹ถ๋‹ค. ์œ ์ง€ํ•˜๊ธฐ ์–ด๋ ค์šด ๊ท ํ˜•์ด์ง€๋งŒ ๊ฐ€๋Šฅํ•ด์•ผํ•œ๋‹ค. ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ํ—ˆ์šฉํ•˜๋Š” ๋‚ด์šฉ์— ๋”ฐ๋ผ, ๋ธŒ๋ผ์šฐ์ €์—์„œ ๋…๋ฆฝ์ ์œผ๋กœ ์˜์กด์„ฑ ์บ์‹ฑ์„ ์‹œ์ž‘ํ•  ์ˆ˜๋„ ์žˆ๋‹ค. ์ด ๊ฒฝ์šฐ ๋‹ค๋ฅธ ์˜์กด์„ฑ ์กฐํ•ฉ์„ ์‚ฌ์šฉํ•˜์—ฌ ์ƒˆ ํ”„๋กœ์ ํŠธ๋ฅผ ๋ฐฉ๋ฌธํ•  ๋•Œ ์ƒˆ ์˜์กด์„ฑ์„ ๋‹ค์šด๋กœ๋“œํ•˜์ง€ ์•Š์•„๋„ ๋œ๋‹ค. ๋‚˜๋Š” ๋˜ํ•œ ์˜์กด์„ฑ ํ•ด๊ฒฐ์„ ๋” ํƒ๊ตฌ ํ•  ๊ฒƒ์ด๋‹ค. ์™„์ „ํ•ด์ง€๊ธฐ ์ „์— ํ•ด๊ฒฐํ•˜๋ ค๋Š” ์ƒˆ๋กœ์šด ์‹œ์Šคํ…œ๊ณผ ๋ฒ„์ „์ด ์ถฉ๋Œํ•  ๊ฐ€๋Šฅ์„ฑ๋„ ์žˆ๋‹ค.

๊ทธ๋Ÿผ์—๋„ ๋ถˆ๊ตฌํ•˜๊ณ  CodeSandbox์˜ ์ƒˆ๋กœ์šด ์ž‘์—…์„ ์ง„ํ–‰ํ•˜๋ฉด์„œ ์ƒˆ ๋ฒ„์ „์— ๋งค์šฐ ๋งŒ์กฑํ•œ๋‹ค.

CodeSandbox์˜ ๊ฐ€์žฅ ๋งŽ์€ ํ™œ๋™์ด ์—ฌ๊ธฐ ์žˆ๋‹ค.

๊ธฐํš ๐Ÿ’ก
๊ทœ์น™ ๐Ÿ›
API ๋ฌธ์„œ ๐Ÿง‘๐Ÿปโ€๐Ÿ’ป
Style Guides ๐Ÿ“‹
์Šคํ”„๋ฆฐํŠธ ๐Ÿ”–
๋ฐ์ผ๋ฆฌ ์Šคํฌ๋Ÿผ ๐Ÿ“
์˜ค๋Š˜์˜ ํšŒ๊ณ  โšพ๏ธ
ํšŒ์˜๋ก ๐Ÿ“„

ํšŒ์˜๋ก

๊ธฐ์ˆ ๊ณต์œ  ๐Ÿ”ฅ

Clone this wiki locally