webpack概念以及配置檔案詳解
Webpack 概念
本質上,webpack 是一個現代 JavaScript 應用程式的靜態模組打包器(module bundler)。當 webpack 處理應用程式時,它會遞迴地構建一個依賴關係圖(dependency graph),其中包含應用程式需要的每個模組,然後將所有這些模組打包成一個或多個 bundle。
模組(Modules):
在模組化程式設計中,將程式分解成離散功能模組(discrete chunks of functionality)。
每個模組具有比完整程式更小的接觸面,使得校驗、除錯、測試輕而易舉。精心編寫的模組提供了可靠的抽象和封裝界限,使得應用程式中每個模組都具有條理清楚的設計和明確的目的。
webpack 模組:
webpack 模組能夠以各種方式表達它們3的依賴關係,例如:
ES2015import
語句
CommonJsrequire()
語句
AMDdefine
和require
語句
css/sass/less 檔案中的@import
語句
樣式(url(...)
)或 HTML 檔案(<img src=...>
)中的圖片連結(image url)
webpack 1 需要特定的 loader 來轉換 ES 2015import
,然而通過 webpack 2 可以開箱即用。
webpack 支援的模組型別:
webpack 通過 loader 可以支援各種語言和前處理器編寫模組。loader 描述了 webpack 如何處理非 JavaScript(non-JavaScript)模組,並且在 bundle 中引入這些依賴。
webpack是高度可配置的,但是必須先理解4個核心概念:
一、入口(entry):入口起點(entry point)指示 webpack 應該使用哪個模組,來作為構建其內部依賴圖的開始。進入入口起點後, webpack 會找出有哪些模組和庫是入口起點(直接和間接)依賴的。* 每個依賴項隨即被處理,最後輸出到稱之為 bundles 的檔案中。*
//可以通過在 webpack.config.js 檔案中配置 entry 屬性,來指定一個入口起點:
module.exports = {
entry : './path/to/my/entry/files.js'
}
更多使用方法查詢:https://doc.webpack-china.org/concepts/entry-points
二、 輸出(output):告訴 webpack 在哪裡輸出它所建立的 bundles ,以及如何命名這些檔案。
module.exports = {
output: {
path : './dist',
//按需載入(on-demand-load)或載入外部資源(external resources)(如圖片、檔案等)
publicPath : '/dist',
filename : 'js/[name].js'
}
}
程式碼解釋:
1.通過 output.filename
和output.path
屬性,來告訴 webpack bundle 的名稱,以及我們想要生成(emit)到哪裡。
2.更多屬性請查詢:https://doc.webpack-china.org/configuration/output
三、loader:讓 webpack 能夠處理那些非 JavaScript 檔案(webpack 自身只理解 JavaScript)。loader 可以將所有型別的檔案轉換為 webpack 能夠處理的有效模組,然後就可以利用 webpack 的打包能力,對它們進行處理。
loader 用於對模組的原始碼進行轉換。loader 可以使你在
import
或“載入”模組時預處理檔案。因此,loader 類似於其他構建工具中”任務(task)”,並提供了處理前端構建步驟的強大辦法。loader 可以將檔案從不同的語言轉換為 JavaScript ,或將內聯影象轉換為 data URL. loader 甚至允許你直接在 JavaScript 模組中import
CSS 檔案。
使用方法查閱:https://doc.webpack-china.org/concepts/loaders
四、 外掛(plugins):外掛的目的在於解決 loader 無法實現的其他事。
webpack 外掛是一個具有
apply
屬性的 JavaScript 物件。apply
屬性會被webpack compiler 呼叫,並且 compiler 物件可在整個編譯生命週期訪問。
Function.prototype.apply
:通過這個方法可以把任意函式作為外掛傳遞(this
將指向compiler
)。
具體用法請查閱:https://doc.webpack-china.org/concepts/plugins
完整的 webpack 配置檔案例項(webpack 1.X)
var webpack = require('webpack');
var ExtractTextPlugin = require("extract-text-webpack-plugin");
var HtmlWebpackPlugin = require('html-webpack-plugin');
//環境變數配置,dev / online
var WEBPACK_ENV = process.env.WEBPACK_ENV || 'dev';
console.log(WEBPACK_ENV);
//獲取html-webpack-plugin的引數的方法
var getHtmlConfig=function(name,title){
return {
template : './src/view/' + name + '.html',
filename : 'view/' + name + '.html',
title : title,
inject : true,
hash : true,
chunks : ['common',name]
};
};
//webpack config
var config ={
//多個入口配置
entry : {
'common' : ['./src/page/common/index.js','webpack-dev-server/client?http://localhost:8088/'],
'index' : ['./src/page/index/index.js'],
'list' : ['./src/page/list/index.js'],
'detail' : ['./src/page/detail/index.js'],
'cart' : ['./src/page/cart/index.js'],
'order-confirm' : ['./src/page/order-confirm/index.js'],
'order-list' : ['./src/page/order-list/index.js'],
'order-detail' : ['./src/page/order-detail/index.js'],
'payment' : ['./src/page/payment/index.js'],
'user-login' : ['./src/page/user-login/index.js'],
'user-register' : ['./src/page/user-register/index.js'],
'user-pass-reset' : ['./src/page/user-pass-reset/index.js'],
'user-center' : ['./src/page/user-center/index.js'],
'user-center-update' : ['./src/page/user-center-update/index.js'],
'user-pass-update' : ['./src/page/user-pass-update/index.js'],
'result' : ['./src/page/result/index.js'],
},
//output
output : {
path : './dist',
publicPath : '/dist',
filename : 'js/[name].js'
},
/*防止將某些 import 的包(package)打包到 bundle 中,
而是在執行時(runtime)再去從外部獲取這些擴充套件依賴*/
externals : {
'jquery' : 'window.jQuery'
},
//loaders
module : {
loaders : [
{ test : /\.css$/, loader:ExtractTextPlugin.extract("style-loader","css-loader")},
{ test : /\.(gif|png|jpg|woff|svg|eot|ttf)\??.*$/, loader:"url-loader?limit=100&name=resource/[name].[ext]"},
{
test : /\.string$/,
loader : 'html-loader',
query : {
minimize : true,
removeAttributeQuotes : false
}
}
]
},
//解析
resolve : {
//建立 import 或 require 的別名,來確保模組引入變得更簡單。
alias : {
node_modules : __dirname + '/node_modules',
util : __dirname + '/src/util',
page : __dirname + '/src/page',
service : __dirname + '/src/service',
image : __dirname + '/src/image'
}
},
//外掛
plugins : [
//獨立通用模組到js/base.js
new webpack.optimize.CommonsChunkPlugin({
name : 'common',
filename : 'js/base.js'
}),
//把css單獨打包到檔案裡
new ExtractTextPlugin("css/[name].css"),
//html模板的處理
new HtmlWebpackPlugin(getHtmlConfig('index','首頁')),
new HtmlWebpackPlugin(getHtmlConfig('list','商品列表')),
new HtmlWebpackPlugin(getHtmlConfig('detail','商品詳情')),
new HtmlWebpackPlugin(getHtmlConfig('cart','購物車')),
new HtmlWebpackPlugin(getHtmlConfig('order-confirm','訂單確認')),
new HtmlWebpackPlugin(getHtmlConfig('order-list','訂單列表')),
new HtmlWebpackPlugin(getHtmlConfig('order-detail','訂單詳情')),
new HtmlWebpackPlugin(getHtmlConfig('payment','訂單支付')),
new HtmlWebpackPlugin(getHtmlConfig('user-login','使用者登入')),
new HtmlWebpackPlugin(getHtmlConfig('user-register','使用者註冊')),
new HtmlWebpackPlugin(getHtmlConfig('user-pass-reset','找回密碼')),
new HtmlWebpackPlugin(getHtmlConfig('user-center','個人中心')),
new HtmlWebpackPlugin(getHtmlConfig('user-center-update','修改個人資訊')),
new HtmlWebpackPlugin(getHtmlConfig('user-pass-update','修改密碼')),
new HtmlWebpackPlugin(getHtmlConfig('result','操作結果')),
]
};
if('dev' === WEBPACK_ENV){
config.entry.common.push('webpack-dev-server/client?http://localhost:8088/');
}
module.exports = config;