本章節,咱們一塊兒來探討如下問題:如何對編譯後的文件進行gzip壓縮,如何讓開發環境的控制檯輸出更加高逼格,如何更好的對編譯後的文件進行bundle分析等。css
若是你想節省帶寬提升網站速度,壓縮是一種簡單有效的方法。咱們模擬一次html的請求,想象一下瀏覽器和服務器的對話:html
那如今問題在哪呢?node
好吧,這系統是正常的,可是過低效了,坦白講100kb是一大段的文字,HTML是冗餘的,每個標籤都有一個幾乎相同的閉合標籤。雖然通篇文字都有重複,可是隻要你砍掉任何的內容,html都不會正常顯示。webpack
當文件太大的時候有什麼好辦法呢,就是gzip壓縮它。web
若是咱們傳輸一個替代原始大文件的zip的壓縮文件給瀏覽器,就會節省帶寬和下載時間。當瀏覽器能夠下載zip文件,解壓,而且渲染給用戶。下載很快,頁面加載也很快。如今,這個瀏覽器–服務器的會話大概是這樣的:正則表達式
狀況很簡單:文件越小,下載更快,用戶感覺更好。下面咱們講講經過webpack如何對文件進行gzip壓縮。算法
開啓gzip壓縮,須要在webpack配置文件中添加一個plugin,而咱們但願把是否開啓gzip壓縮作成可配置化,也就是說,這個gzip的plugin能夠選擇添加也能夠不添加。
咱們在config.js中的build下添加一個配置項,取名爲productionGzipnpm
productionGzip:true,
另外,咱們還須要修改下webpack.prod.conf.js。首先咱們把原來export出來的配置對象放一個變量webpackConfig中,這樣,咱們能夠後續訪問的到plugins數組,而且能夠追加plugin。稍微修改webpack.prod.conf.js,就像這樣:json
const webpackConfig=merge(baseWebpackConfig, { mode: 'production', output: { path: config.build.assetsRoot, filename: utils.assetsPath('js/[name].[chunkhash:16].js'), chunkFilename: utils.assetsPath('js/[id].[chunkhash].js') }, module: { rules: utils.styleLoaders({ sourceMap: config.build.productionSourceMap, extract: true, usePostCSS: true, cssModule:config.base.cssModule, cssModuleExcludePath:config.base.cssModuleExcludePath }) }, plugins: [ new HtmlWebpackPlugin({ template: config.build.index, inject: 'body', minify: { removeComments: true, collapseWhitespace: true, removeAttributeQuotes: true }, }), new CleanWebpackPlugin([config.build.assetsRoot], { allowExternal: true }), //導出css new MiniCssExtractPlugin({ filename: utils.assetsPath('css/[name].[hash].css'), chunkFilename: utils.assetsPath('css/[id].[hash].css'), }), ], optimization: { minimizer: [ new UglifyJSPlugin(), new OptimizeCSSAssetsPlugin({ cssProcessorOptions: true ? { map: { inline: false } } : {} }) ], splitChunks: { chunks: "all", minChunks: 1, cacheGroups: { framework: { priority: 200, test: "framework", name: "framework", enforce: true, reuseExistingChunk: true }, vendor: { priority: 10, test: /node_modules/, name: "vendor", enforce: true, reuseExistingChunk: true } } } } }); if (config.build.productionGzip) { //添加gzip壓縮插件 } module.exports = webpackConfig;
安裝gzip插件:compression-webpack-plugin數組
npm i compression-webpack-plugin --save-dev
使用只要把CompressionWebpackPlugin的實例對象追加到plugins內便可。支持傳入一個配置對象,相關說明:
要配置test,咱們在config.js的build屬性下新增長一個配置項,取名productionGzipExtensions,是一個數組,定義了那些後綴的文件要被壓縮。
productionGzipExtensions: ['js', 'css'],
而後這樣經過正則表達式:
new RegExp('\\.(' + config.build.productionGzipExtensions.join('|') + ')$')
配置的後綴會符合規則被gzip壓縮。
在webpack.prod.conf.js詳細的配置以下:
if (config.build.productionGzip) { const CompressionWebpackPlugin = require('compression-webpack-plugin') webpackConfig.plugins.push( new CompressionWebpackPlugin({ filename: '[path].gz[query]', algorithm: 'gzip', test: new RegExp( '\\.(' + config.build.productionGzipExtensions.join('|') + ')$' ), threshold: 10240, minRatio: 0.8 }) ) }
執行命令查看:
npm run build
查看編譯後生成的js,多了.gz文件,這個就是gzip壓縮後的文件,把它們上傳到服務器,而且服務器開啓gzip的功能便可。
npm install --save-dev webpack-bundle-analyzer
在config.js文件的build屬性下增長配置項bundleAnalyzerReport,用來表示是否開啓分析。這個變量會不停修改,因此咱們但願會在npm命令後面加上--report 就表示最後啓動bundle分析,不加就不會啓動bundle分析。怎麼作?經過process.env.npm_config_report能夠獲取到npm命令的配置
bundleAnalyzerReport: process.env.npm_config_report
在webpack.prod.conf.js增長以下代碼:
if (config.build.bundleAnalyzerReport) { const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin webpackConfig.plugins.push(new BundleAnalyzerPlugin()) }
分別如下2個執行試試看吧
npm run build
npm run build --report
經過增長--report 編譯成功後會啓動Webpack Bundle Analyzer。默認是http://127.0.0.1:8888。你能夠直觀看到每一個文件有哪些模塊被編譯進去。
這裏須要介紹2個npm庫。ora是一個能讓你在終端提示狀態的庫,chalk是方便咱們美化輸出的文本。
咱們先安裝這2個庫。
npm i --save-dev ora chalk
看看咱們原先的build方法,打開package.json,在scripts屬性下找到build屬性,能夠看到它的值是
webpack --config build/webpack.prod.conf.js
經過webpack命令在終端去編譯,咱們沒法獲取webpack的編譯狀態,webpack還提供了webpack方法,經過webpack方法編譯,編譯結束能夠執行回調函數。咱們須要美化終端的顯示,但願在編譯中能顯示編譯的狀態,編譯結束提示編譯成功,頗有必要修改爲經過webpack方法來編譯。
在build目錄下新增長一個build.js文件:內容以下:
const ora = require('ora'); const chalk = require('chalk') const webpack = require('webpack') const webpackConfig = require('./webpack.prod.conf'); const spinner = ora('編譯中...\n').start(); webpack(webpackConfig, function (err, stats) { if (err) { spinner.fail("編譯失敗"); console.log(err); return; } spinner.succeed('編譯已結束. \n'); process.stdout.write(stats.toString({ colors: true, modules: false, children: false, chunks: false, chunkModules: false }) + '\n\n'); console.log(chalk.cyan(' 編譯成功!\n')) console.log(chalk.yellow( ' 提示: 編譯後的文件能夠上傳而且部署到服務器\n' + ' 經過file:// 打開index.html不會起做用.\n' )) })
stats是編譯結束後webpack回調回來的參數,包含了編譯後的文件信息。
修改package.json的build屬性:
"build": "node build/build.js",
最後從新執行編譯命令看看吧
npm run build
觀察終端的輸出,是否是漂亮了不少。固然你能夠本身定製輸出的內容。