從0開始一個Vue.js + TypeScript + Webpack專案
最後一次寫前端的時間是AngularJs正火紅的時候,大約有四年之久...
近期因為新專案的需要,想找一個前端框架來學習
經過評估後,則是選擇用vue.js以及搭配TypeScript做開發
筆記一下整個歷程,也許不是正確的、也許漏了一些細節
但是他是work的🤣
開發環境
vue.js 2.6.11
typescript 3.8.3
Asp.Net Core 3.1(MVC)
在開始之前,記得先準備好前端的套件管理工具 npm,前端的許多步驟都會透過他來處理
1.建立一個新專案,初始化npm來建立package.json
npm init
2.install幾個package,分別是vue、webpack、webpack-cli
- i = install
- -d = --save-dev
npm i -d vue webpack webpack-cli
3.為webpack建立config,webpack.config.js(若沒有建立,會跑預設的設定,但現在我想要額外指定他的打包路徑)
//webpack.config.js
const path = require("path");
module.exports = {
entry: './WebClient/index.js',
output:{
filename:"bundle.js",
path:path.resolve(__dirname,"wwwroot")
},
mode:"development",
devtool:"source-map",
}
4.準備一點簡單的代碼做測試,路徑需要跟設定的entry相同(這邊用的是cshtml,因為原本只是想用.Net Core MVC搭配vue)
//index.js
alert("Hello world");
<!--index.cshtml-->
<div id="app" class="text-center">
<h1 class="display-4">Welcome</h1>
<hello index="12"></hello>
</div>
<script src="~/bundle.js"></script>
5.為了之後方便些,也調整一下package.json,在scripts裡面加上自定義的指令,build和watch
- build相當於 npx webpack,打包內容
- watch相當於 npx webpack --watch,監控檔案有變化時自動打包內容
"scripts": {
"build": "webpack",
"watch": "webpack --watch",
"test": "echo \"Error: no test specified\" && exit 1"
},
6.這時候執行npm run build,會在根目錄的wwwroot資料夾底下建立一個bundle.js,這就是webpack打包出來的檔案,可以注意到上面的html也是引入了bundle.js進去,執行網頁則會直接跳出alert("Hello world")
7.接著把vue.js加進來,調整一下index.js和index.cshtml,加上了一點點功能
//index.js
import Vue from "vue"
new Vue({
el: "#app",
data: {
message: "hello world.",
name:"name"
},
methods: {
Hello: function () {
alert("hello");
}
},
mounted : function(){
console.log('Hello Webpack and Vue !');
}
})
<!--index.cshtml-->
<div id="app" class="text-center">
<h1 class="display-4">Welcome</h1>
<p>{{message}}</p>
<p>{{name}}</p>
<button v-on:click="Hello()">Button</button>
<input v-model="name" type="text">
</div>
<script src="~/bundle.js"></script>
8.開啟Web,會發現完全沒有畫面,接著調整一下webpack.config.js,設置模板編譯,打包並重整後就可以正常看到畫面了
//webpack.config.js
resolve: {
alias: {
'vue': 'vue/dist/vue.js'
}
},
9.這時候有了vue.js也有了webpack幫我們做打包,已經可以開始做基本的開發了,不過還沒結束,還有一個TypeScript還沒加上
10.透過npm再install幾個package,分別是 ts-loader 和 typescript
- typescript:就是typescript,沒什麼要特別說明的
- ts-loader:讓webpack可以解析typescript的內容
npm i ts-loader typescript
11.接者初始化typescript,這邊可以執行指令,也可以手動建立tsconfig.json,透過指令產生的內容會包含大多數的設定(幾乎都是註解的,可以再依照個人需求調整)
tsc --init
12.把index.js改名為index.ts,內容這次先不調整
13.調整webpack.config.js,
- 把emtry改成index.ts
- 加上module,遇到.ts的副檔名就用 ts-loader 解析
//webpack.config.js
const path = require("path");
module.exports = {
entry: './WebClient/index.ts',
output: {
filename: "bundle.js",
path: path.resolve(__dirname, "wwwroot")
},
mode: "development",
devtool: "source-map",
resolve: {
alias: {
'vue': 'vue/dist/vue.js'
}
},
module: {
rules: [
{
test: /\.ts$/,
loader: "ts-loader",
include: /WebClient/,
}
]
}
}
14.再次打包並開啟網頁,理應上會跟原本一模一樣,只是背後改成了typescript
15.接著為了讓vue.js更能享受typescript的功能,逐步調整index.ts,先將它調整為Single File Components
- vue 2對typescript的支持相當差,據說在vue 3有大幅度的支持
16.透過npm install package
npm i vue-loader vue-template-compiler
17.調整幾個檔案的內容,以及新增一個 Hello.vue(component),下面列出在webpack.confg.js的改變
- 加入 const VueLoaderPlugin = require("vue-loader/lib/plugin")
- 加入針對 .vue 副檔名的rule
- 調整針對 .ts 的rule,也對 .vue 副檔名的做處理
- 加入 plugins:[ new VueLoaderPlugin() ]
<!--index.cshtml-->
<div id="app" class="text-center">
<h1 class="display-4">Welcome</h1>
<hello index="12"></hello>
</div>
<script src="~/bundle.js"></script>
//index.ts
import Vue from "vue"
import Hello from "./Components/Hello.vue"
new Vue({
el:"#app",
components:{
Hello
}
})
//webpack.config.js
const Path = require("path");
const VueLoaderPlugin = require("vue-loader/lib/plugin")
module.exports = {
entry: './WebClient/index.ts',
output: {
filename: "bundle.js",
path: Path.resolve(__dirname, "wwwroot")
},
mode: "development",
devtool: "source-map",
resolve: {
alias: {
'vue': 'vue/dist/vue.js'
}
},
module: {
rules: [
{
test: /\.ts$/,
loader: "ts-loader",
include: /WebClient/,
options:{
appendTsSuffixTo:[/\.vue/]
}
},
{
test: /\.vue$/,
loader: "vue-loader",
include: /WebClient/,
},
]
},
plugins:[
new VueLoaderPlugin()
]
}
//Hello.vue
<template>
<div>
<h1>{{Title}}</h1>
<h2>{{Name}}</h2>
<label>
Input
<input v-model="Name" type="text">
</label>
<button v-on:click="Hello">Button</button>
<p>{{Total}}</p>
</div>
</template>
<script lang="ts">
import Vue from "vue"
export default Vue.extend({
props: ["Index"],
data() {
return {
Name: "Test",
Title: "Title",
Index: this.Index,
}
},
methods: {
Hello() {
alert("hello");
}
},
computed: {
Total(): number {
return this.Index + 1;
}
}
})
</script>
18.接著再新增一個檔案,vue-shims.d.ts,讓ts也能識別 .vue 的檔案
declare module "*.vue" {
import Vue from "vue";
export default Vue;
}
19.這部分完成了,執行的web應該要可以正常動作的
20.目前的 .vue 看起來稍微好維護多的,但是仍然沒辦法享受typesript型別檢查的優點,接著繼續調整
21.接著要改用 vue-property-decorator 讓我們開發 .vue
npm i -d vue-property-decorator
22.因為會用到decorators,所以在tsconfig.ts把 experimentalDecorators 改為 true
"experimentalDecorators": true
23.調整 Hello.vue
<template>
<div>
<h1>{{Title}}</h1>
<h2>{{Name}}</h2>
<label>
Input
<input v-model="Name" type="text">
</label>
<button v-on:click="Hello">Button</button>
<p>{{Total}}</p>
</div>
</template>
<script lang="ts">
import Component from "vue-class-component"
import {Vue, Prop} from "vue-property-decorator";
@Component
export default class Hello extends Vue {
@Prop({default: 0}) Index!: number
private Name: string = "Test";
private Title: string = "Title";
private IndexCount: number = this.Index;
Hello() {
alert("hello");
}
get Total(): number {
return this.IndexCount + 1;
}
}
</script>
24.這時候的程式碼功能跟原本是一致的,寫法有很大的不同,而且也能開心的使用typescript的型別檢查了
如果不想從0開始設定,可以直接使用 vue-cli 直接幫你產生完整的範本專案 (https://cli.vuejs.org/zh/)
若不看其他library或是webpack,vue是很好上手的前端語言,好懂好讀又可以簡單的導入專案,不過目前vue 2 對typescript的支援度不高
所以筆者還是決定先跳回angular去了......
不過相信 vue 的未來發展是可以讓人期待的
希望這篇可以幫到任何想開始學習vue+typescript的朋友們
上面提到的所有東西都會列在下面給有興趣的朋友深入了解
vue.js https://cn.vuejs.org/
vue-cli https://cli.vuejs.org/zh/
vue-router https://router.vuejs.org/zh/ (上面沒有提到,不過也挺重要的)
vue-loader https://vue-loader.vuejs.org/zh/
vue-class-component https://class-component.vuejs.org/
vue-typescript-start https://github.com/Microsoft/TypeScript-Vue-Starter (由微軟提供的範例,如何在vue導入typescript)
vue-property-decorator https://github.com/kaorun343/vue-property-decorator
webpack http://webpack.docschina.org/
typescript https://www.tslang.cn/index.html
Sample Code https://github.com/ianChen806/VueJsSample