원문: https://bit.ly/2E1zTUz
이 글은 번역한 내용이 아니라 원문 내용 공부할 목적으로 작성한 내용입니다🤣
일반적으로 Vue로 개발할 때, vue-cli를 사용하여 프로젝트 구조를 생성합니다.
아래 내용은 vue-cli를 사용하지 않고, vue 단일 파일 컴포넌트를 빌드하는 방법을 설명합니다.
vue.js의 CDN을 사용하면 스크립트 태그를 사용하여 자바스크립트 코드를 실행시킬 수 있습니다. 하지만, vue 단일 파일 컴포넌트를 사용하기 위해서는 .vue
파일을 컴파일하고 번들링하는 작업이 필요합니다.
아래 내용에서는 babel
과 webpack
을 사용합니다.
프로젝트 환경 구성시에 NPM(Node Package Manager)을 사용하므로 NPM이 설치되어있어야 합니다.
기본적으로 필요한 파일을 아래와 같은 구조로 생성합니다.
- src
-- main.js
-- index.html
-- App.vue
- .babelrc.js
- package.json
- webpack.config.js
의존성을 설치하기 전에 npm init
으로 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"
}
> 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-loader
및 vue-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
로 표시합니다. 하나의 파일에 모든 종속성을 묶어 놓기 때문에 이 프로젝트에는 프로덕션 종속성이 없습니다.
<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>
<html>
<meta charset="utf-8" />
<head>
<title>Vue Hello World</title>
</head>
<body>
<div id="app"></div>
</body>
</html>
import Vue from 'vue';
import App from './App.vue';
new Vue({
el: '#app',
render: h => h(App)
});
module.exports = {
presets: ['@babel/preset-env'],
}
preset-env는 자바스크립트의 확정되지 않은 proposal 스펙의 모든 stage의 preset 입니다. (자세한 내용은 여기로.. Babel에 대한 모든 것)
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-loader
와 css-loader
를 사용해 .css
파일과 .vue
에 작성된 스타일 태그와 자바스크립트 코드의 CSS를 가져와서 스타일 태그로 HTML에 삽입합니다.
모든 작업을 마쳤으므로 이제 프로그램을 실행할 수 있습니다. 이 환경을 실행하는데 webpack-dev-server
를 사용합니다. package.json
에 test
스크립트를 삭제하고 아래 내용을 추가합니다.
"serve": "webpack-dev-server --mode development"
이제 프로그램을 실행할 수 있습니다.
npm run serve
현재의 환경은 스크립트를 수정하면 브라우저가 새로고침되고, 스크립트와 페이지가 다시 로드되기 때문에 변경된 항목이 화면이 반영됩니다. 하지만, 데이터는 유지되지 않습니다. 아래와 같이 코드를 조금 수정하고 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)라는 솔루션을 제공합니다.
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: true
은 webpack-dev-server
을 실행할 때 브라우저 창을 자동으로 엽니다.
다시 프로그램을 실행하고 <h3>
태그의 내용을 변경하면 input
값이 유지되는 것을 확인할 수 있습니다.
작성한 프로그램을 배포하기 위해서는 webpack-dev-server
가 아닌 webpack
을 사용하여 프로그램을 빌드해야 합니다. 이 과정에서 이전 빌드를 삭제하기 위해 rimraf
를 사용합니다.
dist
는 Webpack이 프로젝트를 빌드 할 때 자동으로 생성되는 폴더입니다.
package.json
에 clean과 build를 스크립트를 추가합니다.
"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/
cli 로 구성안할경우 느끼신 장점이 있으실까요?