원문: https://bit.ly/2E1zTUz
이 글은 번역한 내용이 아니라 원문 내용 공부할 목적으로 작성한 내용입니다🤣

일반적으로 Vue로 개발할 때, vue-cli를 사용하여 프로젝트 구조를 생성합니다.
아래 내용은 vue-cli를 사용하지 않고, vue 단일 파일 컴포넌트를 빌드하는 방법을 설명합니다.

vue.js의 CDN을 사용하면 스크립트 태그를 사용하여 자바스크립트 코드를 실행시킬 수 있습니다. 하지만, vue 단일 파일 컴포넌트를 사용하기 위해서는 .vue 파일을 컴파일하고 번들링하는 작업이 필요합니다.
아래 내용에서는 babelwebpack을 사용합니다.

프로젝트 환경 구성시에 NPM(Node Package Manager)을 사용하므로 NPM이 설치되어있어야 합니다.

개발환경 만들기

1) 프로젝트 구조 만들기

기본적으로 필요한 파일을 아래와 같은 구조로 생성합니다.

- src
  -- main.js
  -- index.html
  -- App.vue
- .babelrc.js
- package.json
- webpack.config.js

2) 프로젝트에 필요한 의존성 설치하기

의존성을 설치하기 전에 npm init으로 package.json을 생성합니다.

  • package.json
{
  "name": "vue-hello-world",
  "version": "1.0.0",
  "description": "",
  "main": "main.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC"
}
  • vue 프로젝트 빌드에 필요한 의존성 항목들을 모두 설치합니다.
> npm install vue vue-loader vue-template-compiler webpack webpack-cli webpack-d
ev-server babel-loader @babel/core @babel/preset-env css-loader vue-style-loader html-webpack-plugin rimraf -D

vue: JavaScript 프레임 워크
vue-loadervue-template-compiler: Vue 파일을 JavaScript로 변환하는 데 사용됩니다.
webpack: 일부 변형을 통해 코드를 전달하고 하나의 파일로 묶을 수있는 도구입니다.
webpack-cli: Webpack 명령을 실행하는 데 필요합니다.
webpack-dev-server: 로컬에서 개발 서버를 실행하는데 필요합니다.
babel-loader: ES6 코드를 ES5로 변환합니다. (다음 두 가지 종속성에 도움이 필요합니다.)
@babel/core@babel/preset-env: babel 자체는 코드에 아무런 영향을 미치지 않습니다. 이 두 가지기능을 사용하면 ES6 코드를 ES5 코드로 변환 할 수 있습니다.
css-loader: .vue 파일에 작성한 CSS 또는 JavaScript 파일로 가져올 CSS를 가져 와서 해당 파일의 경로를 확인합니다.
vue-style-loader: css-loader로 가져온 CSS을 HTML 파일에 삽입합니다. 이렇게 하면 HTML 문서의 header 부분에 스타일 태그가 만들어져 삽입됩니다.
html-webpack-plugin: index.html을 가져 와서 번들 된 JavaScript 파일을 header에 삽입합니다. 그 다음 dist 폴더에 복사합니다.
rimraf: 명령 줄에서 파일 삭제를 허용합니다. 여러번 프로젝트를 빌드할 때 유용하며, 이것을 사용하여 오래된 빌드를 삭제합니다.

npm install 스크립트 끝에있는 "-D" 옵션은 각 종속성을 package.json의 devDependencies로 표시합니다. 하나의 파일에 모든 종속성을 묶어 놓기 때문에 이 프로젝트에는 프로덕션 종속성이 없습니다.

3) 기본 코드 작성

  • App.vue
<template>
  <div id="app">
    {{ message }}
  </div>
</template>

<script>
export default {
  data() {
    return {
      message: 'Hello World',
    };
  },
};
</script>

<style>
#app {
  font-size: 18px;
  font-family: 'Roboto', sans-serif;
  color: blue;
}
</style>
  • index.html
<html>
  <meta charset="utf-8" />
  <head>
    <title>Vue Hello World</title>
  </head>
  <body>
    <div id="app"></div>
  </body>
</html>
  • main.js
import Vue from 'vue';
import App from './App.vue';

new Vue({
  el: '#app',
  render: h => h(App)
});
  • .babelrc.js
module.exports = {
  presets: ['@babel/preset-env'],
}

preset-env는 자바스크립트의 확정되지 않은 proposal 스펙의 모든 stage의 preset 입니다. (자세한 내용은 여기로.. Babel에 대한 모든 것)

4) Webpack 설정하기

  • webpack.config.js
const HtmlWebpackPlugin = require('html-webpack-plugin');
const VueLoaderPlugin = require('vue-loader/lib/plugin');

module.exports = {
  entry: './src/main.js',
  module: {
    rules: [
      { test: /\.js$/, use: 'babel-loader' },
      { test: /\.vue$/, use: 'vue-loader' },
      { test: /\.css$/, use: ['vue-style-loader', 'css-loader']},
    ]
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html',
    }),
    new VueLoaderPlugin(),
  ]
};

