前言
最近有一個(gè)項(xiàng)目使用了Vue框架,組件開發(fā)是Vue里面的重要思想之一,而官方文檔上推薦的最佳實(shí)踐是通過webpack+vue構(gòu)建工程,所以在使用Vue之前,我們需要了解webpack這個(gè)打包工具。
在此之前,筆者稍微從requirejs的r.js領(lǐng)略了一點(diǎn)點(diǎn)打包思想,因?yàn)橹恍枰唵蔚拇虬δ?,網(wǎng)上很多文章說了一大堆,什么ES6,什么AMD、CMD,什么shimming、公共模塊,相信對(duì)于什么都不知道的初學(xué)者,說到后面就會(huì)蒙蔽,所以本文主要介紹webpack的最簡單的用法,適合新手入門。
webpack是什么鬼
webpack 是德國開發(fā)者 Tobias Koppers 開發(fā)的模塊加載器兼打包工具,在webpack中,它可以把各種資源當(dāng)成一個(gè)模塊,例如JS(含JSX)、coffee、樣式(含less/sass)、圖片等都作為模塊來使用和處理。不同的模塊,他們有對(duì)應(yīng)不同的加載器,稱之為loader。
這個(gè)圖我都看過不下10遍了(看不懂沒關(guān)系,照做就行,寫代碼這東西,多實(shí)踐幾次就知道了)

