Webpack 是當(dāng)下最熱門(mén)的前端資源模塊化管理和打包工具充活。它可以將許多松散的模塊按照依賴和規(guī)則打包成符合生產(chǎn)環(huán)境部署的前端資源。還可以將按需加載的模塊進(jìn)行代碼分隔蜡娶,等到實(shí)際需要的時(shí)候再異步加載混卵。通過(guò) loader
的轉(zhuǎn)換,任何形式的資源都可以視作模塊窖张,比如 CommonJs 模塊幕随、 AMD 模塊、 ES6 模塊宿接、CSS赘淮、圖片辕录、 JSON、Coffeescript梢卸、 LESS 等走诞。
安裝
首先要安裝 Node.js, Node.js 自帶了軟件包管理器 npm蛤高,Webpack 需要 Node.js v0.6 以上支持蚣旱,建議使用最新版 Node.js。
用 npm 安裝 Webpack:
$ npm install webpack -g
此時(shí) Webpack 已經(jīng)安裝到了全局環(huán)境下戴陡,可以通過(guò)命令行 webpack -h 試試塞绿。
通常我們會(huì)將 Webpack 安裝到項(xiàng)目的依賴中,這樣就可以使用項(xiàng)目本地版本的 Webpack恤批。
進(jìn)入項(xiàng)目目錄
確定已經(jīng)有 package.json异吻,沒(méi)有就通過(guò) npm init 創(chuàng)建
安裝 webpack 依賴
$ npm install webpack --save-dev
Webpack 目前有兩個(gè)主版本,一個(gè)是在 master 主干的穩(wěn)定版开皿,一個(gè)是在 webpack-2 分支的測(cè)試版涧黄,測(cè)試版擁有一些實(shí)驗(yàn)性功能并且和穩(wěn)定版不兼容,在正式項(xiàng)目中應(yīng)該使用穩(wěn)定版赋荆。
查看 webpack 版本信息
$ npm info webpack
安裝指定版本的 webpack
$ npm install webpack@1.12.x --save-dev
如果需要使用 Webpack 開(kāi)發(fā)工具笋妥,要單獨(dú)安裝:
$ npm install webpack-dev-server --save-dev
使用
首先創(chuàng)建一個(gè)靜態(tài)頁(yè)面 index.html 和一個(gè) JS 入口文件 entry.js:
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<script src="bundle.js"></script>
</body>
</html>
// entry.js
document.write('It works.')
然后編譯 entry.js 并打包到 bundle.js:
$ webpack entry.js bundle.js
打包過(guò)程會(huì)顯示日志:
Hash: e964f90ec65eb2c29bb9
Version: webpack 1.12.2
Time: 54ms
Asset Size Chunks Chunk Names
bundle.js 1.42 kB 0 [emitted] main
[0] ./entry.js 27 bytes {0} [built]
用瀏覽器打開(kāi) index.html 將會(huì)看到 It works. 。
接下來(lái)添加一個(gè)模塊 module.js 并修改入口 entry.js:
// module.js
module.exports = 'It works from module.js.'
// entry.js
document.write('It works.')
document.write(require('./module.js')) // 添加模塊
重新打包 webpack entry.js bundle.js 后刷新頁(yè)面看到變化 It works.It works from module.js.
Hash: 279c7601d5d08396e751
Version: webpack 1.12.2
Time: 63ms
Asset Size Chunks Chunk Names
bundle.js 1.57 kB 0 [emitted] main
[0] ./entry.js 66 bytes {0} [built]
[1] ./module.js 43 bytes {0} [built]
Webpack 會(huì)分析入口文件窄潭,解析包含依賴關(guān)系的各個(gè)文件春宣。這些文件(模塊)都打包到 bundle.js 。Webpack 會(huì)給每個(gè)模塊分配一個(gè)唯一的 id 并通過(guò)這個(gè) id 索引和訪問(wèn)模塊嫉你。在頁(yè)面啟動(dòng)時(shí)月帝,會(huì)先執(zhí)行 entry.js 中的代碼,其它模塊會(huì)在運(yùn)行 require 的時(shí)候再執(zhí)行幽污。
Loader
Webpack 本身只能處理 JavaScript 模塊嚷辅,如果要處理其他類(lèi)型的文件,就需要使用 loader 進(jìn)行轉(zhuǎn)換距误。
Loader 可以理解為是模塊和資源的轉(zhuǎn)換器簸搞,它本身是一個(gè)函數(shù),接受源文件作為參數(shù)准潭,返回轉(zhuǎn)換的結(jié)果趁俊。這樣,我們就可以通過(guò) require 來(lái)加載任何類(lèi)型的模塊或文件刑然,比如 CoffeeScript寺擂、 JSX、 LESS 或圖片。
先來(lái)看看 loader 有哪些特性怔软?
Loader 可以通過(guò)管道方式鏈?zhǔn)秸{(diào)用垦细,每個(gè) loader 可以把資源轉(zhuǎn)換成任意格式并傳遞給下一個(gè) loader ,但是最后一個(gè) loader 必須返回 JavaScript挡逼。
Loader 可以同步或異步執(zhí)行蝠检。
Loader 運(yùn)行在 node.js 環(huán)境中,所以可以做任何可能的事情挚瘟。
Loader 可以接受參數(shù),以此來(lái)傳遞配置項(xiàng)給 loader饲梭。
Loader 可以通過(guò)文件擴(kuò)展名(或正則表達(dá)式)綁定給不同類(lèi)型的文件乘盖。
Loader 可以通過(guò) npm 發(fā)布和安裝。
除了通過(guò) package.json 的 main 指定憔涉,通常的模塊也可以導(dǎo)出一個(gè) loader 來(lái)使用订框。
Loader 可以訪問(wèn)配置。
插件可以讓 loader 擁有更多特性兜叨。
Loader 可以分發(fā)出附加的任意文件穿扳。
Loader 本身也是運(yùn)行在 node.js 環(huán)境中的 JavaScript 模塊,它通常會(huì)返回一個(gè)函數(shù)国旷。大多數(shù)情況下矛物,我們通過(guò) npm 來(lái)管理 loader,但是你也可以在項(xiàng)目中自己寫(xiě) loader 模塊跪但。
按照慣例履羞,而非必須,loader 一般以 xxx-loader 的方式命名屡久,xxx 代表了這個(gè) loader 要做的轉(zhuǎn)換功能忆首,比如 json-loader。
在引用 loader 的時(shí)候可以使用全名 json-loader被环,或者使用短名 json糙及。這個(gè)命名規(guī)則和搜索優(yōu)先級(jí)順序在 webpack 的 resolveLoader.moduleTemplates api 中定義。
Default: ["-webpack-loader", "-web-loader", "-loader", ""]
Loader 可以在 require() 引用模塊的時(shí)候添加筛欢,也可以在 webpack 全局配置中進(jìn)行綁定浸锨,還可以通過(guò)命令行的方式使用。
接上一節(jié)的例子悴能,我們要在頁(yè)面中引入一個(gè) CSS 文件 style.css揣钦,首頁(yè)將 style.css 也看成是一個(gè)模塊,然后用 css-loader 來(lái)讀取它漠酿,再用 style-loader 把它插入到頁(yè)面中冯凹。
/* style.css */
body { background: yellow; }
修改 entry.js:
require("!style-loader!css-loader!./style.css") // 載入 style.css
document.write('It works.')
document.write(require('./module.js'))
安裝 loader:
npm install css-loader style-loader
重新編譯打包,刷新頁(yè)面,就可以看到黃色的頁(yè)面背景了宇姚。
如果每次 require CSS 文件的時(shí)候都要寫(xiě) loader 前綴匈庭,是一件很繁瑣的事情。我們可以根據(jù)模塊類(lèi)型(擴(kuò)展名)來(lái)自動(dòng)綁定需要的 loader浑劳。
將 entry.js 中的 require("!style!css!./style.css") 修改為 require("./style.css") 阱持,然后執(zhí)行:
$ webpack entry.js bundle.js --module-bind 'css=style-loader!css-loader'
有些環(huán)境下可能需要使用雙引號(hào)
$ webpack entry.js bundle.js --module-bind "css=style-loader!css-loader"
顯然,這兩種使用 loader 的方式魔熏,效果是一樣的衷咽。
配置文件
Webpack 在執(zhí)行的時(shí)候,除了在命令行傳入?yún)?shù)蒜绽,還可以通過(guò)指定的配置文件來(lái)執(zhí)行镶骗。默認(rèn)情況下,會(huì)搜索當(dāng)前目錄的 webpack.config.js 文件躲雅,這個(gè)文件是一個(gè) node.js 模塊鼎姊,返回一個(gè) json 格式的配置信息對(duì)象,或者通過(guò) --config 選項(xiàng)來(lái)指定配置文件相赁。
繼續(xù)我們的案例相寇,在根目錄創(chuàng)建 package.json 來(lái)添加 webpack 需要的依賴:
{
"name": "webpack-example",
"version": "1.0.0",
"description": "A simple webpack example.",
"main": "bundle.js",
"scripts": {
"test": "echo "Error: no test specified" && exit 1"
},
"keywords": [
"webpack"
],
"author": "zhaoda",
"license": "MIT",
"devDependencies": {
"css-loader": "^0.21.0",
"style-loader": "^0.13.0",
"webpack": "^1.12.2"
}
}
如果沒(méi)有寫(xiě)入權(quán)限,請(qǐng)嘗試如下代碼更改權(quán)限
chflags -R nouchg .
sudo chmod 775 package.json
別忘了運(yùn)行 npm install钮科。
然后創(chuàng)建一個(gè)配置文件 webpack.config.js:
var webpack = require('webpack')
module.exports = {
entry: './entry.js',
output: {
path: __dirname,
filename: 'bundle.js'
},
module: {
loaders: [
{test: /.css$/, loader: 'style-loader!css-loader'}
]
}
}
同時(shí)簡(jiǎn)化 entry.js 中的 style.css 加載方式:
require('./style.css')
最后運(yùn)行 webpack唤衫,可以看到 webpack 通過(guò)配置文件執(zhí)行的結(jié)果和上一章節(jié)通過(guò)命令行 webpack entry.js bundle.js --module-bind 'css=style-loader!css-loader' 執(zhí)行的結(jié)果是一樣的。
開(kāi)發(fā)環(huán)境
當(dāng)項(xiàng)目逐漸變大跺嗽,webpack 的編譯時(shí)間會(huì)變長(zhǎng)战授,可以通過(guò)參數(shù)讓編譯的輸出內(nèi)容帶有進(jìn)度和顏色。
$ webpack --progress --colors
如果不想每次修改模塊后都重新編譯桨嫁,那么可以啟動(dòng)監(jiān)聽(tīng)模式植兰。開(kāi)啟監(jiān)聽(tīng)模式后,沒(méi)有變化的模塊會(huì)在編譯后緩存到內(nèi)存中璃吧,而不會(huì)每次都被重新編譯楣导,所以監(jiān)聽(tīng)模式的整體速度是很快的。
$ webpack --progress --colors --watch
當(dāng)然畜挨,使用 webpack-dev-server 開(kāi)發(fā)服務(wù)是一個(gè)更好的選擇筒繁。它將在 localhost:8080 啟動(dòng)一個(gè) express 靜態(tài)資源 web 服務(wù)器,并且會(huì)以監(jiān)聽(tīng)模式自動(dòng)運(yùn)行 webpack巴元,在瀏覽器打開(kāi) http://localhost:8080/ 或 http://localhost:8080/webpack-dev-server/ 可以瀏覽項(xiàng)目中的頁(yè)面和編譯后的資源輸出毡咏,并且通過(guò)一個(gè) socket.io 服務(wù)實(shí)時(shí)監(jiān)聽(tīng)它們的變化并自動(dòng)刷新頁(yè)面。
安裝
$ npm install webpack-dev-server -g
運(yùn)行
$ webpack-dev-server --progress --colors