TIL/개념정리

vanilla js로 간단하게 spa 구현

초집중 2023. 1. 8. 20:43

Vanilla JS로 SPA 구현

 

유튜브를 참고해서 바닐라 js로 간단하게 spa 구조를 잡는 것을 실습해보았다.

 

기존의 history 방식으로 구현된다는 것은 대충 알고 있었는데 실제로 구현해보니 잘 이해할 수 있었다. 조금 헷갈렸던 부분이 이벤트 리스너를 달아주는 부분이었는데 찾아보니 다양한 이벤트를 감지할 수 있었다는 것을 알았다.

 

import Home from "./Home.js";
import Posts from "./Posts.js";
import Settings from "./Setting.js";
import NotFound from "./NotFound.js";

function navigateTo(url) {
  history.pushState(null, null, url);
  router();
}

async function router() {
  const routes = [
    { path: "/", view: Home },
    { path: "/posts", view: Posts },
    { path: "/settings", view: Settings },
  ];

  const potentialMatches = routes.map((route) => {
    return {
      route,
      isMatch: location.pathname === route.path,
    };
  });

  //주어진 라우터가 있는지 확인 없으면 undefined 리턴
  //있다면 일치하는 첫 번째 값을 리턴해준다.
  //따라서 현재 라우터와 일치하는 값을 리턴해준다
  let match = potentialMatches.find((potentialMatch) => potentialMatch.isMatch);

  // 404페이지로 이동하기
  if (!match) {
    match = {
      route: routes[routes.length - 1],
      isMatch: true,
    };
    const page = new NotFound();
    document.querySelector("#root").innerHTML = await page.getHtml();
  } else {
    const page = new match.route.view();
    document.querySelector("#root").innerHTML = await page.getHtml();
  }
}

document.addEventListener("DOMContentLoaded", () => {
  document.body.addEventListener("click", (e) => {
    if (e.target.matches("[data-link]")) {
      e.preventDefault();
      history.pushState(null, null, e.target.href);
      router();
    }
  });
  router();
});

window.addEventListener("popstate", () => {
  router();
});

간단하게 구현해보고 프로그래머스 과제 테스트 참고해보러 갔는데 아무래도 직접 구현하진 못할거같다는 느낌이 강하게 들었다.

그래서 앞으로는 js 쪽을 더 공부해보려고 한다.

 

SPA 구현한 것에 웹팩 적용해보기

 

구현된 부분의 규모가 크지 않아서 그런지 눈에 띄는 결과는 나오지 않았지만 원하는 결과는 확인했다.

const path = require("path");
const HtmlWebpackPlugin = require("html-webpack-plugin");

module.exports = {
  mode: "none",
  entry: "./frontend/static/js/index.js",
  output: {
    filename: "bundle.js",
    path: path.resolve(__dirname, "dist"),
  },
  module: {
    rules: [
      {
        // css로더
        test: /\.css$/,
        use: ["style-loader", "css-loader"],
        exclude: /node_modules/,
      },
    ],
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: path.resolve(__dirname, "frontend", "index.html"),
    }),
  ],
};

 

Webpack으로 번들링 시키기 전

 

Webpack으로 번들링 시키고 난 후

요청하는 js파일이 5가지였는데 하나의 파일로 만들게 되면서 요청횟수를 확실히 줄일 수 있어 성능적으로 향상시킬 수 있다는 것을 알 수 있었다