webpack的優(yōu)勢:
- 可以將任何文件類型模塊化,不僅僅是js
- webpack 可以通過commonJS 的形式開發(fā),支持 AMD和CMD
- 打包、壓縮混淆、圖片轉(zhuǎn)base64等,圖片轉(zhuǎn)base64也是圖片模塊化的思想
- 反正就是很厲害啦~
安裝node和npm
在安裝webpack之前,我們需要先安裝npm,安裝npm的之前呢,我們又必須安裝nodejs。因?yàn)镹ode.js 自帶了軟件包管理器 npm,Webpack 需要 Node.js v0.6 以上支持,建議使用最新版 Node.js。PS:總之要用webpack前,先把node裝好。
有幾個(gè)方法安裝node的:
第一種方法:下載安裝包
下載安裝包或者源碼包安裝
https://nodejs.org/en/
在Windows上安裝時(shí)務(wù)必選擇全部組件,包括勾選Add to Path。
第二種方法:使用nvm安裝nodejs(強(qiáng)烈推薦!?。?/h3>
nvm全稱Node Version Manager,是通過shell腳本實(shí)現(xiàn)的,通過nvm可以輕松地安裝多個(gè)版本,隨意切換版本,根據(jù)喜好和依賴自由選擇,省去了很多安裝繁瑣過程,強(qiáng)烈推薦大家使用。
安裝方式有兩種:
$ curl https://raw.github.com/creationix/nvm/v0.4.0/install.sh | sh
或者
$ wget -qO- https://raw.github.com/creationix/nvm/v0.4.0/install.sh | sh
nvm安裝完成之后,可以用以下命令來安裝node
$ nvm install 7.6.0
使用指定的node版本
$ nvm use 7.6.0
查看當(dāng)前已經(jīng)安裝的版本
$ nvm ls
v4.2.2 *
-> v7.6.0 *
default -> stable (-> v7.6.0 *)
node -> stable (-> v7.6.0 *) (default)
stable -> 7.6 (-> v7.6.0 *) (default)
iojs -> N/A (default)
lts/* -> lts/boron (-> N/A)
lts/argon -> v4.8.0 (-> N/A)
lts/boron -> v6.10.0 (-> N/A)
在看看npm:
npm -v
4.1.2
可以看到筆者安裝了兩個(gè)版本的node,目前使用的是v7.6.0,上面有小箭頭指向你正在使用的版本,并且npm也準(zhǔn)備就緒。
nvm管理node簡單清爽,幫你減去了維護(hù)各種依賴的繁瑣環(huán)節(jié),你值得擁有。
安裝webpack
全局安裝:
npm install webpack -g
查看webpack版本:
webpack -v
2.2.1
webpack已經(jīng)安裝成功!
不過你應(yīng)該將webapck安裝到當(dāng)前的項(xiàng)目依賴中,這樣可以根據(jù)本地項(xiàng)目使用對(duì)應(yīng)版本的webpack
首先,我們創(chuàng)建一個(gè)測試目錄:
mkdir testapp
然后通過npm初始化該目錄:
npm init
name: (testapp) hello
npm初始化的時(shí)候會(huì)創(chuàng)建一系列的基礎(chǔ)信息,包括name、version、description、main、author、licence,你只要寫上name和author就可以了,一路回車不要停。
完成后,該目錄會(huì)生成package.json配置文件。
1 {
2 "name": "hello",
3 "version": "1.0.0",
4 "description": "test webpack",
5 "main": "index.js",
6 "scripts": {
7 "test": "echo \"Error: no test specified\" && exit 1"
8 },
9 "author": "dada",
10 "license": "ISC"
11 }
上面提到,可以將webpack安裝在當(dāng)前目錄下:
npm install webpack --save-dev
# 可以縮寫:npm i webpack -D
# –save:模塊名將被添加到dependencies,可以簡化為參數(shù)-S。
# –save-dev: 模塊名將被添加到devDependencies,可以簡化為參數(shù)-D。開發(fā)環(huán)境一般使用--save-dev就可以了
安裝完成后,會(huì)出現(xiàn)一個(gè)node_modules目錄,這里面會(huì)存放通過npm安裝的模塊。
webpack打第一個(gè)包
在testapp目錄下創(chuàng)建index.html
<!-- index.html -->
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<h1 id="app"></h1>
<script src="build.js"></script>
<!-- 注意這里引入的不是我們創(chuàng)建的文件,而是用webpack生成的文件 -->
</body>
</html>
創(chuàng)建app.js(一會(huì)兒我們用webpack打包這個(gè)js,命名無所謂)
/*** app.js ***/
document.getElementById('app').innerHTML="hello world!";
現(xiàn)在開始打包!激動(dòng)!
webpack app.js build.js
打包完成后,有如下信息:
Version: webpack 2.3.2
Time: 96ms
Asset Size Chunks Chunk Names
build.js 2.71 kB 0 [emitted] main
[0] ./app.js 76 bytes {0} [built]
查看當(dāng)前文件夾,出現(xiàn)如下:
app.js
build.js
index.html
node_module
package.json
可以看到build.js就是通過webpack生成的。
我們打開瀏覽器看看的index.html看看:

沒錯(cuò)!我們看見了經(jīng)典程序——Hello world!
然后查看源碼:

查看build.js:

我們拉到底部,看見了我們的app.js,就這樣被包含進(jìn)來了。
這就是第一個(gè)用webpack打包的程序。
一些朋友要說這有卵用!我就innerHTML直接寫在index.html里面不就好了嗎?搞毛webpack啊。
Keep Calm and Carry On . 我們?cè)俣嘧鰩讉€(gè)實(shí)驗(yàn),看有沒有卵用。
在app.js中引入一個(gè)button.js工具包,它可以幫我們?cè)黾右粋€(gè)button按鈕。
/*create a button*/
var button = document.createElement("button");
button.innerHTML ="Click me!";
document.body.appendChild(button);
然后在app.js 中引入button.js
/*** app.js ***/
document.getElementById('app').innerHTML="hello world!";
require("./button.js");
再打包一次:
webpack app.js build.js
刷新瀏覽器,頁面多了一個(gè)按鈕

查看build.js,可以看到button.js的代碼也被打包進(jìn)去,這就是按鈕為什么也顯示出來。

