1.什么是webpack
webpack是近期最火的一款模塊加載器兼打包工具,它能把各種資源,例如JS(含JSX)、coffee、樣式(含less/sass)、圖片等都作為模塊來使用和處理。
我們可以直接使用 require(XXX) 的形式來引入各模塊,即使它們可能需要經(jīng)過編譯(比如JSX和sass),但我們無須在上面花費太多心思,因為 webpack 有著各種健全的加載器(loader)在默默處理這些事情。
你可以不打算將其用在你的項目上,但沒有理由不去掌握它,因為以近期 Github 上各大主流的(React相關(guān))項目來說,它們倉庫上所展示的示例已經(jīng)是基于 webpack 來開發(fā)的,比如 React-Boostrap 和 Redux。
webpack的官網(wǎng)是 http://webpack.github.io/ ,文檔地址是 http://webpack.github.io/docs/。
2.webpack 的優(yōu)勢
其優(yōu)勢主要可以歸類為如下幾個:
- webpack 是以 commonJS 的形式來書寫腳本滴,但對 AMD/CMD 的支持也很全面,方便舊項目進行代碼遷移。
- 能被模塊化的不僅僅是 JS 了。
- 開發(fā)便捷,能替代部分 grunt/gulp 的工作,比如打包、壓縮混淆、圖片轉(zhuǎn)base64等。
- 擴展性強,插件機制完善,特別是支持 React 熱插拔(見 react-hot-loader )的功能讓人眼前一亮。
3.搭建webpack環(huán)境
指定版本安裝
npm install -g webpack@1.12.3
安裝最新版
npm install -g webpack
初始化倉庫
npm init -y
下載webpack服務(wù)
npm install -g webpack-dev-server
npm install --save-dev webpack-dev-server
4.使用測試
在項目中新建一個文件夾
mkdir test && cd test
目錄結(jié)構(gòu)如下
webpack.config.js
- entry 入口文件 讓webpack用哪個文件作為項目的入口
- output 出口 讓webpack把處理完成的文件放在哪里
- module 模塊 要用什么不同的模塊來處理各種類型的文件
module.exports = {
// 入口文件
entry: {
"bundle01": "./main01.js",
"bundle02": "./main02.js"
},
output: {
filename: "[name].js"
}
}
index.html
<script src="bundle01.js"></script>
<script src="bundle02.js"></script>
main01.js
document.write("<h1>Hello webpack</h1>");
main02.js
document.write("<p>hah</p>");
啟動服務(wù)
webpack-dev-server
瀏覽器輸入localhost:8080
5.安裝loader
使用loader,改變頁面內(nèi)容,瀏覽器會自動刷新
babel-loader
Babel 是一個 JavaScript 編譯器,可以將ES6語法轉(zhuǎn)換為ES5語法。
babel的安裝
npm install -g babel-cli
npm install --save-dev babel-core babel-loader babel-preset-es2015
目錄結(jié)構(gòu)如下

babel的使用
webpack.config.js
module.exports = {
entry: "./main.js",
output: {
filename: "babel.js"
},
module: {
loaders: [{
// 匹配文件格式
test: /\.js$/,
// 排除的文件
exclude: /node_modules/,
// 需要用到的loader
loader: "babel-loader"
}]
}
}
index.html
<script src="babel.js"></script>
main.js
import test from "./test.js";
// 等同于
// var test = require("./test.js");
document.write(test.fun1());
document.write(test.fun2());
test.js
function fun1() {
return "hello es6";
}
function fun2() {
return "config ok";
}
module.exports = {
fun1: fun1,
fun2: fun2
}
json-loader
安裝
npm install --save-dev json-loader
目錄結(jié)構(gòu)如下

