npm&dependency.md

๐Ÿก

NPM

npm (ํŒจํ‚ค์ง€ ๋งค๋‹ˆ์ €) ์„ ์‚ฌ์šฉํ•˜๋Š” ์ด์œ 

๐Ÿ‘‰ ํŒจํ‚ค์ง€ ๋งค๋‹ˆ์ €๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š์•˜์„ ๋•Œ

  1. ๋Œ€๊ทœ๋ชจ ํ”„๋กœ์ ํŠธ์—์„œ ์ž๋ฐ”์Šคํฌ๋ฆฝํŠธ์˜ ๋กœ๋“œ๋ฅผ ๊ด€๋ฆฌํ•  ์ˆ˜ ์—†์Œ
  2. ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ์ƒˆ ๋ฒ„์ „์ด ๋‚˜์™”์„ ๋•Œ, ํŒŒ์ผ์„ ์—…๋ฐ์ดํŠธํ•ด์•ผํ•จ
  3. ์ด์ „์—๋Š” ๋ชจ๋“  ํŒจํ‚ค์ง€๋ฅผ ํฌํ•จํ•œ ๋‹จ์ผ ์ €์žฅ์†Œ๊ฐ€ ์—†์—ˆ์Œ
์ฆ‰, ๋” ๋‚˜์€ ๋ฐฉ์‹์œผ๋กœ ์˜์กด์„ฑ์„ ๊ด€๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•˜๋Š” ๋ชจ๋˜ ๊ฐœ๋ฐœ ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค.

global๋กœ ํŒจํ‚ค์ง€๋ฅผ ์„ค์น˜ํ•˜๋Š” ์ด์œ 

  • ๊ธ€๋กœ๋ฒŒ ๋„๊ตฌ๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ์ž…๋‹ˆ๋‹ค.
    • ex) live server, nodemon, parcel
    • ํ•˜์ง€๋งŒ ํŒจํ‚ค์ง€๋ฅผ ๊ธ€๋กœ๋ฒŒ๋กœ ์„ค์น˜ํ•˜๋ฉด ํ•ญ์ƒ ์ตœ์‹  ๋ฒ„์ „์„ ์œ ์ง€ํ•˜๊ธฐ ์–ด๋ ต์Šต๋‹ˆ๋‹ค.
์„ค์น˜ํ•˜๋Š” ํŒจํ‚ค์ง€์˜ ๋ฒ„์ „์„ ์ตœ์‹ ์œผ๋กœ ์œ ์ง€ํ•˜๊ธฐ ์œ„ํ•ด, global ์„ค์น˜๋ฅผ ์ง€์–‘ํ•  ์ด์œ ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

dev dependency๋ž€?

npm i parcel --save-dev
  • devDependency๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋นŒ๋“œํ•˜๊ธฐ ์œ„ํ•œ ๋„๊ตฌ์ž…๋‹ˆ๋‹ค. ๊ฐœ๋ฐœ์— ์‚ฌ์šฉ๋˜๊ธฐ ๋•Œ๋ฌธ์— devDependency๋ผ๋Š” ์ด๋ฆ„์„ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.
    • dependency์™€ ๊ฐ™์ด ์ฝ”๋“œ์— ํฌํ•จ๋˜๋Š” ์˜์กด์„ฑ์ด ์•„๋‹™๋‹ˆ๋‹ค.
    | ์ข…์†์„ฑ(์˜์กด์„ฑ) | ์šด์˜ํ™˜๊ฒฝ | ๊ฐœ๋ฐœํ™˜๊ฒฝ | cli | | --- | --- | --- | --- | | ์ผ๋ฐ˜(์ •๊ทœ) ์˜์กด์„ฑ regular dependency | O | O | npm i ~ | | ๊ฐœ๋ฐœ ์˜์กด์„ฑ devDependency | X | O | npm i ~ โ€”save-dev | | ์šด์˜ ์˜์กด์„ฑ production dependency | O | X | npm i ~ โ€”production |
๐Ÿค” **regular dependency์™€ dev dependency์˜ ์ฐจ์ด์ ์€?**