webpack 會(huì)自動(dòng)分析我們的入口文件,我們這里用app.js做為一個(gè)被打包文件,里面require了button,js,webpack這個(gè)時(shí)候會(huì)分析找到依賴的js文件,一并打包進(jìn)來,生成一個(gè)全新的build.js。
webpack就這點(diǎn)能耐?如果是的話,它應(yīng)該火不起來,因?yàn)檫@個(gè)功能大多數(shù)打包工具都有。
牛逼哄哄的loader
webpack 本身只能處理 JavaScript 模塊,如果要處理其他類型的文件,就需要使用 loader 進(jìn)行轉(zhuǎn)換??梢岳斫鉃槭悄K和資源的轉(zhuǎn)換器,它本身是一個(gè)函數(shù),接受源文件作為參數(shù),返回轉(zhuǎn)換的結(jié)果。這樣,我們就可以通過require來加載任何類型的模塊或文件,比如VUE、JSX、SASS 或圖片。
安裝css的loader
css的轉(zhuǎn)換,需要引入兩個(gè)loader,css-loader和style-loader
npm install css-loader style-loader --save-dev
查看package.json,其中devDependencies多了css-loader和style-loader
{
"name": "hello",
"version": "1.0.0",
"description": "test webpack",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "dada",
"license": "ISC",
"devDependencies": {
"css-loader": "^0.28.0",
"style-loader": "^0.16.1",
"webpack": "^2.3.2"
}
}
加載css
新增一個(gè)test.css
把字變成白色,背景變成黑色
h1 {
color:#fff
}
body{
background:#000;
}
然后在app.js里面引入test.css,其中style-loader!css-loader表示引入的資源依賴這兩個(gè)loader
/*** app.js ***/
require("style-loader!css-loader!./test.css");
document.getElementById('app').innerHTML="hello world!";
require("./button.js");
打包:
webpack app.js build.js
查看變化,css已經(jīng)生效,背景色變成黑色,h1字體變成白色

控制臺(tái)查看,我們的test.css已經(jīng)載入了

以下這種寫法很不優(yōu)雅,難道加載一個(gè)css,前面就要加上“style-loader!css-loader”嗎?
require("style-loader!css-loader!./test.css");
可以換種方式實(shí)現(xiàn):
require("./test.css");
然后命令行添加--modulle-bind參數(shù),我們把background改成pink試試
webpack app.js build.js --module-bind "css=style-loader\!css-loader"
執(zhí)行沒問題,背景應(yīng)該變成粉紅色,注意:這里的css-loader前面要加一個(gè)反斜線,表示轉(zhuǎn)義,否則無法編譯通過。
加載圖片
js和css都已經(jīng)可以正常引入、打包、加載了,那么圖片能否做到呢?
首先圖片需要url-loader這個(gè)加載器:
npm install url-loader --save-dev
修改css,增加一張叮當(dāng)貓的圖片作背景
h1 {
color:#fff
}
body{
background:url('./dingdang.jpg');
}
然后再打包,因?yàn)榧虞d兩種文件類型的loader,一個(gè)是css,一個(gè)是圖片,所以我們寫下各自的--module-bind配置
webpack app.js build.js
\--module-bind "css=style-loader\!css-loader"
\--module-bind "jpg=url-loader?mimetype=image/jpg"
背景圖出現(xiàn)叮當(dāng)貓:

查看源碼,圖片已經(jīng)變成base64編碼

再看一次index.html源碼,它由此至終都只引入了一個(gè)build.js,不會(huì)引入任何其他的js或者css文件,減少了HTTP請(qǐng)求。

發(fā)現(xiàn)問題
如果我們加載的資源類型多了,每次輸入一大串帶有--module-bind參數(shù)的命令很煩,怎么辦?
如果我的圖片太大,不想轉(zhuǎn)為base64編碼,怎么辦?
如果每次開發(fā)完,都要運(yùn)行一次webpack很煩,怎么辦?
如果想用webpack結(jié)合vue寫超簡約代碼,怎么辦?
如果我記不住哪個(gè)文件用哪個(gè)loader,怎么辦?
如果package.json里面不知道配置,怎么辦?
這些都不是本文要講的,一次練習(xí)一件事兒,本文只練習(xí)css,js、圖片打包方法。
欲知上面那些怎么辦,請(qǐng)聽下回分解。o(∩_∩)o