015

๐Ÿ˜‰ ํ—ท๊ฐˆ๋ ธ๋˜ & ๋ชฐ๋ž๋˜ ๋ถ€๋ถ„๋“ค๋งŒ ์ •๋ฆฌํ•˜๋Š” ๋‚˜๋งŒ์˜ TIL
๐Ÿ˜ฏ ๋ชจ๋“  ๊ฐ•์˜ ๋‚ด์šฉ์€ ์ ์ง€ ์•Š์•„์š”!

์˜ค๋Š˜์˜ ์†Œ๊ฐ์€?
๋“œ๋””์–ด ๋ทฐ, webpack์˜ ๊ธฐ์ดˆ๊ฐ€ ๋๋‚ฌ์Šต๋‹ˆ๋‹ค.
๋ทฐ๋กœ ๋…ธ์…˜ ํด๋กœ๋‹์„ ํ•˜๋ฉด ์ •๋ง ํŽธ๋ฆฌํ•  ๊ฒƒ ๊ฐ™์•„์š”.
VanillaJS์— ์ต์ˆ™ํ–ˆ์—ˆ๋Š”๋ฐ.. ๋” ํŽธ๋ฆฌํ•œ ๊ฑธ ์•Œ์•„๋ฒ„๋ ธ์–ด..




[1] Vue Router

Vue Router ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•ด์„œ ํŽ˜์ด์ง€ ๋ถ„๋ฆฌ ๋ฐ ์ด๋™์„ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.


Vue Router๋Š” ํ•ด๋‹น ๋ช…๋ น์–ด๋กœ ์„ค์น˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

npm i vue-router@next // next๋ฒ„์ „์œผ๋กœ ์„ค์น˜ํ•ฉ๋‹ˆ๋‹ค.


[1-1] Router mode

[1] Hash ๋ชจ๋“œ

// router hash ๋ชจ๋“œ
export default createRouter({
  history: createWebHashHistory(),
  routes: [
    {
      path: "/",
      name: "home",
      component: Home,
    },
    {
      path: "/about",
      name: "about",
      component: About,
    },
    {
      path: "/documents",
      component: Docs,
      children: [
        {
          path: ":id",
          component: DocsId,
        },
      ],
    },
    {
      path: "/:notFound(.*)",
      component: NotFound,
    },
  ],
});

// main.js
app.use(router); // use๋ฅผ ์‚ฌ์šฉํ•ด์„œ ๋“ฑ๋กํ•ฉ๋‹ˆ๋‹ค.
<template>
  <!-- ๋งํฌ ์ด๋™์„ ์œ„ํ•œ ํƒœ๊ทธ -->
  <RouterLink to="/">Home</RouterLink>
  <RouterLink to="/about">About</RouterLink>

  <!-- ๋ผ์šฐํŒ…์— ๋”ฐ๋ฅธ ์ปดํฌ๋„ŒํŠธ ๋ Œ๋”๋ง ํƒœ๊ทธ -->
  <RouterView />

  <!-- RouterLink์™€ ๊ฐ™์€ ์—ญํ• ์ž…๋‹ˆ๋‹ค. -->
  <button @click="$router.push('/')">Home</button>
  <button @click="$router.push('/about')">About</button>
</template>


  • ์žฅ์ 

๊ธฐ๋ณธ์ ์ธ ๋„๋ฉ”์ธ ์ฃผ์†Œ๋กœ๋งŒ ์š”์ฒญ์ด ๋“ค์–ด๊ฐ€๊ณ , ๊ทธ ์™ธ์˜ ๋‚˜๋จธ์ง€ ํŽ˜์ด์ง€ ๋ถ„๋ฅ˜๋Š” ์š”์ฒญ์„ ์„œ๋ฒ„๋กœ ์ „๋‹ฌํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๋”ฐ๋ผ์„œ ์„œ๋ฒ„์— ์š”์ฒญ์„ ์ถ”๊ฐ€์ ์œผ๋กœ ์ „์†กํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

  • ๋‹จ์ 

๋„๋ฉ”์ธ ์ฃผ์†Œ์˜ ๋’ค์ชฝ์— ๋ถˆํ•„์š”ํ•˜๊ฒŒ #๊ฐ€ ๋“ค์–ด๊ฐ‘๋‹ˆ๋‹ค.

ํ•˜๋‚˜์˜ ๋„๋ฉ”์ธ์— ์—ฌ๋Ÿฌ ์š”์ฒญ์„ ์ฒ˜๋ฆฌํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๊ฒ€์ƒ‰ ์—”์ง„ ์ตœ์ ํ™”์˜ ๋ฌธ์ œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.