์†Œํ”„ํŠธ์›จ์–ด ๊ฐœ๋ฐœ์—์„œ, ์˜์กด์„ฑ์€ ์ฝ”๋“œ ์ž‘๋™์— ํ•„์š”ํ•œ ํŒจํ‚ค์ง€๋‚˜ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ž…๋‹ˆ๋‹ค. 
npm ํ˜น์€ yarn ๊ฐ™์€ ํŒจํ‚ค์ง€ ๊ด€๋ฆฌ์ž๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ๋Š” package.json ํŒŒ์ผ์— ์ด๋Ÿฌํ•œ ์˜์กด์„ฑ์„ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ข…์†์„ฑ(dependency)์€ ์ฝ”๋“œ๊ฐ€ **์šด์˜ ํ™˜๊ฒฝ**์—์„œ ์‹คํ–‰๋  ๋•Œ ํ•„์š”ํ•œ ํŒจํ‚ค์ง€์ž…๋‹ˆ๋‹ค. 
์ด๋“ค์€ ์‚ฌ์šฉ์ž๊ฐ€ ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์ด๋‚˜ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ํ•„์š”ํ•œ ๊ฒƒ๋“ค์ž…๋‹ˆ๋‹ค. 

์šด์˜ ์ข…์†์„ฑ(production dependency)๋งŒ์„ ์„ค์น˜ํ•˜๊ธฐ ์œ„ํ•ด npm i ~ โ€”production ๋ช…๋ น์–ด๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ฐœ๋ฐœ ์ข…์†์„ฑ(dev dependencies)์€ **๊ฐœ๋ฐœ ์ค‘์—๋งŒ ํ•„์š”**ํ•œ ํŒจํ‚ค์ง€์ž…๋‹ˆ๋‹ค. 
์ด๋Ÿฌํ•œ ๊ฒƒ๋“ค์€ ํ…Œ์ŠคํŠธ ํ”„๋ ˆ์ž„์›Œํฌ, ๋นŒ๋“œ ๋„๊ตฌ, ๋ฆฐํ„ฐ ๋“ฑ์ด ํฌํ•จ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. 
์šด์˜ ํ™˜๊ฒฝ์—์„œ ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์ด๋‚˜ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‹คํ–‰ํ•  ๋•Œ ํ•„์š”ํ•˜์ง€ ์•Š์œผ๋ฏ€๋กœ, ์ฝ”๋“œ๋ฅผ ๋ฐฐํฌํ•  ๋•Œ๋Š” ํฌํ•จ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

leaflet : ์™ธ๊ตญ map api

an open-source JavaScript library for mobile-friendly interactive maps

image

lodash : javaScript๋ฅผ ๋” ํŽธํ•˜๊ฒŒ ์“ฐ๊ธฐ

  • ์ข…๋ฅ˜
    • ๊ทธ๋ƒฅ lodash โ‡’ use common JS
    • lodash-es โ‡’ es6
  • cloneDeep ๋ฉ”์†Œ๋“œ
    • ์ค‘์ฒฉ ๊ฐœ์ฒด nested obejct์— ๊นŠ์€ ๋ณต์‚ฌ deep copy / deep clone์„ ์ˆ˜๋™์œผ๋กœ ๊ตฌํ˜„ํ•˜๋Š” ๊ฒƒ์€ ๋ณต์žกํ•ฉ๋‹ˆ๋‹ค.,

      1. json์œผ๋กœ ๋ณ€ํ™˜ ํ›„ object๋กœ ์žฌ๋ณ€ํ™˜ โ‡’ ๋Š๋ฆฐ ์†๋„, ํ•จ์ˆ˜์— ์ ์šฉํ•  ์ˆ˜ x
      2. Lodash๋ฅผ ์‚ฌ์šฉ โ‡’ ์˜์กด์„ฑ
      3. ์žฌ๊ท€ ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉ โ‡’ ์ฐธ์กฐํ•œ ๊ฐ์ฒด๋ฅผ ๋ถ„๋ฆฌํ•ด๊ฐ€๋ฉฐ ๊นŠ์€ ๋ณต์‚ฌ
    • cloneDeep()์„ ์‚ฌ์šฉํ•˜์—ฌ ๊นŠ์€ ๋ณต์‚ฌ๋ฅผ ์ง„ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

      // ์ค‘์ฒฉ ๊ฐ์ฒด๋ฅผ ๊นŠ์€ ๋ณต์‚ฌ
      import { cloneDeep } from "lodash-es";
      
      const state = {
        cart: [
          { product: "๋ถ€๋Œ€์ฐŒ๊ฐœ", quantity: 1 },
          { product: "๊ฝ์น˜์ฐŒ๊ฐœ", quantity: 1 },
          { product: "๊น€์น˜์ฐŒ๊ฐœ", quantity: 1 },
        ],
        user: { loggedIn: true },
      };
      
      const objectClone = Object.assign({}, state); // ์–•์€ ๋ณต์‚ฌ
      const objectDeepClone = cloneDeep(state); // lodash์˜ ๊นŠ์€ ๋ณต์‚ฌ ๊ธฐ๋Šฅ
      
      state.user.loggedIn = false;
      
      console.log(objectClone); // loggedIn์€ false์ž…๋‹ˆ๋‹ค.
      console.log(objectDeepClone); // loggedIn์€ true์ž…๋‹ˆ๋‹ค.
      

