webpack實戰專案中程式碼打包和優化總結
網上關於webpack的優化的已經很多了,只是都比較零散,結合實戰專案自己做個總結
webpack 優化,實際專案中主要做到了一下幾點:
1、 檔案壓縮(css, js, html, 字型檔案, 圖片檔案)
2、 babel-loader 避免不必要的轉義
3、 babel-轉義結果進行快取
4、 公共模組的提取
5、 loader 轉為多程序
6、 按需載入
7、 DllPlugin 增加開發時打包速度
8、 Gzip進行檔案壓縮,webpack壓縮檔案,後臺可以再次進行壓縮
接下來針對每一個細節點進行詳細說明
1、檔案壓縮(html, css, js, 字型檔案,圖片檔案的壓縮和轉碼)
HtmlWebpackPlugin 官網連結 https://webpack.docschina.org/plugins/html-webpack-plugin/#src/components/Sidebar/Sidebar.jsx
關於 HtmlWebpackPlugin 的外掛使用就不過多贅述,參考官方文件,主要是用來壓縮程式碼以及自動將打包後生成的就是檔案插入到html中
如圖中所示的<script></script>標籤對js的引入都是該外掛的功勞,具體用法和配置如下
plugins: [ new HtmlWebpackPlugin({ filename: config.build.index, // 指定專案的生成名稱 template: 'index.html', // 將模板指向根那個目錄 inject: true, // 指定生成的<script></script>放在那個目錄 // 去掉空格、註釋、多餘的應用等等都在這裡配置 minify: { removeComments: true, collapseWhitespace: true, removeAttributeQuotes: true }, chunksSortMode: 'dependency', // 成產環境下的第三方依賴進行壓縮 }), ]
js 壓縮用法同上,就不細講了參見官方文件
https://webpack.docschina.org/guides/migrating/#uglifyjsplugin-sourcemap
css、圖片、字型檔案壓縮主要通過 loader 來進行
配置如下:
const webpackConfig = { module: { rules: [ { loader: 'css-loader', options: { sourceMap: options.sourceMap } } { test: /\.(mp4|webm|ogg|mp3|wav|flac|aac)(\?.*)?$/, loader: 'url-loader', options: { limit: 10000, // 限制壓縮檔案的大小 name: utils.assetsPath('media/[name].[hash:7].[ext]') // 檔案的路徑 } }, { test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, loader: 'url-loader', options: { limit: 10000, name: utils.assetsPath('fonts/[name].[hash:7].[ext]') } } ] } }
2、3 關於babel 的轉碼和轉碼快取
const webpackConfig = {
module: {
rules: [
{
test: /\.js$/,
loader: 'babel-loader?cacheDirectory=true', // 將轉譯結果快取至檔案系統
include: [resolve('src'), resolve('test'), resolve('node_modules/webpack-dev-server/client')] // 針對特定的檔案進行轉碼 通過include來配置,效率比 exclude 要高
},
]
}
}
4、公共模組的提取配置檔案如下
plugins配置如下
const webpackConfig = {
plugins: [
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor',
minChunks (module) {
return (
module.resource &&
/\.js$/.test(module.resource) &&
module.resource.indexOf(
path.join(__dirname, '../node_modules')
) === 0
)
}
}),
new webpack.optimize.CommonsChunkPlugin({
name: 'manifest',
minChunks: Infinity
}),
new webpack.optimize.CommonsChunkPlugin({
name: 'app',
async: 'vendor-async',
children: true,
minChunks: 3
}),
]
}
主要是目的是將第三方依賴抽取到公共模組放到vendor.js,然後針對動態引入的靜態檔案做進一步的抽離放到 manifest.js 中
5、多程序轉碼
具體用法和配置如下:
const HappyPack = require('happypack') // 引入第三方依賴
const happyThreadPool = HappyPack.ThreadPool({size: 5}) // 設定五個執行緒池這裡預設設定5個程序
module.exports = {
plugins: [
new HappyPack({
id: 'happyBabel', // 定義唯一id
threadPool: happyThreadPool, // 指定程序池
loaders: ['babel-loader?cacheDirectory=true']
}),
],
module: {
rules: [
{
test: /\.js$/,
loader: 'happypack/loader?id=happyBabel', // 通過唯一id進行查詢
include: [resolve('src'), resolve('test'), resolve('node_modules/webpack-dev-server/client')]
},
]
}
}
6、按需載入配置如下,實際生產中減少渲染壓力
{
path: '/test',
name: 'test',
component: resolve => require(['@/test'], resolve)
}
7、DllPlugin 外掛的使用(這裡提供簡單的配置,具體根據實際需要)
首先在你的build檔案加下新建 webpack.dall.config.js 檔案,內容如下
const path = require('path')
const webpack = require('webpack')
module.exports = {
entry: {
vendor: [
'aws-sdk',
'axios',
'moment',
'vue',
'vue-awesome-swiper',
'vue-router',
'vuex',
]
},
output: {
path: path.resolve(__dirname, '../static'), // 這裡通過絕對路徑指定生成檔案
filename: '[name].dll.js',
library: '[name]_library'
},
plugins: [
new webpack.DllPlugin({
path: path.resolve(__dirname, '../static', '[name]-manifest.json'),
name: '[name]_library'
}),
]
}
控制檯輸入 webpack --config build/webpack.dall.config.js
或者 在package.json檔案中進行如下配置 執行 npm/cnpm/yarn build build:dall
"scripts": {
"dev": "webpack-dev-server --inline --progress --config build/webpack.dev.conf.js",
"start": "npm run dev",
"test": "cross-env NODE_ENV=test env_config=test node build/build.js",
"lint": "eslint --ext .js,.vue src",
"build": "cross-env NODE_ENV=production env_config=prod node build/build.js",
"build:dall": "webpack --config build/webpack.dall.config.js"
},
將會看到static目錄項生成 vendor.dall.js 和 vende-manifest.json檔案,生成檔案如下
接下來在生 build 下的 webpack.prod.conf.js 進行引用
到這個時候我們進行一口深呼吸,以為打工打工告成,結果發現每次打包,然並卵,各位可憐的程式設計師,別急,萬里長征還剩最後一步,生成的js檔案你不引用還能怪誰啊親
看清楚了怎麼引用
找到你的index.html檔案手動引入 vendor.dll.js如下
第一次執行速度依然沒啥改變,當你再次執行的時候你會有飛一般的感覺
8、Gzip 檔案壓縮 根據實際情況,具體配置如下
if (config.build.productionGzip) {
const CompressionWebpackPlugin = require('compression-webpack-plugin')
webpackConfig.plugins.push(
new CompressionWebpackPlugin({
asset: '[path].gz[query]',
algorithm: 'gzip',
test: new RegExp(
'\\.(' +
config.build.productionGzipExtensions.join('|') +
')$'
),
threshold: 10240,
minRatio: 0.8
})
)
}
以上是個人在實際生產專案中的webpack打包以及程式碼壓縮的優化,從一開始的發版打包專案 接近一份到到 20幾秒將近一半時間的縮短,從一開始發版後端人員的抱怨:好沒好,你們打包這麼這麼慢 到 我靠!!!這麼快就好了。這是一種自我價值的體現和別人對你的肯定。
更多的乾貨請點選這裡 https://blog.csdn.net/woleigequshawanyier
歡迎各位看官的批評和指正,共同學習和成長
希望該文章對您有幫助,也希望得到您的鼓勵和支援