Webpack——打包優化

引言

其實,相信很多隻是從事快速應用開發的同學,對於 Webpack打包優化方面可能是一知半解(我深有感觸…)。但是,作爲一名從事編程的人,我一直推崇的就是用編程高效、快速解決一些問題。因爲,如果只是解決問題,我想這不是我想要的,就比如只會迭代不會遞歸,以及還停留在 console.log調試代碼等等。

當然,人總是從未知向知一點到知一些到構建完整的知識體系過渡,只要堅持,未知終將變爲已知。那麼,回到今天的正題,如何用Webpack進行一些打包的優化?

在我們開始本篇文章之前,我們需要先安裝兩個 Plugin用於分析 Wepack打包的時間和打包後的各個模塊的大小:
1.speed-measure-webpack-plugin,它會分析每個 Loader在打包過程中的耗時:
a. 首先安裝依賴

npm install --save-dev speed-measure-webpack-plugin

b. 在 webpack.config.js中使用

// 引入
const SpeedMeasurePlugin = require('speed-measure-plugin')
const speedMeasure = new SpeedMeasurePlugin

// 配置
const config = {
	....
}
// 用 speed 插件包裹導出
module.exports = speedMeasure.wrap(config)

2.webpack-bundle-analyzer,它會分析打包後的各個模塊所佔用的大小:
a. 安裝依賴

npm install --save-dev webpack-bundle-analyzer

b. 配置 webpack.config.js

// 引入
const BundleAnalyzer = require('webpack-bundle-analyzer')

const config = {
	...
	plugin: [
		...
		new BundleAnalyzer()
	]
}

c. 配置 package.js中的 scripts命令

{
	...
	'scripts`: {
		"analyze": "cross-env NODE_ENV=production npm_config_report=true npm run build",
	}
}

一、resolve 優化


resolve.modules

配置第三方模塊對應的路徑,即針對於代碼中import from 'react'之類的對應 from後面的字符串,即不是絕對路徑,又不是相對路徑時命中的邏輯。

resolve: {
	modules: [
		resolve('node_modules') // 指定第三方模塊去 node_modules 中查找
	]
}

resolve.alias

針對特定的路徑匹配(可以理解爲指定)到對應已設好的目錄,通常我們會用來指定自定義的組件文件夾。

resolve: {
	alias: [
		'component': resolve('src/component')
	]
}

二、module 優化


noParse

忽略掉對一些文件的解析,例如 Jquery之類的。

module: {
	noParse: /Jquery/
}

loader優化

主要是用好一些 queryparams以及精確地指定需要使用和不使用 loader的地方,即 includeexclude,例如對於 babel-loader而言:

modulde: {
	rules: [
		{
			test: /\.js$/,
			loader: 'babel-loader?cacheDirectory=true', // 緩存解析過的文件
			include: resolve('src'), 
			exclude: /node_modules/
		}
	]
}

三、plugins 優化


webpack-parallel-uglify-plugin

主要是針對於代碼壓縮方面的優化,當然這是相對於Webpack.optimize.UglifyJsPlugin而言,因爲 Webpack自帶的 UglifyJsPlugin只能同步壓縮代碼,而webpack-parallel-uglify-plugin可以實現並行壓縮代碼的效果,這樣一來就很好地利用了 CPU,從而提高壓縮速度。

const ParallelUglifyPlugin = require('webpack-parallel-uglify-plugin')

new ParallelUglifyPlugin({
	parallel: true, // 開啓並行壓縮 默認線程=cup-1
	cache: path.resolve(__dirname, 'dist'),
	uglifyOptions: {
		output: {
		  comments: false
		},
		compress: {
		  drop_debugger: true,
		  drop_console: true
		},
		warnings: false
	}
}),

hard-source-webpack-plugin

爲模塊提供中間緩存的作用,即在很大程度上會縮短第二次打包的時間。

const HardSourcePlugin = require('hard-source-webpack-plugin')

plugins: [
	new HardSourcePlugin
]

happypack

Webpack壓縮的過程中,很重要的一個過程就是babel解析轉化代碼的過程,所以優化這個過程,在一定程度上也可以提高我們的打包速度。同樣地,由於Webpack整個打包地過程是同步進行的,而happypack則可以實現多線程並行打包,它通常用於配合loader一起使用,例如它和babel-loader一起使用:

const HappyPack = require('happypack')
const os = require('os')
const happyThreadPool = HappyPack.ThreadPool({ size: os.cpus().length })

module: {
	rules: [
		{
			test: /\.js$/,
			loader: isProd ? 'happypack/loader?id=happybabel':'babel-loader' // 需要區分生產和開發環境
			include: [resolve('src')],
			exclude: /node_modules/,
		}
	]
},
plugins: isProd ? [
	new HappyPack({	
        id: 'happyBabel',
        loaders: [{
          loader: 'babel-loader?cacheDirectory=true'
        }],
        threadPool: happyThreadPool,
        verbose: true // 允許 HappyPack 輸出日誌
    })
]:[]

四、其他優化


externals

對於一些文件我們可以預先放在 CDN上,然後 index.html中通過 script標籤引入,通過配置 externals,我們仍然可以在代碼中通過 import導入。例如,拿 Jquery舉例:
index.html中引入:

<script src="http://wjc.cdn.com/jquery.min.js"></script>

webpack中配置 externals

{
	externals: {
		'jquery': 'jquery'
	}
}

在項目中使用:

import $ from 'jquery'

總結


其實對於 webpack的優化還有其他的途徑,例如將第三方依賴分離出來直接放到 CDN上,當然首先要保證這些依賴已經編譯成 ES5。又或者結合 DllPlugin將第三方依賴(例如 Vue)之類的不會發生變化的單獨打包成js文件,然後在index.html中通過script標籤引入等等。後續,時間充裕我會繼續補上各種優化手段。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章