[2] HTML5 ๋ชจ๋“œ(History ๋ชจ๋“œ)

// router HTML5 ๋ชจ๋“œ
export default createRouter({
  history: createWebHistory(),
  routes: [
    {
      path: "/",
      name: "home",
      component: Home,
    },
    {
      path: "/about",
      name: "about",
      component: About,
    },
    {
      path: "/documents",
      component: Docs,
      children: [
        {
          path: ":id",
          component: DocsId,
        },
      ],
    },
    {
      path: "/:notFound(.*)",
      component: NotFound,
    },
  ],
});


ํ•ด๋‹น ๋ชจ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ๋ช‡๊ฐ€์ง€ ์„ค์ •์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

// webpack.config.js
// ...

output: {
  path: path.resolve(__dirname, "dist"),
  publicPath: "/", // publicPath๋กœ script์˜ main.js๋ฅผ ์ ˆ๋Œ€ ๊ฒฝ๋กœ๋กœ ๋ถˆ๋Ÿฌ์˜ฌ ์ˆ˜ ์žˆ๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค.
  clean: true,
},

// ...
devServer: { // ์ €ํฌ๋Š” ๋กœ์ปฌ ์„œ๋ฒ„๋ฅผ ์ด์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์— devServer์— ์„ธํŒ…ํ•ฉ๋‹ˆ๋‹ค.
  historyApiFallback: true, // ํŠน์ •ํ•œ ๊ฒฝ๋กœ๋กœ ๋“ค์–ด๊ฐ”์„ ๋•Œ, index.html๋กœ ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ ์‹œ์ผœ์ค๋‹ˆ๋‹ค.
},


  • ์žฅ์ 

์ฃผ์†Œ๊ฐ€ ๊น”๋”ํ•ฉ๋‹ˆ๋‹ค.

๊ฒ€์ƒ‰ ์—”์ง„ ์ตœ์ ํ™”๊ฐ€ ํŽธ๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

  • ๋‹จ์ 

์—ฌ๋Ÿฌ ์ฃผ์†Œ๋งˆ๋‹ค ๋งค๋ฒˆ ์„œ๋ฒ„์— ๋Œ€ํ•œ ์š”์ฒญ์ด ๋“ค์–ด๊ฐ‘๋‹ˆ๋‹ค.


๐Ÿฅบ ๊ฐœ์ธ์ ์œผ๋ก  history mode๊ฐ€ ๋” ์‚ฌ์šฉ์„ฑ์ด ์ข‹์„ ๊ฒƒ ๊ฐ™๋‹ค๊ณ  ํŒ๋‹จํ–ˆ์Šต๋‹ˆ๋‹ค.


[1-2] ๋„ค๋น„๊ฒŒ์ด์…˜ ๊ฐ€๋“œ

๋„ค๋น„๊ฒŒ์ด์…˜์—๋Š” ๊ฐ๊ฐ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๊ฐ€๋“œ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.

Untitled

๋ผ์šฐํ„ฐ๋กœ ์ธํ•ด ๊ฒฝ๋กœ๊ฐ€ ๋ณ€๊ฒฝ๋˜๊ธฐ ์ด์ „, ๊ทธ๋ฆฌ๊ณ  ์ดํ›„์˜ ๋‹ค์–‘ํ•œ ๊ฒฝ์šฐ์— ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.


๊ฐ€๋“œ๋Š” ๋ณดํ†ต ๋ณ„๋„์˜ ํŒŒ์ผ์„ ๋งŒ๋“ค์–ด ์ž‘์„ฑํ•ฉ๋‹ˆ๋‹ค.

// guard.js
import router from "./index";
import store from "~/store";

router.beforeEach((to) => {
  // beforeEach ๊ฐ€๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ ‘๊ทผ ๊ถŒํ•œ์ด ์žˆ๋Š” ํŽ˜์ด์ง€์˜ ๋กœ๊ทธ์ธ ์—ฌ๋ถ€๋ฅผ ์ฒดํฌํ•ด์ค„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  console.log(to);
  if (to.meta.requiresAuth && !store.state.user.isLoggedIn) {
    return {
      path: "/login",
      query: { redirect: to.fullPath },
    };
  }
});


[1-3] ์Šคํฌ๋กค

SPA์—์„œ๋Š” ์Šคํฌ๋กค ์œ„์น˜๊ฐ€ ๊ณ ์ •๋ฉ๋‹ˆ๋‹ค.

