지금까지는 리액트를 사용하면서 웹사이트를 개발을 했다. 그런데 이번에는 새로운걸 도전해보고 싶어서 vue.js를 ts와 webpack으로 사용해보고 그 과정을 기록해보겠다. 처음 도전하는데 어려움이 있는 경우 이 글을 읽으면 Hello, world를 찍을수 있으니 잘 따라오도록 하자.
mkdir vue-webpack && cd vue-webpack
yarn init -y
package.json
은 아래와 같을 것이다.
{
"name": "vue-webpack",
"version": "1.0.0",
"main": "index.js",
"license": "MIT",
}
typescript를 사용할것이므로 tsconfig.json
을 설정해준다.
{
"compilerOptions": {
"module": "CommonJS",
},
"include": [
"./src/**/*",
]
}
다음으로 이 프로젝트에 필요한 라이브러리를 설치하자.
yarn add vue vue-loader vue-template-compiler vue-styleloader typescript ts-loader css-loader webpack webpack-cli webpack-dev-server
- vue: vue를 사용하기 위함
- vue-loader: vue를 단일 파일 컴포넌트를 지원함
- vue-template-compiler: vue의 template을 컴파일하기 위함?(이게 없으니 에러가떠서 추가해줌)
- vue-styleloader: .vue안에 있는 style태그를 사용하기 위함
- typescript: typescript를 사용하기 위함
- ts-loader: ts를 해석하기 위함
- css-loader: css파일을 사용하기 위함
- webpack: webpack을 사용하기 위함
- webpack-cli: webpack 명령어로 build 등을 하기 위함
- webpack-dev-server: 코드의 변경사항을 바로 적용하기 위함
webpack.config.js
의 파일은 아래와 같을 것이다.
var path = require('path')
var webpack = require('webpack')
const VueLoaderPlugin = require('vue-loader/lib/plugin');
module.exports = {
entry: './src/main.ts', // 최초 실행될 entry 파일
output: {
path: path.resolve(__dirname, './dist'), build 결과가 저장될 폴더
publicPath: '/dist/', // 이걸 지우게 되면 css가 적용이 안되는게 확인됨. 약간 경로 관련해서 문제가 있던걸로 기억하는데 일단 path랑 똑같이 지정해준다.
filename: 'build.js' // build 결과 파일 이름
},
module: {
rules: [ // build 규칙들
{
test: /\.vue$/, // .vue파일을
loader: 'vue-loader' // vue-loader로 해석
},
{
test: /\.ts$/, // .ts파일을
loader: 'ts-loader' // ts-loader로 해석
},
{
test: /\.css$/, // .css파일을
use: [
'vue-style-loader', // vue-style-lodaer을 이용해서
{
loader: 'css-loader', // css-loader로 해석. 구글링을 찾은 방법
}
]
}
]
},
devServer: { // webpack-dev-server 옵션 설정
host: "localhost", // localhost 설정
port: 5500, // 포트 설정
// noInfo: true, // true로 했더니 실행이 안되는줄알고 몇시간 삽질을 했다. 지워주자.
open: true, // localhost:5500 으로 새탭 열림
},
plugins: [
new VueLoaderPlugin() // 이것도 오류가나서 내용 보니까 설정해주라 해서 설정해줌.
]
}
./src/components/main.ts
코드를 짜보자.
import Vue from 'vue';
import App from './App.vue';
new Vue({
render: h => h(App),
}).$mount('#app');
위 코드를 해석하자면
참고 블로그
render: function(createElement) {
return createElement(App);
}
일반적으로 h는 hyperscript의 약자로 Virtural DOM에서 관용적으로 사용되는 표현인데 HTML 구조를 생성하는 스크립트라는 의미 라고 에반유는 이야기하고 있다.
또 new Vue({ ... }).$mount('#app')
이 부분은
공식문서에 나와 있듯이 id가 app인 태그에 엘리먼트를 삽입하는 부분이다.
var MyComponent = Vue.extend({
template: '<div>Hello!</div>'
})
// 생성하고 #app에 마운트 합니다.(#app을 대체합니다)
new MyComponent().$mount('#app')
// 위와 같습니다.
new MyComponent({ el: '#app' })
// 또는 문서를 렌더링하고 나중에 추가할 수 있습니다.
var component = new MyComponent().$mount()
document.getElementById('app').appendChild(component.$el)
vue 관련 코드에 관한 설명은 블로그여기에서 이해를 해보자.
App.vue
코드를 살펴보자.
<template> // template는 html template를 짜는 부분인것 같다.
<div id="app">
<HelloWorld msg="Welcome to Yout Vue.js App" /> // HelloWorld 컴포넌트에 msg props로 넘겨준 모습으로 예측된다.
</div>
</template>
<script>
import HelloWorld from './components/HelloWorld.vue'; // 다른 컴포넌트를 임포트한다.
export default { // 반드시 객체를 export 해줘야 한다.
name: 'app',
components: {
HelloWorld, // HelloWorld 컴포넌트를 <HelloWorld>로 사용하겠다고 정의, "HelloWorld": HelloWorld와 같음
}
}
</script>
<style>
#app {
background-color: #000000;
}
</style>
./src/components/HelloWorld.vue
코드는 아래와 같다.
<template>
<div>
<p>{{ greeting }} world!</p>
</div>
</template>
<script>
export default {
data: () => ({ greeting: 'hello' }) // data가 약간 react state같은 개념 {{ greeting }} 으로 접근 가능한것을 볼 수 있다.
}
</script>
<style>
p {
font-size: 40px;
color: white;
}
</style>
이렇게만 하면 오류가 나게 되는데 아마 App.vue를 import할수 없을 것이다. 이러한 경우엔 커스텀 d.ts 파일을 생성해줘야 하는데 직접하기엔 아직이여서 구글링으로 파일을 찾았다. 아래와 같다.
./src/components/vue-shim.d.ts
declare module "*.vue" {
import Vue from "vue";
export default Vue;
}
./index.html
을 생성해주자.
<!DOCTYPE html>
<html>
<head></head>
<body>
<div id="app">
</div>
<script src="./dist/build.js"></script> // webpack build 후 스크립트 삽입
</body>
</html>
package.json
에 명령어를 추가해주자.
...
"scripts": {
"build": "webpack", // webpack build
"start:dev": "webpack-dev-server --hot" // 개발시 코드 수정시 자동 반영
},
...
이제 개발 서버를 켜 결과를 확인해보자.
yarn start:dev
아래와 같이 잘 작동되고 hello world를 다르게 변경시켜도 바로 반영이 되는걸 볼 수 있다.
전체 코드는 github-uchanlee에서 확인할 수 있다.
이틀간 vue.js를 ts, webpack으로 처음 실행해 봤는데 엄청 삽질을 많이 했다. 확실히 리액트와 다른부분이 있고 비슷한 개념도 있는것 같다. 이걸 개인프로젝트에 적용시킬지는 한번 고민해봐야할 문제인것 같다. vue또한 좋은 라이브러리임은 분명하다. 나중에 기회가 된다면 vue를 자세하게 파볼 생각이다.