webpack 通過(guò) plugins 實(shí)現(xiàn)各種功能。常見(jiàn)的 plugins 如下:
- webpack.DefinePlugin 定義環(huán)境變量
- webpack.EnvironmentPlugin 定義環(huán)境變量
- webpack.optimize.CommonsChunkPlugin 共用 js 打包
- html-webpack-plugin 使用模版生成 html 文件
- webpack-visualizer-plugin 輸出依賴文件分析圖表
- webpack.HotModuleReplacementPlugin 代碼熱更新擎值,用于調(diào)試模式
- webpack.optimize.OccurrenceOrderPlugin 調(diào)整模塊的打包順序鸭丛,用到次數(shù)更多的會(huì)出現(xiàn)在文件的前面
- webpack.NoErrorsPlugin 構(gòu)建過(guò)程中有報(bào)錯(cuò)说榆,不認(rèn)為構(gòu)建完成
- webpack.ProgressPlugin 輸出構(gòu)建進(jìn)度
- webpack.BannerPlugin 在文件頭添加注釋
- webpack.optimize.UglifyJsPlugin 壓縮 js
- webpack.optimize.DedupePlugin 去除重復(fù)依賴
- extract-text-webpack-plugin 從 js 中提取出樣式文件泽腮,單獨(dú)打包成 css 文件
webpack.DefinePlugin
這個(gè)插件可以把命令行的環(huán)境變量帶到瀏覽器端画髓。react 認(rèn)為 NODE_ENV=production
是生產(chǎn)環(huán)境录粱,類似的我們可以定義不同環(huán)境的 NODE_ENV
腻格,在瀏覽器代碼中通過(guò) process.env.NODE_ENV
變量拿到值。
const webpack = require('webpack');
const NODE_ENV = process.env.NODE_ENV; // 從命令行環(huán)境獲取 NODE_ENV 參數(shù)
module.exports = {
plugins: [
new webpack.DefinePlugin({
'process.env': {
'NODE_ENV': JSON.stringify(NODE_ENV)
} // 定義瀏覽器中的替換的變量為 `process.env.NODE_ENV`
})
]
}
在代碼中可以使用 process.env.NODE_ENV
獲取對(duì)應(yīng)的值啥繁。
webpack.EnvironmentPlugin
webpack.DefinePlugin 上面提到的功能可以被 webpack.EnvironmentPlugin 替代掉菜职。
const webpack = require('webpack');
module.exports = {
plugins: [
new webpack.EnvironmentPlugin([
'NODE_ENV'
])
]
}
效果同上。
webpack.optimize.CommonsChunkPlugin
可以提取多個(gè) entry 中共用的內(nèi)容旗闽,打包到一個(gè)共用 js 文件中去酬核,多個(gè)頁(yè)面可以都引用這個(gè)文件,以利用瀏覽器緩存适室,減少下載體積嫡意。
const webpack = require('webpack');
module.exports = {
plugins: [
new webpack.optimize.CommonsChunkPlugin({
names: ['common'],
filename: 'js/[name].js',
minChunks: 2
})
]
}
上面的配置會(huì)把用到 2 次及以上(在 minChunks 中定義)的內(nèi)容放到 js/common.js
中。配合 HtmlWebpackPlugin
可以自動(dòng)填充到 html 中捣辆。
names 可以傳多個(gè)文件名蔬螟,wepback 會(huì)把共用部分再拆分出來(lái)。
html-webpack-plugin
const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
plugins: [
new HtmlWebpackPlugin({
template: 'src/html/index.html', // ${SOURCE_PATH}/${HTML_FOLDER}/${htmlTemplateName}.html
filename: 'html/index.html', // ${HTML_FOLDER}/${entryName}.html
hash: true,
inject: 'body',
chunksSortMode: 'none',
chunks: [
'common',
'index'
]
})
]
}
這個(gè)插件可以根據(jù) html 模版生成 html 文件汽畴。結(jié)合上面的 CommonsChunkPlugin 可以動(dòng)態(tài)決定最后編譯出來(lái)的 html 中引用哪些 js 或者 css 文件旧巾。
-
template
: 選用的模版文件 -
filename
: 最終生成的 html 文件名稱,其中可以帶上路徑名 -
hash
: 是否在文件后添加 hash忍些,用于禁用緩存 -
inject
: 文件插入的位置鲁猩。可以選擇在body
還是head
中 -
chunks
: 文件中插入的 entry 名稱罢坝,注意必須在 entry 中有對(duì)應(yīng)的申明廓握,或者是使用 CommonsChunkPlugin 提取出來(lái)的 chunk -
chunksSortMode
: 默認(rèn)地,插件會(huì)根據(jù)規(guī)則重新調(diào)整 chunks 的順序嘁酿。none
表示排序依據(jù) webpack 提供的規(guī)則
利用這個(gè)插件疾棵,我們可以實(shí)現(xiàn)項(xiàng)目下統(tǒng)一的模版定義,而不再需要每個(gè)入口 entry 都寫(xiě)一個(gè) html 去引用痹仙,而是動(dòng)態(tài)根據(jù) entry 名稱去生成 html。
webpack-visualizer-plugin
const Visualizer = require('webpack-visualizer-plugin');
module.exports = {
plugins: [
new Visualizer()
]
}
構(gòu)建輸出目錄下會(huì)有一個(gè) stats.html 文件殉了,其中包含了各個(gè)依賴來(lái)源和大小开仰。
可以看到這里用到了 lodash.merge 占了 56.8k。如果引入整個(gè) lodash 則整個(gè)體積會(huì)大很多。
代碼中
import _ from 'lodash';
_.merge({}, {/* ... */});
會(huì)導(dǎo)致引入整個(gè) lodash 庫(kù)众弓《鹘Γ可以修改成
import _merge from 'lodash.merge';
_merge({}, {/* ... */});
類似地
import { RaisedButton } from 'material-ui';
會(huì)引入所有的 material-ui 組件,應(yīng)該修改成
import RaisedButton from 'material-ui/RaisedButton';
ant-design 提供了 babel-plugin-import 以工具的形式處理了上面的寫(xiě)法谓娃。