Parcel

https://parceljs.org/

  • ์„ค์ • ์—†์ด ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๋ชจ๋˜ ๊ฐœ๋ฐœ ๋นŒ๋“œ ๋„๊ตฌ์ž…๋‹ˆ๋‹ค.

parcel vs webpack

Parcel๊ณผ Webpack์€ ๋‘˜ ๋‹ค JavaScript ๋ฒˆ๋“ค๋Ÿฌ์ž…๋‹ˆ๋‹ค. ์ด๋“ค์€ JavaScript ์ฝ”๋“œ์™€ ๊ธฐํƒ€ ์ž์‚ฐ(์ด๋ฏธ์ง€ ๋˜๋Š” CSS ํŒŒ์ผ ๊ฐ™์€)์„ ํ•˜๋‚˜์˜ ํŒŒ์ผ(๋˜๋Š” ์—ฌ๋Ÿฌ ํŒŒ์ผ)๋กœ ๊ฒฐํ•ฉํ•˜์—ฌ ์›น ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ๋กœ๋“œํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค.

๋‘ ๊ฐ€์ง€ ์‚ฌ์ด์˜ ์ฃผ์š” ์ฐจ์ด์ ์€ Parcel์€ ์„ค์ • ํŒŒ์ผ ์—†์ด ์ž‘๋™ํ•˜๋Š” ๋ฒˆ๋“ค๋Ÿฌ์ด๋ฉฐ, ์ฝ”๋“œ๋ฅผ ์–ด๋–ป๊ฒŒ ๋ฒˆ๋“ค๋ง ํ• ์ง€๋ฅผ ์ง€์ •ํ•˜๋Š” webpack.config.js์™€ ๊ฐ™์€ ์„ค์ • ํŒŒ์ผ์„ ๋งŒ๋“ค ํ•„์š”๊ฐ€ ์—†๋‹ค๋Š” ์ ์ž…๋‹ˆ๋‹ค. ๋Œ€์‹  ๊ทœ์น™๊ณผ ํžˆ์œ„๋ฆญ(heuristics)์„ ์‚ฌ์šฉํ•˜์—ฌ ์ฝ”๋“œ๋ฅผ ์ž๋™์œผ๋กœ ๋ฒˆ๋“ค๋ง ํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์„ ์ฐพ์•„๋ƒ…๋‹ˆ๋‹ค.

Webpack์€ ๋ฐ˜๋ฉด์— ์„ค์ • ํŒŒ์ผ์ด ํ•„์š”ํ•˜๋ฉฐ, ์ฝ”๋“œ๋ฅผ ๋ฒˆ๋“ค๋ง ํ•  ๋•Œ ๋” ์„ธ๋ถ„ํ™”๋œ ์ œ์–ด๋ฅผ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” Parcel๋ณด๋‹ค ๊ฐ•๋ ฅํ•˜๊ณ  ์œ ์—ฐํ•˜์ง€๋งŒ, ์„ค์ •ํ•˜๊ณ  ์„ค์ •ํ•˜๋Š” ๊ฒƒ์ด ๋” ๋ณต์žกํ•˜๋ฉฐ ํ•™์Šต ๊ณก์„ ์ด ๋†’์•„์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋‹ค๋ฅธ ์ฐจ์ด์ ์œผ๋กœ๋Š” webpack์ด ๋” ์ธ๊ธฐ์žˆ๊ณ  ์‚ฌ์šฉ๋Ÿ‰์ด ๋” ๋งŽ๊ธฐ ๋•Œ๋ฌธ์—, ๋” ๋งŽ์€ ์ปค๋ฎค๋‹ˆํ‹ฐ ์„œํฌํŠธ์™€ ์„œ๋“œํŒŒํ‹ฐ ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