환경설정을 살펴보면, rules에 의해 적용 또는 변환되는 내용이 entry로 설정한 파일에 삽입되고, 여기서 사용되는 플러그인을 plugins에 설정하는 내용입니다.

babel-loader를 통해 ES6+ 구문을 ES5로 변환하고, vue-loader를 사용해 .vue 파일을 자바스크립트로 로 변환합니다. vue-style-loadercss-loader를 사용해 .css파일과 .vue에 작성된 스타일 태그와 자바스크립트 코드의 CSS를 가져와서 스타일 태그로 HTML에 삽입합니다.

5) webpack을 실행할 수 있도록 package.json 설정하기

모든 작업을 마쳤으므로 이제 프로그램을 실행할 수 있습니다. 이 환경을 실행하는데 webpack-dev-server를 사용합니다. package.jsontest 스크립트를 삭제하고 아래 내용을 추가합니다.

"serve": "webpack-dev-server --mode development"

이제 프로그램을 실행할 수 있습니다.

npm run serve

6) HMR(Hot Module Replacement) 추가하기

현재의 환경은 스크립트를 수정하면 브라우저가 새로고침되고, 스크립트와 페이지가 다시 로드되기 때문에 변경된 항목이 화면이 반영됩니다. 하지만, 데이터는 유지되지 않습니다. 아래와 같이 코드를 조금 수정하고 input에 텍스트를 입력한 다음 <h3> 태그 내용을 변경하고 저장하면, input에 입력한 값이 초기값으로 변경되는것을 알 수 있습니다.

<template>
  <div id="app">
    <input
      v-model="message"
      type="text">
      <h2 class="message">{{ message }}</h2>
      <h3>Some Other Message</h3>
  </div>
</template>

<script>
export default {
  data() {
    return {
      message: 'Hello world!',
    };
  },
};
</script>

<style>
.message {
  font-size: 18px;
  font-family: 'Roboto', sans-serif;
  color: blue;
}
</style>

이처럼 프로그램을 작성하고 데이터를 추가할 때마다 매번 데이터가 재설정되는것은 매우 불편합니다. 다행히 Webpack은 HMR(Hot Module Replacement)라는 솔루션을 제공합니다.

  • webpack.config.js
const HtmlWebpackPlugin = require('html-webpack-plugin');
const VueLoaderPlugin = require('vue-loader/lib/plugin');
const webpack = require('webpack');

module.exports = {
  entry: './src/main.js',
  module: {
    rules: [
      { test: /\.js$/, use: 'babel-loader' },
      { test: /\.vue$/, use: 'vue-loader' },
      { test: /\.css$/, use: ['vue-style-loader', 'css-loader'] }
    ]
  },
  devServer: {
    open: true,
    hot: true
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html'
    }),
    new VueLoaderPlugin(),
    new webpack.HotModuleReplacementPlugin()
  ]
};

Webpack에 액세스 할 수 있도록 webpack을 가져오고, hotModuleReplacementPlugin을 plugins 배열에 추가 한 다음, Webpack에서 사용하도록 hot: true를 설정했습니다. open: truewebpack-dev-server을 실행할 때 브라우저 창을 자동으로 엽니다.
다시 프로그램을 실행하고 <h3>태그의 내용을 변경하면 input 값이 유지되는 것을 확인할 수 있습니다.

7) 프로젝트 빌드하기

작성한 프로그램을 배포하기 위해서는 webpack-dev-server가 아닌 webpack을 사용하여 프로그램을 빌드해야 합니다. 이 과정에서 이전 빌드를 삭제하기 위해 rimraf를 사용합니다.

dist는 Webpack이 프로젝트를 빌드 할 때 자동으로 생성되는 폴더입니다.

package.json에 clean과 build를 스크립트를 추가합니다.

  • package.json
"scripts": {
    "clean": "rimraf dist",
    "build": "npm run clean && webpack --mode production",
    "serve": "webpack-dev-server --mode development"
  },

이제 프로젝트를 빌드할 수 있습니다.

npm run build

dist 폴더의 index.html을 직접 실행하여 프로그램이 동작하는 것을 확인할 수 있습니다.

Webpack을 --production 모드로 빌드하였기 때문에 개발 콘솔 정보를 확인할 수 없고, 스타일 태그가 자바스크립트 런타임에 동적으로 삽입되기 때문에 스타일을 볼 수 없습니다.

결론

vue-cli 3을 사용하자


참조

vue cli babel 설정
https://github.com/vuejs/vue-cli/blob/dev/packages/%40vue/babel-preset-app/README.md
vue cli webpack 설정
https://github.com/vuejs/vue-cli/blob/dev/packages/%40vue/cli-service/lib/config/base.js
vue cli 3.0 설명
https://jaeyeophan.github.io/2018/10/21/Vuetorials-1-vue-cli-3-0/