Vue 프로젝트를 단일 HTML 파일로 빌드하기

Kyu·2020년 12월 16일
1
post-thumbnail

Vue3를 이용하여 작성하였는데, vue.config 사용방식은 동일하여 Vue2에도 적용이 가능합니다.
vue-router 이전버전에서는 router mode를 hash로 변경해야 합니다.

Vue 프로젝트를 HTML 파일 한개로 빌드하기

어쩌다가 가벼운(?) 어드민을 만들었는데, 하나의 HTML 파일로 번들링을 하게되었다.
요즘은 프레임워크 위에서 라이브러리들을 이것저것 사용하다보니 가급적 파일을 chunk로 나눠서 배포하고 있어서 처음 겪는 상황에 좀 당황스럽긴했다. 처음에는 html 파일의 head에 embed script 링크에 빌드된 항목들이 inline으로 들어가면 될거라고 생각했는데, 가만 생각해보니 페이지별로 라우터에서 lazy loading을 사용하고 있었다...

1) 웹팩 설정하기

웹팩 설정은 플러그인을 검색해서 해결할 수 있었는데, 요즘은 잘 사용하지 않는 방식이라 그런지 해당 플러그인이 beta로 배포되고도 Readme가 업데이트 되지 않아서 좀 헤맨것 같다.
웹팩 플러그인html-webpack-pluginhtml-webpack-inline-source-plugin@beta를 설치하고 vue.config.js 파일을 수정한다.

npm install -D html-webpack-plugin html-webpack-inline-source-plugin@beta
// vue.config.js
const HtmlWebpackPlugin = require('html-webpack-plugin')
const HtmlWebpackInlineSourcePlugin = require('html-webpack-inline-source-plugin')

module.export = {
  css: {
    extract: false,
  },
  configureWebpack: {
    optimization: {
      splitChunks: false, // 코드 스플리팅 사용 안함
    },
    plugins: [
      new HtmlWebpackPlugin({
        filename: 'output.html', // the output file name that will be created
        template: 'src/output.html', // this is important - a template file to use for insertion
        inlineSource: '.(js|css)$', // embed all javascript and css inline
      }),
      new HtmlWebpackInlineSourcePlugin(HtmlWebpackPlugin),
    ],
  },
}

HtmlWebpackPlugin에서 사용할 template 파일을 만들어주어야 한다.

<!-- src/output.html 템플릿 파일 -->
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width,initial-scale=1" />
    <title>example title</title>
  </head>
  <body>
    <noscript
      ><strong
        >We're sorry but my example doesn't work properly without JavaScript enabled. Please enable it to
        continue.</strong
      ></noscript
    >
    <div id="app"></div>
  </body>
</html>

2) 라우터 모드 변경하기

Vue router를 사용하면 페이지별로 별도의 스크립트 파일이 생성되고, 사이트 진입시 로딩되거나 동적으로 로딩하는 경우 페이지 진입시에 스크립트가 로딩된다. 단일 HTML로 동작하는 경우, 브라우저의 navigation이 현재 HTML 파일의 경로를 벗어나면 동작하지 않기 때문에 고전적인 방법인 hash 방식의 라우팅을 사용해야 한다.

// vue-router 4
import { createRouter, createWebHashHistory, RouteRecordRaw } from 'vue-router'
import Home from '@/pages/Home.vue'
import Page from '@/pages/Page.vue'

const routes: Array<RouteRecordRaw> = [
  {
    path: '/',
    redirect: '/home',
  },
  {
    name: 'home',
    path: '/home',
    component: Home,
  },
  {
    name: 'page',
    path: '/page',
    component: Page,
  },
]

const router = createRouter({
  history: createWebHashHistory(process.env.BASE_URL)
  routes,
})

export default router

이렇게 하면 브라우저 URL에 #가 붙어서 지저분해지긴 하지만, Vue-router를 사용하고도 단일 HTML로 번들링이 가능하게된다.

0개의 댓글