parcel ์‹คํ–‰ํ•˜๊ธฐ

npx parcel index.html
  • npx : npm์— ๋‚ด์žฅ๋œ ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ
  • parcel์˜ ์˜ต์…˜ : entry point
    image
  • /dist
    • parcel ๋นŒ๋“œ โ‡’ dist์— ์œ„์น˜

    • index.html

      <script src="/index.8cfc62b9.js" defer=""></script>
      

npx parcel index.html vs โ€œstartโ€: โ€œparcel index.htmlโ€

โ“ **why "npx parcel index.html" is became "start": "parcel index.html" in package.json script? 
โ‡’ why there is no npx prefix?**

---

"npx parcel index.html"๊ณผ "start": "parcel index.html"๋Š” ๊ด€๋ จ๋˜์ง€๋งŒ ์„œ๋กœ ๋‹ค๋ฅธ ๋ชฉ์ ์„ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

"npx parcel index.html"๋ฅผ command line์—์„œ ์‹คํ–‰ํ•˜๋ฉด **npx ํŒจํ‚ค์ง€ ๋Ÿฌ๋„ˆ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ 
parcel ๋ช…๋ น์„ ์‹คํ–‰ํ•˜๊ณ  ๊ฐœ๋ฐœ ์„œ๋ฒ„๋ฅผ ์‹œ์ž‘**ํ•ฉ๋‹ˆ๋‹ค. ์ด๋•Œ npx ํŒจํ‚ค์ง€ ๋Ÿฌ๋„ˆ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ 
**์„ค์น˜ํ•œ ๋กœ์ปฌ ๋ฒ„์ „์˜ parcel์„ ์‚ฌ์šฉ**ํ•˜๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.

๋ฐ˜๋ฉด์— package.json์˜ script ์„น์…˜์— ์žˆ๋Š” "start": "parcel index.html"๋Š” npm script ๋ช…๋ น์–ด๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ 
์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋Š” ๋ช…๋ น์„ ์ •์˜ํ•˜๋Š”๋ฐ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. "npm start" ๋˜๋Š” "yarn start"๋ฅผ ์‹คํ–‰ํ•˜๋ฉด 
start ์Šคํฌ๋ฆฝํŠธ์— ์ ํžŒ ๋ช…๋ น์ธ "parcel index.html"์ด ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. ์ด ๋ช…๋ น์€ **๊ฐœ๋ฐœ ์„œ๋ฒ„๋ฅผ ์‹œ์ž‘**ํ•˜์ง€๋งŒ 
**npx ํŒจํ‚ค์ง€ ๋Ÿฌ๋„ˆ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ , ํ”„๋กœ์ ํŠธ์— ์„ค์น˜๋œ ๋กœ์ปฌ ๋ฒ„์ „์˜ parcel ๋ช…๋ น**์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

package.json ์Šคํฌ๋ฆฝํŠธ์—์„œ **npx ์ ‘๋‘์‚ฌ๊ฐ€ ํ•„์š”ํ•˜์ง€ ์•Š์€ ์ด์œ **๋Š” ์Šคํฌ๋ฆฝํŠธ๊ฐ€ ํ”„๋กœ์ ํŠธ์˜ 
**๋กœ์ปฌ node_modules ์ปจํ…์ŠคํŠธ ๋‚ด์—์„œ ๋ช…๋ น์„ ์‹คํ–‰**ํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. 
์ด๊ณณ์—๋Š” **๋กœ์ปฌ๋กœ ์„ค์น˜๋œ parcel ํŒจํ‚ค์ง€**๊ฐ€ ์œ„์น˜ํ•ด ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. 
๊ทธ๋Ÿฌ๋‚˜ ๋ช…๋ น์„ ๋ช…๋ น ํ–‰์—์„œ ์ง์ ‘ ์‹คํ–‰ํ•  ๋•Œ๋Š” npx ์ ‘๋‘์‚ฌ๊ฐ€ ํ•„์š”ํ•˜๋ฉฐ 
์ด๋ฅผ ํ†ตํ•ด ์ •ํ™•ํ•œ ๋ฒ„์ „์˜ parcel์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.

