本文系統講解vue-cli腳手架build目錄中的webpack.prod.conf.js配置文件
- 這個配置文件是webpack生產環境的核心配置文件
- 因爲這是一個系統的配置文件,將涉及不少的模塊和插件,因此這部份內容我將分多個文章講解,請關注我博客的其餘文章
- 關於註釋
- 當涉及到較複雜的解釋我將經過標識的方式(如(1))將解釋寫到單獨的註釋模塊,請自行查看
- 上代碼
// 下面是引入nodejs的路徑模塊
var path = require('path')
// 下面是utils工具配置文件,主要用來處理css類文件的loader
var utils = require('./utils')
// 下面引入webpack,來使用webpack內置插件
var webpack = require('webpack')
// 下面是config目錄下的index.js配置文件,主要用來定義了生產和開發環境的相關基礎配置
var config = require('../config')
// 下面是webpack的merger插件,主要用來處理配置對象合併的,能夠將一個大的配置對象拆分紅幾個小的,合併,相同的項將覆蓋
var merge = require('webpack-merge')
// 下面是webpack.base.conf.js配置文件,我其餘博客文章已經解釋過了,用來處理不一樣類型文件的loader
var baseWebpackConfig = require('./webpack.base.conf')
// copy-webpack-plugin使用來複制文件或者文件夾到指定的目錄的
var CopyWebpackPlugin = require('copy-webpack-plugin')
// html-webpack-plugin是生成html文件,能夠設置模板,以前的文章將過了
var HtmlWebpackPlugin = require('html-webpack-plugin')
// extract-text-webpack-plugin這個插件是用來將bundle中的css等文件產出單獨的bundle文件的,以前也詳細講過
var ExtractTextPlugin = require('extract-text-webpack-plugin')
// optimize-css-assets-webpack-plugin插件的做用是壓縮css代碼的,還能去掉extract-text-webpack-plugin插件抽離文件產生的重複代碼,由於同一個css可能在多個模塊中出現因此會致使重複代碼,換句話說這兩個插件是兩兄弟
// 詳情見(1)
var OptimizeCSSPlugin = require('optimize-css-assets-webpack-plugin')
// 若是當前環境變量NODE_ENV的值是testing,則導入 test.env.js配置文,設置env爲"testing"
// 若是當前環境變量NODE_ENV的值不是testing,則設置env爲"production"
var env = process.env.NODE_ENV === 'testing'
? require('../config/test.env')
: config.build.env
// 把當前的配置對象和基礎的配置對象合併
var webpackConfig = merge(baseWebpackConfig, {
module: {
// 下面就是把utils配置好的處理各類css類型的配置拿過來,和dev設置同樣,就是這裏多了個extract: true,此項是自定義項,設置爲true表示,生成獨立的文件
rules: utils.styleLoaders({
sourceMap: config.build.productionSourceMap,
extract: true
})
},
// devtool開發工具,用來生成個sourcemap方便調試
// 按理說這裏不用生成sourcemap屢次一舉,這裏生成了source-map類型的map文件,只用於生產環境
devtool: config.build.productionSourceMap ? '#source-map' : false,
output: {
// 打包後的文件放在dist目錄裏面
path: config.build.assetsRoot,
// 文件名稱使用 static/js/[name].[chunkhash].js, 其中name就是main,chunkhash就是模塊的hash值,用於瀏覽器緩存的
filename: utils.assetsPath('js/[name].[chunkhash].js'),
// chunkFilename是非入口模塊文件,也就是說filename文件中引用了chunckFilename
chunkFilename: utils.assetsPath('js/[id].[chunkhash].js')
},
plugins: [
// http://vuejs.github.io/vue-loader/en/workflow/production.html
// 下面是利用DefinePlugin插件,定義process.env環境變量爲env
new webpack.DefinePlugin({
'process.env': env
}),
new webpack.optimize.UglifyJsPlugin({
// UglifyJsPlugin插件是專門用來壓縮js文件的
compress: {
warnings: false // 禁止壓縮時候的警告信息,給用戶一種vue高大上沒有錯誤的感受
},
// 壓縮後生成map文件
sourceMap: true
}),
// extract css into its own file
new ExtractTextPlugin({
// 生成獨立的css文件,下面是生成獨立css文件的名稱
filename: utils.assetsPath('css/[name].[contenthash].css')
}),
// Compress extracted CSS. We are using this plugin so that possible
// duplicated CSS from different components can be deduped.
new OptimizeCSSPlugin({
// 壓縮css文件
cssProcessorOptions: {
safe: true
}
}),
// generate dist index.html with correct asset hash for caching.
// you can customize output by editing /index.html
// see https://github.com/ampedandwired/html-webpack-plugin
// 生成html頁面
new HtmlWebpackPlugin({
//非測試環境生成index.html
filename: process.env.NODE_ENV === 'testing'
? 'index.html'
: config.build.index,
// 模板是index.html加不加無所謂
template: 'index.html',
// 將js文件放到body標籤的結尾
inject: true,
minify: {
// 壓縮產出後的html頁面
removeComments: true,
collapseWhitespace: true,
removeAttributeQuotes: true
// more options:
// https://github.com/kangax/html-minifier#options-quick-reference
},
// necessary to consistently work with multiple chunks via CommonsChunkPlugin
// 分類要插到html頁面的模塊
chunksSortMode: 'dependency'
}),
// split vendor js into its own file
// 下面的插件是將打包後的文件中的第三方庫文件抽取出來,便於瀏覽器緩存,提升程序的運行速度
new webpack.optimize.CommonsChunkPlugin({
// common 模塊的名稱
name: 'vendor',
minChunks: function (module, count) {
// any required modules inside node_modules are extracted to vendor
// 將全部依賴於node_modules下面文件打包到vendor中
return (
module.resource &&
/\.js$/.test(module.resource) &&
module.resource.indexOf(
path.join(__dirname, '../node_modules')
) === 0
)
}
}),
// extract webpack runtime and module manifest to its own file in order to
// prevent vendor hash from being updated whenever app bundle is updated
// 把webpack的runtime代碼和module manifest代碼提取到manifest文件中,防止修改了代碼可是沒有修改第三方庫文件致使第三方庫文件也打包的問題
new webpack.optimize.CommonsChunkPlugin({
name: 'manifest',
chunks: ['vendor']
}),
// copy custom static assets
// 下面是複製文件的插件,我認爲在這裏並非起到複製文件的做用,而是過濾掉打包過程當中產生的以.開頭的文件
new CopyWebpackPlugin([
{
from: path.resolve(__dirname, '../static'),
to: config.build.assetsSubDirectory,
ignore: ['.*']
}
])
]
})
if (config.build.productionGzip) {
// 開啓Gzi壓縮打包後的文件,老鐵們知道這個爲何還能壓縮嗎??,就跟你打包壓縮包同樣,把這個壓縮包給瀏覽器,瀏覽器自動解壓的
// 你要知道,vue-cli默認將這個神奇的功能禁用掉的,理由是Surge 和 Netlify 靜態主機默認幫你把上傳的文件gzip了
var CompressionWebpackPlugin = require('compression-webpack-plugin')
webpackConfig.plugins.push(
new CompressionWebpackPlugin({
asset: '[path].gz[query]',
algorithm: 'gzip',
test: new RegExp( // 這裏是把js和css文件壓縮
'\\.(' +
config.build.productionGzipExtensions.join('|') +
')$'
),
threshold: 10240,
minRatio: 0.8
})
)
}
if (config.build.bundleAnalyzerReport) {
// 打包編譯後的文件打印出詳細的文件信息,vue-cli默認把這個禁用了,我的以爲仍是有點用的,能夠自行配置
var BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
webpackConfig.plugins.push(new BundleAnalyzerPlugin())
}
module.exports = webpackConfig
解釋
(1)optimize-css-assets-webpack-plugin插件
在生產環境中使用extract-text-webpack-plugin,最好也使用這個插件
使用方法以下
安裝 npm install --save-dev optimize-css-assets-webpack-plugin
還要安裝 cssnano 這是一個css編譯器 npm install --save-dev cssnano 這個vue-cli腳手架並無使用cssnano,可是這個插件的官方說要安裝cssnano,這是否是一個bug??
new OptimizeCssAssetsPlugin({
assetNameRegExp: /\.optimize\.css$/g, // 不寫默認是/\.css$/g
cssProcessor: require('cssnano'), // 編譯器選項,不寫默認是cssnano,因此使用這個插件無論怎樣都要cssnano
cssProcessorOptions: { discardComments: {removeAll: true } }, // 傳遞給編譯器的參數
canPrint: true // 是否可以輸出信息
})