by yugasun from yugasun.com/post/you-ma… 本文可全文轉載,但需要保留原作者和出處。
開發環境
既然是實戰,怎離不開專案開發的環境呢?先給大家推薦下我的個人開發環境:
硬體裝置:Mac OSX 編譯器:Visual Studio Code 命令列工具:iTerm2 除錯工具:Chrome Dev tool + vue-devtools 版本管理:Git
具體工具的操作介面和如何使用,這裡就不展示了。隨便用搜尋引擎搜尋,就是相關介紹。大家可以根據個人喜好,來選擇適合你的開發環境。
模組化開發
前面的文章中使用 Vue,都是直接引入原始碼方式來使用,但是實際開發中專案一般很複雜,並且會涉及到很多頁面模板,不可能所有的功能我們都寫在同一個js檔案,然後在通過 script 標籤引入,這樣專案大了會越來越不易維護,所以專案需要模組化開發。
關於什麼事模組化,具體如何模組化構架我們的專案,推薦閱讀 JavaScript 模組化入門Ⅰ:理解模組 和 JavaScript 模組化入門Ⅱ:模組打包構建。
當專案程式碼多了,我們的模組檔案越來越多,就需要工具來幫助我們更好的管理和打包這些模組,讓我們能更好的關注模組化開發,而不是這些瑣碎的事情。於是 webpack
類似的工具就應運而生,當然除了 webpack
還有很多類似的工具,他們各有各的優點,比如:rollup、parcel...。
今後文章所有的例項將用到 webpack
的 3.x
版本工具來結合Vue 完成開發工作。
初始 webpack
這裡不得不說一下,很多朋友在開發 Vue 專案的時候,一上來就使用 vue-cli 腳手架工具開發專案,雖然可以很快的構建專案模板,不用關注初始化配置問題。但是我不建議這麼做,因為一上來就是 vuejs + webpack + es6 + babel + eslint...
等各種工具,有人都還不知道他們是什麼,就開始用。出了問題,就不知道如何是好。雖然藉助搜尋引擎可以幫助我們解決80%的難題,但還是需要花費大量的精力去搜尋查詢,不斷的嘗試,等問題解決了,一天就過去了,得不償失啊。
所以我建議先從學會使用 webpack
開始,一步一步的引入進來,會容易接受一些。畢竟這世界上大多數人都不是天才,要學會跑,得先學會走路。
雖然當前社會比較浮躁,但是擁有一顆寧靜的心,腳踏實地,才是成功之道啊~
好了廢話不多說,直接進入今天的正題,使用 webpack 愉快的進行 Vuejs 專案開發。
在閱讀下面程式碼之前,請提前熟悉 nodejs 模組的使用,包括基本的通過 npm 安裝模組依賴和如何引入第三方模組使用,這裡雖然會提到,但不會詳細解釋。
我們先新建一個專案資料夾,在根目錄下新建 index.html
,程式碼如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Vue webpack demo</title>
</head>
<body>
<div id="app"></div>
<script src="./build.js"></script>
</body>
</html>
複製程式碼
命令列執行 npm init
,按照互動提示,填寫專案相關資訊(當然都是英文,不懂得直接翻一下就明白了),填寫完成後,專案根目錄下會出現 package.json
檔案(關於package.json檔案內容具體介紹,可以閱讀這篇文章:package.json檔案)。然後通過 npm
安裝我們需要的 vue
庫:
# 新增 --save 引數,會將 vue 依賴新增到 package.json 檔案中
npm install vue --save
複製程式碼
然後新建一個 src
目錄,在 src
目錄下建立一個 app.js
入口檔案,程式碼如下:
// 模組化的引入 vue,並將其賦值給 Vue 變數
var Vue = require('vue')
new Vue({
el: "#app",
template: "<h1>{{ msg }}</h1>",
data () {
return {
msg: 'Hello Vue.js'
}
}
})
複製程式碼
當然 require
函式瀏覽器是無法識別的,這是就需要通過 webpack
幫我們實現編譯打包工作,轉化為主流瀏覽器可是別的 ES5 程式碼。
先安裝 webpack
包依賴:
# 新增 --save-dev 引數,會將 webpack 開發依賴新增到 package.json 檔案中
npm install webpack --save-dev
複製程式碼
然後在專案根目錄下建立 webpack.config.js
檔案,程式碼如下:
module.exports = {
// 入口檔案
entry: './src/app.js',
// 編譯輸出檔案
output: {
filename: 'build.js'
},
resolve: {
alias: {
// 因為我們這裡用的是 require 引入方式,所以應該使用vue.common.js/vue.js/vue.min.js
'vue$': 'vue/dist/vue.common.js'
}
}
}
複製程式碼
因為上面的 index.html
中引入的是編譯後的 build.js
檔案,要看到開發效果,就需要手動執行 webpack
打包命令:
./node_modules/.bin/webpack
複製程式碼
這裡如果你想直接執行
webpack
,那麼就需要你的電腦全域性安裝 webpack,可以通過執行npm install webpack -g
命令來全域性安裝。
然後你會看到輸出以下結果:
$ webpack
Hash: 8a61c2605578f38f46cd
Version: webpack 3.10.0
Time: 386ms
Asset Size Chunks Chunk Names
build.js 104 kB 0 [emitted] main
[0] (webpack)/buildin/global.js 509 bytes {0} [built]
[1] ./src/app.js 148 bytes {0} [built]
+ 4 hidden modules
複製程式碼
此時根目錄下就會出現 build.js
檔案,我們再通過瀏覽器開啟 index.html
檔案,熟悉的畫面出現了,Hello Vue.js
。
到這裡一個簡單的基於 vue + webpack
的專案就構建完成了,是不是很簡單,迫不及待想自己動手試試呢?當然 webpack
的功能遠不止如此更詳細的功能,請閱讀 官方文件,全面的瞭解下 webpack
的強大。
實時重新載入(live reloading)
上面的例子還有個問題,就是每次我們更新了程式碼,就需要重新進行打包編譯,並手動重新整理瀏覽器,才能看到我們更改的效果,實在是太麻煩了。webpack 作者也考慮到了這個問題,於是同時開發了 webpack-dev-server
工具,來幫助我們實現 live reloading
的功能,也就是當我們更新程式碼時,瀏覽器會實時重新整理,呈現更新後的效果。
趕緊用起來~ 先安裝下依賴:
npm install webpack-dev-server --save-dev
複製程式碼
然後修改 webpack.config.js
配置檔案如下:
module.exports = {
// 入口檔案
entry: './src/app.js',
// 編譯輸出檔案
output: {
filename: 'build.js'
},
resolve: {
alias: {
// 因為我們這裡用的是 require 引入方式,所以應該使用vue.common.js/vue.js/vue.min.js
'vue$': 'vue/dist/vue.common.js'
}
},
// 這裡新增的是有關 webpack-dev-server 的配置
devServer: {
// 這裡定義 webpack-dev-server 開啟的web服務的根目錄
contentBase: './'
}
}
複製程式碼
然後執行命令:
./node_modules/.bin/webpack-dev-server
複製程式碼
控制檯會輸出一下內容:
$ ./node_modules/.bin/webpack-dev-server
Project is running at http://localhost:8080/
webpack output is served from /
Content not from webpack is served from ./
Hash: d33155f6797f2c78c448
Version: webpack 3.10.0
Time: 903ms
Asset Size Chunks Chunk Names
build.js 627 kB 0 [emitted] [big] main
[0] (webpack)/buildin/global.js 509 bytes {0} [built]
[3] multi (webpack)-dev-server/client?http://localhost:8080 ./src/app.js 40 bytes {0} [built]
[4] (webpack)-dev-server/client?http://localhost:8080 7.91 kB {0} [built]
...
[28] ./node_modules/timers-browserify/main.js 1.9 kB {0} [built]
+ 15 hidden modules
webpack: Compiled successfully.
複製程式碼
開啟瀏覽器,訪問: http://localhost:8080,此時我們熟悉的畫面又出現了,O(∩_∩)O~~。我們再嘗試修改 app.js
中 msg
內容,瀏覽器的內容也會跟著變化,是不是很酷,趕緊動手試試吧。
使用 npm 指令碼
針對上面的打包命令 ./node_modules/.bin/webpack
和實時開發命令 ./node_modules/.bin/webpack-dev-server
,雖然你可以很快的在命令列復制貼上輸入,但是第一次還是免不了動手輸入。作為一個懶惰的程式設計師,怎麼能接受敲擊這麼多多餘的字元呢?正好package.json
檔案中 scripts
欄位就可以幫助我們解決這個煩惱。
先來看下介紹:
scripts 是用來指定執行指令碼命令的npm命令列縮寫的,比如 start 指定了執行
npm run start
時,所要執行的相關命令。
好的,既然明白了它的作用,我們就來嘗試改寫 package.json
檔案,修改 scripts
欄位為如下內容:
"scripts": {
"dev": "webpack-dev-server",
"build": "webpack"
}
複製程式碼
然後,在命令列輸入:
npm run dev
複製程式碼
你會發現跟執行 ./node_modules/.bin/webpack-dev-server
是一樣的效果。
注意:這裡在
scripts
中指定webpack-dev-server
命令是,省去了命令路徑,這是因為,npm 在執行指令碼時,會預設優先執行當前目錄下./node_modules/.bin/
中的命令,如果找不到該命令,則會執行全域性命令。
同理,執行 npm run build
就是打包輸出我們想要的 build.js
檔案。
CSS前處理器
雖然 css 已經足夠強大,但是在程式設計師眼裡,它一直是個很麻煩的東西,它沒有變數,也沒有條件語句,只是單純的一行行的描述,寫起來相當麻煩。於是各種 CSS前處理器 應運而生,其中我最喜歡的是 SASS,使用 sass 語法編寫我們的樣式檔案,會大大提高我們的開發效率,使得 css 工程化變得容易了很多。
接下來介紹下,如何整合到我們的專案中。
對於 webpack 來說 一切皆模組
,所有的檔案通過模組引入的方式形成依賴關係,而對於每個模組的引入或預處理,都是通過 loader
來實現了。因為我們的 sass
語法瀏覽器是無法識別的,所以在引入時需要使用相關 loader
對其進項預處理,轉化為相應的 css
。雖然 css 瀏覽器可以識別的,但是 webpack
本質上是一個 javascript 應用程式的靜態模組打包器,一切檔案內容都將處理為 javascript,然後進行後期的處理。所以這裡除了需要預處理 sass
的 loader
,還需要載入 css
的 loader
,最後還需要通過 style-loader
來轉化為通過 js 的方式動態建立 style
標籤到 index.html
中。
知道了這點,我們就知道要怎麼做了,首先安裝所需的 loader
:
# 因為 `sass-loader` 需要依賴 `node-sass`, 所以這裡一併安裝
npm install style-loader css-loader sass-loader node-sass --save-dev
複製程式碼
修改 webpack.config.js
配置檔案,新增相關 loader
配置:
module.exports = {
//...
module: {
// 這裡用來配置處理不同字尾檔案所使用的loader
rules: [
{
test: /\.scss$/,
use: [
{
loader: 'style-loader'
},
{
loader: 'css-loader'
},
{
loader: 'sass-loader'
}
]
}
]
}
}
複製程式碼
webpack 的 loader 是支援鏈式傳遞的,它能夠對資源使用流水線(pipline)式處理,一組鏈式的 loader 將按照相反順序依次處理,這裡的處理流程就是: sass-loader -> css-loader => style-loader
配置好了,我們現在來測試下,在 src
目錄下建立一個 app.scss
檔案,內容如下:
$red: rgb(218, 42, 42);
h1 {
color: $red;
}
複製程式碼
然後在 src/app.js
檔案中引入:
require('./app.scss');
var Vue = require('vue');
new Vue({
el: "#app",
template: "<h1>{{ msg }}</h1>",
data () {
return {
msg: 'Hello Vue.js'
}
}
});
複製程式碼
此時再執行 npm run dev
,你會發現我們的 h1
標籤顏色變了。通過稽核元素,可以發現 index.html
的 head
標籤中新增了一個 style
標籤,內容就是,app.scss
編譯輸出的內容:
h1 {
color: #da2a2a;
}
複製程式碼
如果還不清楚 sass
用法的,建議去看看這篇基礎介紹文件:SASS用法指南
圖片載入
既然說到了 css 靜態資源,自然免不了對於圖片的載入了。上文說過,在 webpack 中,一切皆模組,圖片當然也是以模組的方式引入的。既然是模組,自然少不了相關引入的 loader,這裡圖片引入我們使用到的是 url-loader
,先安裝下:
npm install url-loader --save-dev
複製程式碼
新增 url-loader
配置:
module.exports = {
// ...
module: {
// 這裡用來配置處理不同字尾檔案所使用的loader
rules: [
// ...
{
test: /\.(jpe?g|gif|png)$/,
use: 'url-loader'
}
]
}
}
複製程式碼
然後再 app.js
中引入:
require('./app.scss');
var Vue = require('vue');
var logoSrc = require('./logo.jpg')
new Vue({
el: "#app",
data () {
return {
msg: 'Hello Vue.js'
}
},
render (h) {
return (
h('div', [
h('img', {
domProps: {
src: logoSrc,
alt: 'logo',
className: 'logo'
}
}),
h('h1', this.msg)
])
)
}
});
複製程式碼
這裡我們用
render
函式來自定義渲染我們的節點,它含有預設引數h
就是我們 花式渲染目標元素 講到的createElement
引數的別名而已,這裡為了書寫簡單。h
函式的第一個引數為dom
名稱,第二個引數為建立時配置物件,通過domProps
來新增 DOM 相關的屬性值。這裡將我們引入的logoSrc
賦值給它的src
屬性。
然後再重新執行 npm run dev
,頁面中就出現了我們想要的 logo
圖片了。
總結
知己知彼,百戰不殆
,我們只有真正瞭解了 webpack
的使用技巧,在實際開發中,我們才會更加的得心應手。不至於被一個莫名其妙的錯誤個嚇到。程式設計師有三寶:多學習,多編寫,多總結
,我們的程式設計技巧才能才會不斷提高。