json-loader的使用
webpack.config.js
module.exports = {
// 入口文件
entry: "./main.js",
output: {
filename: "bundle.js"
},
module: {
loaders: [{
test: /\.json$/,
exclude: /node_modules/,
loader: "json-loader"
}]
}
}
index.html
<script src="bundle.js"></script>
main.js
// require 引入模塊(js/json/css/less/sass/img)
var test = require("./test.json");
document.write(test.name);
document.write(test.age);
test.json
{
"name": "qzy",
"age": 20
}
css-loader
注意: 安裝css-loader必須依賴style-loader模塊
css-loader將引入的css生成目標文件
style-loader將生成的目標文件生成標簽插入到頁面中
安裝
npm install --save-dev style-loader css-loader
css-loader的使用
目錄結(jié)構(gòu)如下
webpack.config.js
module.exports = {
entry: "./main.js",
output: {
filename: "bundle.js"
},
module: {
loaders: [{
test: /\.css$/,
exclude: /node_modules/,
loader: "style-loader!css-loader"
}]
}
}
//或者
module.exports = {
entry: "./main.js",
output: {
filename: "bundle.js"
},
module: {
loaders: [{
test: /\.css$/,
exclude: /node_modules/,
loaders: ["style-loader","css-loader"]
}]
}
}
index.html
<script src="bundle.js"></script>
main.js
var test = require("./test.css");
document.write("hello css-loader");
test.css
body{
color: #f00;
}
效果如下

less-loader
注意,安裝less-loader必須依賴less,style-loader、css-loader三個模塊
安裝
npm install --save-dev less-loader less
目錄結(jié)構(gòu)如下

less-loader的使用
webpack.config.js
module.exports = {
entry: "./main.js",
output: {
filename: "bundle.js"
},
module: {
loaders: [{
test: /\.css$/,
exclude: /node_modules/,
loaders: ["style-loader", "css-loader", "less-loader"]
}]
}
}
index.html
<script src="bundle.js"></script>
main.js
var test = require("./test.less");
document.write("hello less-loader");
test.less
@color : blue;
body{
color: @color;
background: #ccc;
}
這樣敲代碼爽多了,less不用手動編譯,只需要保存文件瀏覽器就自動刷新了,簡直是太棒了!
打包靜態(tài)資源(如:圖片)
npm install --save-dev url-loader file-loader image-loader
目錄結(jié)構(gòu)如下

url-loader的使用
webpack.config.js
module.exports = {
entry: "./main.js",
output: {
filename: "bundle.js"
},
module: {
loaders: [{
test: /\.(png|jpg|gif)$/,
exclude: /node_modules/,
// limit指定文件大小
loader: "url-loader?limit=8192"
}]
}
}
index.html
<body>
<!-- 防止找不到body -->
<script src="bundle.js"></script>
</body>
main.js
var img = new Image();
img.src = require("./icon.png");
img.width = 500;
document.body.appendChild(img);
效果

6.使用plugin
代碼壓縮
npm install --save-dev webpack
webpack.config.js
var webpack = require("webpack");
var uglifyJsPlugin = webpack.optimize.UglifyJsPlugin;
module.exports = {
entry: "./main.js",
output: {
filename: "bundle.js"
},
plugins: [
new uglifyJsPlugin({
compress: {
warnings: false
}
})
]
}
index.html
<script src="bundle.js"></script>
main.js
document.write("hello world");
/*
占位占位
*/
document.write(a());
function a() {
var fsdfsdf = "haha";
return fsdfsdf;
}
var sdfdsfs;
效果:

可以看出代碼已經(jīng)壓縮過了
公共模塊的提取
CommonsChunkPlugin
作用: 將所有的依賴庫打包為一個文件
webpack.config.js
var webpack = require("webpack");
...
module.exports = {
entry: {
// 入口文件
app: "./src/main.js",
// 依賴的文件
vendor: [
"jquery",
"director" //路由
]
},
output: {
path: __dirname + 'dist',
filename: "bundle.js"
},
...
plugins: [
// 將 entry.vendor 數(shù)組中的所有依賴文件打包為vendor.js
new webpack.optimize.CommonsChunkPlugin('vendor', 'vendor.js')
]
}
index.html
<script src="vendor.js"></script>
<script src="bundle.js"></script>
自動打開瀏覽器
npm install --save-dev open-browser-webpack-plugin
webpack.config.js
var openBrowserPlugin = require("open-browser-webpack-plugin");
module.exports = {
entry: "./main.js",
output: {
filename: "bundle.js"
},
plugins: [
new openBrowserPlugin({
url: "http://localhost:8080"
})
]
}
運行webpack-dev-server會自動打開瀏覽器
參考資料
用webpack的CommonsChunkPlugin提取公共代碼的3種方式