| ์‹คํ–‰ํ•˜๋Š” ๊ณณ | ๋ช…๋ น์–ด | ์‹คํ–‰ํ•˜๋Š” ํŒจํ‚ค์ง€์˜ ์œ„์น˜ | | --- | --- | --- | | command line | npx parcel index.html | npx ํŒจํ‚ค์ง€ ๋Ÿฌ๋„ˆ์—์„œ, ์„ค์น˜ํ•œ ๋กœ์ปฌ ๋ฒ„์ „์˜ parcel ์‹คํ–‰ | | script | โ€œstartโ€ : โ€œparcel index.htmlโ€ | ๋กœ์ปฌ node_module ์ปจํ…์ŠคํŠธ ๋‚ด, ๋กœ์ปฌ๋กœ ์„ค์น˜๋œ parcel ํŒจํ‚ค์ง€ |

build

  • compress build โ‡’ /dist ๋‚ด
"build": "parcel build index.html"

๐Ÿšซ parcel build ์—๋Ÿฌ : main entry ์— ๋Œ€ํ•ด์„œ!

  • ํ˜„์žฌ parcel ๋ฒ„์ „ "parcel": "^2.8.3โ€ ์—์„œ ์˜ˆ์ œ์™€ ๊ฐ™์ด ๋นŒ๋“œ ์‹œ, ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

image

  • โ€œmainโ€ ํ•„๋“œ๊ฐ€ โ€œscript.jsโ€์ธ๋ฐ ๋ฐ˜ํ•ด, ์ปดํŒŒ์ผ๋œ ๋ฒˆ๋“ค์˜ ํƒ€์ž…์€ โ€œhtmlโ€์ด๋ฏ€๋กœ, ํƒ€์ž…์ด ๋งค์น˜๋˜์ง€ ์•Š์•„ ์ƒ๊ธฐ๋Š” ์—๋Ÿฌ์ž…๋‹ˆ๋‹ค.
    • ํ„ฐ๋ฏธ๋„์˜ ์•ˆ๋‚ด์— ๋”ฐ๋ผ โ€œscript.htmlโ€์œผ๋กœ ๋ฐ”๊พธ๊ฑฐ๋‚˜ ( main์„ html๋กœ ) ๋˜๋Š” script์˜ build๋ฅผ js๋กœ ๋ฐ”๊พธ๋ ค๊ณ  ํ–ˆ์„ ๋•Œ๋Š” ๋˜ ๋‹ค๋ฅธ ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

    • ๊ด€๋ จ ๋ฌธ์„œ: https://parceljs.org/features/targets/#library-targets

      image

  • main ํ•„๋“œ๋ฅผ ์ง€์šฐ๋ฉด ์—๋Ÿฌ๊ฐ€ ํ•ด๊ฒฐ๋ฉ๋‹ˆ๋‹ค. (๊ฐ’์„ ์ง€์šฐ๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ, ํ•„๋“œ ์ž์ฒด๋ฅผ ์‚ญ์ œํ•ฉ๋‹ˆ๋‹ค.)
main field is not mandatory for every package, 
if you don't want to set the main field in your package.json file, 
you can remove it.

hot module replacement

  • ์ „์ฒด ํŽ˜์ด์ง€๊ฐ€ ์ƒˆ๋กœ๊ณ ์นจ ๋˜์ง€ ์•Š์Œ
    • ํŽ˜์ด์ง€๋ฅผ ๋กœ๋“œํ•ด๋„, ๋ฐ์ดํ„ฐ ์œ ์ง€
if (module.hot) {
  module.hot.accept();
}
  • ์‹คํ—˜
    • ์ƒˆ๋กœ ๊ณ ์นจ ๋˜์ง€ ์•Š์œผ๋ฏ€๋กœ ๋ฒ„ํŠผ append + ๋ฒ„ํŠผ์˜ ์ฆ๊ฐ€๊ฐ’ ๋‹ค๋ฆ„
    • ์ €์žฅ ํ•  ๋•Œ๋งˆ๋‹ค ๊ณ„์† append

image

let num = 0;
let acc = 5; // 1์—์„œ 5๋กœ ๋ณ€๊ฒฝ

const button = document.createElement("button");
button.innerHTML = `${acc} ๋”ํ•˜๊ธฐ ๋ฒ„ํŠผ: ๊ฐ’ ${num}`;

const newNum = () => {
  num += acc;
  button.innerHTML = `${acc} ๋”ํ•˜๊ธฐ ๋ฒ„ํŠผ: ๊ฐ’ ${num}`;
};

button.removeEventListener("click", newNum);
button.addEventListener("click", newNum);

document.querySelector(".button-box").append(button);

if (module.hot) {
  module.hot.accept();
}