home ํŽ˜์ด์ง€์—์„œ route ์ฒ˜๋ฆฌ๋กœ about ํŽ˜์ด์ง€๋กœ ์ด๋™ํ•˜๋”๋ผ๋„, ํ•ด๋‹น ์Šคํฌ๋กค์˜ ์œ„์น˜๋Š” ๊ณ ์ •๋œ ์ฑ„ ํŽ˜์ด์ง€ ์ด๋™์ด ์ผ์–ด๋‚ฉ๋‹ˆ๋‹ค.


Vue router์—์„œ๋Š” ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ๊ฒŒ ์Šคํฌ๋กค ๋™์ž‘์„ ์ œ์–ดํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.

// routes/index.js
export default createRouter({
  history: createWebHistory(),
  scrollBehavior() {
    return { top: 0 }; // ์Šคํฌ๋กค ์œ„์น˜๋ฅผ ํŠน์ • ์œ„์น˜๋กœ ๊ณ ์ •์‹œ์ผœ์ค„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  },

ํŠน์ •ํ•œ ์š”์†Œ์˜ ์œ„์น˜๋กœ ์Šคํฌ๋กค ์ด๋™, ๋ธŒ๋ผ์šฐ์ €๋ฅผ ์ค‘์‹ฌ์œผ๋กœ ๊ณ ์ •๋œ ์œ„์น˜๋กœ ์Šคํฌ๋กค ์ด๋™, ๋น„๋™๊ธฐ๋กœ ์œ„์น˜ ๋ณ€๊ฒฝ ๋“ฑ์˜ ๋‹ค์–‘ํ•œ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค.




[2] Babel

Babel์€ ์ตœ์‹ ์˜ JavaScript ๋ฌธ๋ฒ•์„ ๊ตฌํ˜•์˜ ๋ธŒ๋ผ์šฐ์ €์—์„œ๋„ ๋™์ž‘ํ•  ์ˆ˜ ์žˆ๊ฒŒ ์ด์ „์˜ JavaScript ๋ฌธ๋ฒ•์œผ๋กœ ๋ณ€ํ™˜์‹œ์ผœ์ฃผ๋Š” ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค.


๋ฐ”๋ฒจ์€ ๋‹ค์Œ์˜ ๋ช…๋ น์–ด๋กœ ์„ค์น˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

npm i -D @babel/core @babel/cli // babel core์™€ babel cli๋ฅผ ํ•จ๊ป˜ ์„ค์น˜ํ•ฉ๋‹ˆ๋‹ค.
"scripts": {
	"babel": "babel main.js"
}

์ง„์ž…์ ์„ ํ•จ๊ป˜ ์ง€์ •ํ•ด์ค˜์•ผ ํ•ฉ๋‹ˆ๋‹ค.


babel core๋Š” ์ง„์ž…์ ์— ์žˆ๋Š” ํŒŒ์ผ๋“ค์„ ๋ณ€ํ™˜ํ•ด์ฃผ๋Š” ์—ญํ• ์„ ํ•˜์ง€๋งŒ, ํ•ด๋‹น ๋ณ€ํ™˜๋˜๋Š” ์˜ต์…˜๋“ค์€ ์ง์ ‘ ์ง€์ •ํ•ด์ค˜์•ผ ํ•ฉ๋‹ˆ๋‹ค.

ํ•ด๋‹น ์˜ต์…˜๋“ค์€ babel.config.json (๋˜๋Š” js)ํŒŒ์ผ ๋‚ด๋ถ€์— ์ž‘์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.


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

๋”ฐ๋ผ์„œ ์ด๋ฅผ ๋ฌถ์–ด๋†“์€ preset-env ํŒจํ‚ค์ง€๋ฅผ ์„ค์น˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

npm i -D @babel/preset-env
{
  "presets": ["@babel/preset-env"]
}

ํ•ญ์ƒ ์„ค์น˜ ํ›„์—๋Š” babel.config.json์— ๋“ฑ๋กํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค!


[2-1] Transform runtime

Babel์€ JS์˜ ์ตœ์‹  ์ฝ”๋“œ๋ฅผ ๊ตฌํ˜• ์ฝ”๋“œ๋กœ ๋ณ€ํ™˜ํ•ด์ค๋‹ˆ๋‹ค.

์ด๋ ‡๊ฒŒ ๋ณ€ํ™˜๋œ ๊ฒฐ๊ณผ๋Š” ์ „์—ญ์œผ๋กœ ๋“ฑ๋ก์ด ๋˜๊ธฐ ๋•Œ๋ฌธ์— ์ „์—ญ์ด ์˜ค์—ผ๋  ์ˆ˜ ์žˆ๋‹ค๋Š” ๋‹จ์ ์ด ์žˆ์Šต๋‹ˆ๋‹ค.


์ด๋ฅผ ๋ณด์™„ํ•˜๊ธฐ ์œ„ํ•ด transform-runtime ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

ํ•ด๋‹น ํ”Œ๋Ÿฌ๊ทธ์ธ์€ ์ „์—ญ์ด ์˜ค์—ผ๋˜์ง€ ์•Š๊ณ ๋„ ๋ณ€ํ™˜๋œ ์ฝ”๋“œ๊ฐ€ ์‹คํ–‰๋  ์ˆ˜ ์žˆ๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค.

๋˜ํ•œ ์‹ค์ œ๋กœ ์ž‘์„ฑํ•œ ์ฝ”๋“œ๋งŒ ๋ณ€ํ™˜์‹œ์ผœ์ฃผ๊ธฐ ๋•Œ๋ฌธ์—, ์ฝ”๋“œ์˜ ์šฉ๋Ÿ‰ ๋˜ํ•œ ์ ˆ์•ฝํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

npm i -D @babel/plugin-transform-runtime @babel/runtime-corejs3
{
  "presets": ["@babel/preset-env"],
  "plugins": [
    [
      "@babel/plugin-transform-runtime",
      {
        "corejs": 3
      }
    ]
  ]
}

corejs์˜ ๋ฒ„์ „์ด 3์ด์–ด์•ผ includes์™€ ๊ฐ™์€ ๋ฉ”์†Œ๋“œ๋„ ์™„๋ฒฝํ•˜๊ฒŒ ๋ณ€ํ™˜์‹œํ‚ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.


[2-2] browserslist

ํ˜„์žฌ ์›น ํŽ˜์ด์ง€๊ฐ€ ๋™์ž‘ํ•  ๋ธŒ๋ผ์šฐ์ €์˜ ๋ฒ”์œ„๋ฅผ ์ง€์ •ํ•ด์ค„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด๋Š” package.json ํŒŒ์ผ์— ๋“ฑ๋กํ•˜๋ฉฐ, ๋ฌธ์ž์—ด์„ ๋‹ด์€ ๋ฐฐ์—ด ํ˜•ํƒœ๋กœ ์ž‘์„ฑํ•ฉ๋‹ˆ๋‹ค.

"browserslist" : [
	"> 1%",
	"last 2 versions",
	"not dead"
]

์ด๋Ÿฌํ•œ ๋ธŒ๋ผ์šฐ์ €๋“ค์˜ ๋ฒ”์œ„๋ฅผ ์ง€์ •ํ•˜์ง€ ์•Š์œผ๋ฉด, ๋ฐ”๋ฒจ๋กœ ์ฝ”๋“œ๋ฅผ ๋ณ€ํ™˜ํ•ด์•ผ ํ•˜๋Š” ๋ฒ”์œ„๊ฐ€ ๋„“์–ด ๋น„ํšจ์œจ์ ์ž…๋‹ˆ๋‹ค.
๋”ฐ๋ผ์„œ ์ด๋Ÿฌํ•œ ๋ธŒ๋ผ์šฐ์ €์˜ ๋ฒ”์œ„๋ฅผ ๋ช…์‹œํ•˜๋Š” ๊ฒƒ์ด ํ•„์ˆ˜์ ์ž…๋‹ˆ๋‹ค.


[2-3] webpack๊ณผ babel

webpack๊ณผ babel์„ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” webpack ์ฝ”์–ด ํŒจํ‚ค์ง€ ์™ธ์— babel-loader๋ฅผ ์„ค์น˜ํ•ด์ค˜์•ผ ํ•ฉ๋‹ˆ๋‹ค.

// webpack.config.js
module: {
  rules: [
    {
      test: /\.vue$/,
      use: "vue-loader",
    },
    {
      test: /\.s?css$/,
      use: ["vue-style-loader", "css-loader", "sass-loader"],
    },
		{
      test: /\.js$/,
			exclude: /node_modules/,
      use: "babel-loader",
			// js ํŒŒ์ผ์„ ๋งŒ๋‚˜๋ฉด babel-loader๋ฅผ ๋™์ž‘ ์‹œํ‚ต๋‹ˆ๋‹ค.
			// ๊ทธ ๊ฒฐ๊ณผ๋ฅผ ์›นํŒฉ์˜ ์ตœ์ข… ๋ฒˆ๋“ค๋กœ ์ถœ๋ ฅํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
			// node_modules๋Š” ์ œ์™ธํ•ฉ๋‹ˆ๋‹ค.
    },
  ],
},




[3] PortCSS, Autoprefixer

PostCSS๋Š” scss์™€ ๊ฐ™์€ ์ „์ฒ˜๋ฆฌ ๋„๊ตฌ๊ฐ€ ์•„๋‹Œ ํ›„์ฒ˜๋ฆฌ ๋„๊ตฌ์ž…๋‹ˆ๋‹ค.

๋ฐ”๋ฒจ๊ณผ ๊ฐ™์ด ์ฝ”๋“œ๋ฅผ ๋ณ€ํ™˜ํ•˜๊ณ  ํ›„์ฒ˜๋ฆฌํ•˜๋Š” ์—ญํ• ์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.


PostCSS์ค‘ ๊ฐ€์žฅ ๋Œ€ํ‘œ์ ์ธ ํ”Œ๋Ÿฌ๊ทธ์ธ์ด Autoprefixer์ž…๋‹ˆ๋‹ค.

์ด ๋‘˜์„ ์ด์šฉํ•ด์„œ display: flex, grid์™€ ๊ฐ™์ด CSS ์ตœ์‹  ๊ธฐ์ˆ ๋“ค์„ ์ด์ „์˜ ๋ฌธ๋ฒ•๋“ค๋กœ ๋ณ€ํ™˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.


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

npm i -D postcss autoprefixer postcss-loader

Postcss์™€ Autoprefixer, webpack์˜ postcss-loader๋„ ํ•จ๊ป˜ ์„ค์น˜ํ•ฉ๋‹ˆ๋‹ค.

// webpack.config.js
{
  test: /\.s?css$/,
  use: [
    "vue-style-loader",
    "css-loader",
    "postcss-loader",
    "sass-loader",
  ],
},
// ๊ธฐ์กด์˜ ์Šคํƒ€์ผ ๋กœ๋”, css ๋กœ๋” ๋“ฑ๊ณผ ํ•จ๊ป˜ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.


PostCSS๋Š” postcss.config.js์— ์—ฌ๋Ÿฌ ์˜ต์…˜๋“ค์„ ์ง€์ •ํ•ด์ค˜์•ผ ํ•ฉ๋‹ˆ๋‹ค.

// postcss.config.js
module.exports = {
  plugins: [require("autoprefixer")],
};

๋ฐ”๋ฒจ๊ณผ ๋™์ผํ•˜๊ฒŒ browserslist๋ฅผ ์ง€์ •ํ•ด์ค˜์•ผ ํ•ฉ๋‹ˆ๋‹ค.




[4] Webpack Template

์ง€๊ธˆ๊นŒ์ง€ ๋ฐฐ์šด ๋ชจ๋“  vuex, babel, postCSS ๋“ฑ์„ webpack์— ์ ์šฉํ•ด๋ณด๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.

// webpack.config.js
const path = require("path");
const { VueLoaderPlugin } = require("vue-loader");
const HtmlPlugin = require("html-webpack-plugin");
const CopyPlugin = require("copy-webpack-plugin");

module.exports = {
  resolve: {
    extensions: [".vue", ".js"],
    alias: {
      "~": path.resolve(__dirname, "src"),
    },
  },
  entry: "./src/main.js",
  output: {
    path: path.resolve(__dirname, "dist"),
    publicPath: "/",
    clean: true,
  },
  module: {
    rules: [
      {
        test: /\.vue$/,
        use: "vue-loader",
      },
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: "babel-loader",
      },
      {
        test: /\.s?css$/,
        use: [
          "vue-style-loader",
          "css-loader",
          "postcss-loader",
          "sass-loader",
        ],
      },
    ],
  },
  plugins: [
    new VueLoaderPlugin(),
    new HtmlPlugin({
      template: "./src/index.html",
    }),
    new CopyPlugin({
      patterns: [{ from: "static" }],
    }),
  ],
  devServer: {
    historyApiFallback: true,
  },
};

์ด๋Ÿฌํ•œ ํ…œํ”Œ๋ฆฟ์„ ์ €์žฅ์†Œ์— ์˜ฌ๋ ค๋†“๊ณ , ํ•„์š”ํ•  ๋•Œ ๋งˆ๋‹ค ๋ถˆ๋Ÿฌ์™€์„œ ์‚ฌ์šฉํ•˜๋ฉด ํŽธ๋ฆฌํ•ฉ๋‹ˆ๋‹ค. ๐Ÿ˜Š





์ถœ์ฒ˜

https://router.vuejs.org/

https://babeljs.io/

ํ”„๋กœ๊ทธ๋ž˜๋จธ์Šค

Vue.js3 Document

์นดํ…Œ๊ณ ๋ฆฌ: ,

์—…๋ฐ์ดํŠธ:

๋Œ“๊ธ€๋‚จ๊ธฐ๊ธฐ