要想讓webpack為我所用,不僅要求我們在loader使用上得心應手,更離不開對plugins的熟練使用。
Pre:本文,承接loader全解析
如果說把webpack比喻成一臺豆漿機,我們需要一杯豆漿喝,我們要:
- 準備好原材料,好比我們的 entry 入口起點的處理;
- 選擇豆漿品種,好比我們在選擇 loader 載入器;
- 攪拌電機工作,好比我們 plugins 外掛的大用處;
- 完成倒出品嚐,好比我們 output 輸出檔案的處理;
- 電力保障線上,好比我們 devServer 服務開啟。
這一形象的比喻,目的在於幫助我們理解webpack的工作機制,要想用好它,就必須清楚每個module的原理和使用方法。下面重點談談plugins的大用處:
外掛(plugins)
loader 僅在每個檔案的基礎上執行轉換,而 外掛(plugins) 更常用於(但不限於)在打包模組的 “compilation” 和 “chunk” 生命週期執行操作和自定義功能。webpack 的外掛系統極其強大和可定製化。
使用方法:
想要使用一個外掛,你只需要 require() 它,然後把它新增到 plugins 陣列中。
多數外掛可以通過選項(option)自定義。你也可以在一個配置檔案中因為不同目的而多次使用同一個外掛,這時需要通過使用 new 來建立它的一個例項。
在webpack.config.js配置如下:const HtmlWebpackPlugin = require('html-webpack-plugin'); const webpack = require('webpack'); const path = require('path'); const config = { //入口配置 entry: './path/to/my/entry/file.js', //輸出配置 output: { path: path.resolve(__dirname, 'dist'), filename: 'my-first-webpack.bundle.js' }, //模組loader載入轉換 module: { rules: [ { test: /\.txt$/, use: 'raw-loader' } ] }, //外掛呼叫完成功能定製 plugins: [ //壓縮js外掛 new webpack.optimize.UglifyJsPlugin(), //以index.html檔案為模板生成html5新檔案 new HtmlWebpackPlugin({template: './src/index.html'}) ] }; module.exports = config;複製程式碼
常用webpack外掛舉例
webpack 有著豐富的外掛介面(rich plugin interface)。webpack 自身的多數功能都使用這個外掛介面。這個外掛介面使 webpack 變得極其靈活。
更多外掛使用還請移步官網。CommonsChunkPlugin
The CommonsChunkPlugin is an opt-in feature that creates a separate file (known as a chunk), consisting of common modules shared between multiple entry points. By separating common modules from bundles, the resulting chunked file can be loaded once initially, and stored in cache for later use. This results in pagespeed optimizations as the browser can quickly serve the shared code from cache, rather than being forced to load a larger bundle whenever a new page is visited.
大致翻譯過來就是這個外掛可以幫助你從眾多模組中抽離併合並出一個公共模組檔案,瀏覽器只載入一次即可,給頁面載入帶來速度上的提升。
注意: 此外掛屬於webpack內建 無需安裝
使用方法:new webpack.optimize.CommonsChunkPlugin(options)
配置:
{
name: string, // or
names: string[],
// 這是 common chunk 的名稱。已經存在的 chunk 可以通過傳入一個已存在的 chunk 名稱而被選擇。
// 如果一個字串陣列被傳入,這相當於外掛針對每個 chunk 名被多次呼叫
filename: string,
// common chunk 的檔名模板。可以包含與 `output.filename` 相同的佔位符。
minChunks: number|Infinity|function(module, count) -> boolean,
// 在傳入 公共chunk(commons chunk) 之前所需要包含的最少數量的 chunks 。
// 數量必須大於等於2,或者少於等於 chunks的數量
chunks: string[],
// 通過 chunk name 去選擇 chunks 的來源。chunk 必須是 公共chunk 的子模組。
// 如果被忽略,所有的,所有的 入口chunk (entry chunk) 都會被選擇。
children: boolean,
// 如果設定為 `true`,所有 公共chunk 的子模組都會被選擇
deepChildren: boolean,
// If `true` all descendants of the commons chunk are selected
async: boolean|string,
// 如果設定為 `true`,一個非同步的 公共chunk 會作為 `options.name` 的子模組,和 `options.chunks` 的兄弟模組被建立。
minSize: number,
// 在 公共chunk 被建立立之前,所有 公共模組 (common module) 的最少大小。
}複製程式碼
舉例:
// 提取公共檔案
new webpack.optimize.CommonsChunkPlugin({
name: 'reset',
filename: 'vendor/common.js',
//(模組必須被3個 入口chunk 共享)
minChunks: 3
}),複製程式碼
- ExtractTextWebpackPlugin
Extract text from a bundle, or bundles, into a separate file.
這個外掛是用來分離的,出單獨的一個檔案
安裝:
npm install --save-dev extract-text-webpack-plugin複製程式碼
使用方法:
const ExtractTextPlugin = require("extract-text-webpack-plugin");
module.exports = {
module: {
rules: [
{
test: /\.css$/,
use: ExtractTextPlugin.extract({
fallback: "style-loader",
use: "css-loader"
})
}
]
},
plugins: [
new ExtractTextPlugin("styles.css"),
]
}複製程式碼
它會將所有的入口 chunk(entry chunks)中引用的 *.css,移動到獨立分離的 CSS 檔案。因此,你的樣式將不再內嵌到 JS bundle 中,而是會放到一個單獨的 CSS 檔案(即 styles.css)當中。
- HotModuleReplacementPlugin
模組熱替換外掛,啟用熱替換模組(Hot Module Replacement),也被稱為 HMR。
注意:永遠不要在生產環境(production)下啟用 HMR
用法:
啟用 HMR 非常簡單,在大多數情況下也不需要設定選項。new webpack.HotModuleReplacementPlugin({ // Options... })複製程式碼
- HtmlWebpackPlugin
它簡化了HTML檔案的建立,以便為您的webpack包提供服務。 這對於在檔名中包含每次會隨著變異會發生變化的雜湊的webpack bundle尤其有用。
安裝
npm install --save-dev html-webpack-plugin複製程式碼
使用方法:
SPA單頁面時:
const HtmlWebpackPlugin = require('html-webpack-plugin');
var webpackConfig = {
entry: 'index.js',
output: {
path: 'dist',
filename: 'index_bundle.js'
},
plugins: [new HtmlWebpackPlugin()]
};
module.exports = webpackConfig;複製程式碼
這將會產生一個包含以下內容的檔案 dist/index.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>webpack App</title>
</head>
<body>
<script src="index_bundle.js"></script>
</body>
</html>複製程式碼
多頁面時:
{
entry: 'index.js',
output: {
path: __dirname + '/dist',
filename: 'index_bundle.js'
},
plugins: [
new HtmlWebpackPlugin(), // Generates default index.html
new HtmlWebpackPlugin({ // Also generate a test.html
filename: 'test.html',
template: 'src/assets/test.html'
})
]
}複製程式碼
- ProvidePlugin
自動載入模組,而不必到處 import 或 require 。
當我們的應用大量使用jQuery或Zepto時,可以藉助此外掛實現一次認定,到處使用。
注意:webpack內建,不用安裝
要自動載入 jquery,我們可以將兩個變數都指向對應的 node 模組:
使用:Lodash Mapnew webpack.ProvidePlugin({ $: 'jquery', jQuery: 'jquery' })複製程式碼
new webpack.ProvidePlugin({ _map: ['lodash', 'map'] })複製程式碼
- UglifyjsWebpackPlugin
to minify your JavaScript
這個外掛用來壓縮你的js的,uglify翻譯過來是醜化,弄的難看,就是要變成在一堆的程式碼,從而減小程式碼檔案的體積。
安裝:
npm i -D uglifyjs-webpack-plugin複製程式碼
使用方法:
const UglifyJSPlugin = require('uglifyjs-webpack-plugin')
module.exports = {
plugins: [
new UglifyJSPlugin()
]
}複製程式碼
配置項:
{
parse: {
// parse options
},
compress: {
// compress options
},
mangle: {
// mangle options
properties: {
// mangle property options
}
},
output: {
// output options
},
sourceMap: {
// source map options
},
ecma: 5, // specify one of: 5, 6, 7 or 8
nameCache: null, // or specify a name cache object
toplevel: false,
ie8: false,
warnings: false,
}複製程式碼
更多引數請參考Uglifyjs官網