Webpack4優化之路

簡介

Webpack4 那點兒東西 基於webpack4總結了一些webpack的常見配置,可是webpack 各類強大的配置有時候讓你不堪重負,會打包不少的文件,遍歷解析不少文件。。。。。總之,這些操做會讓webpack打包過程變得很慢,因此開發過程當中咱們不得不去優化一些配置,讓webpack更好的服務於咱們的開發。vue

動態連接庫DLL

即把基礎模塊的代碼打包進入動態連接庫裏,好比經常使用的react,vue等,當須要導入的模塊在動態鏈接庫裏的時候,模塊不能再次被打包,而是去動態鏈接庫裏獲取node

  1. 建立一個webpack.dll.config.js文件打包經常使用類庫到dll中
module.exports = {
    entry: {
        react: ['vue'] //vue模塊打包到一個動態鏈接庫
    },
    output: {
        path: path.resolve(__dirname, 'dist'),
        filename: '[name].dll.js', //輸出動態鏈接庫的文件名稱
        library: '_dll_[name]' //全局變量名稱
    },
    plugins: [
        new webpack.DllPlugin({
            name: '_dll_[name]', //和output.library中一致,也就是輸出的manifest.json中的 name值
            path: path.join(__dirname, 'dist', '[name].manifest.json')
        })
    ]
}
webpack --config webpack.dll.config.js --mode production
複製代碼
  1. 在住配置文件 webpack.config.js中加入如下代碼
plugins: [
 new webpack.DllReferencePlugin({
       manifest: require(path.join(__dirname, 'dist', 'vue.manifest.json')),
   })
]
webpack --config webpack.config.js --mode development
複製代碼

這樣會從dll中獲取vue,並且不用再次打包vue了。react

Webpack熱替換之HMR

Hot Module Replacement(如下簡稱 HMR)是 webpack 中超級有用的特性之一 ,當你對代碼進行修改並保存後,webpack 將對代碼從新打包,並將新的模塊發送到瀏覽器端,瀏覽器經過新的模塊替換老的模塊,這樣在不刷新瀏覽器的前提下就可以對應用進行更新。從而減小不少時間。の。。。。好比,頁面中有一個modal框,須要點擊button觸發modal顯示,在開發過程當中,若是修改了modal 的樣式,觸發瀏覽器刷新,你還須要再次點擊button才能看到修改後的modal樣式,可是熱替換是不須要刷新瀏覽器的,能夠直接觀察到修改後的變化。 上文中已經介紹了watch的用法,可是watch是針對打包時文件發生變化進行從新打包,而HMR是針對webpack-dev-server的。webpack

  1. devserver配置以下
devServer: {//配置此靜態文件服務器,能夠用來預覽打包後項目
    inline:true,//打包後加入一個websocket客戶端
    hot:true,//熱加載
    contentBase: path.resolve(__dirname, 'dist'),//開發服務運行時的文件根目錄
    host: 'localhost',//主機地址
    port: 9090,//端口號
    compress: true//開發服務器是否啓動gzip等壓縮
}
複製代碼
  1. plugins配置項加入如下兩行
new webpack.HotModuleReplacementPlugin(),
 new webpack.NamedModulesPlugin()//用戶名替代id
複製代碼

3.業務代碼中的修改git

if(module.hot) {
    module.hot.accept('./hello.js', function() {
        div.innerHTML = hello()
    })
}
複製代碼
  1. 原理及流程解析大體流程: webpack-dev-server能夠和瀏覽器之間創建一個web socket進行通訊,一旦新文件被打包出來,webpack-dev-server就告訴瀏覽器這個消息,這時瀏覽器就能夠自動刷新頁面或者進行熱替換操做。當一個模塊b發生改變,而模塊內又沒有HMR代碼(相似於上述3中的代碼)來處理這一消息時,那這一消息就會被傳遞到依賴模塊b的其餘模塊上;若是消息在新模塊上沒有被捕獲的話就會再次進行傳遞;若是全部的消息都被捕獲了的話,那咱們的應用就應該已經按照代碼進行了更新;反之若是有消息冒泡到了入口(entry)文件尚未被捕獲的話,那就說明咱們的代碼中沒有處理這類變動方法,那webpack就會刷新瀏覽器頁面,即從HMR回退到LiveReload。

Tree Shaking

tree shaking 是一個術語,一般用於描述移除 JavaScript 上下文中的未引用代碼。這個術語和概念其實是興起於 ES2015 模塊打包工具 rollup。你能夠將應用程序想象成一棵樹。綠色表示實際用到的源碼和 library,是樹上活的樹葉。灰色表示無用的代碼,是秋天樹上枯萎的樹葉。爲了除去死去的樹葉,你必須搖動這棵樹,使它們落下。可是webpakc的Tree Shaking依賴靜態的ES6模塊化語法即經過import和export導入導出的代碼,並且須要引入一個可以刪除未引用代碼(dead code)的壓縮工具(minifier)(例如 UglifyJSPlugin)或者在運行命令的時候用webpack --display-used-exports --optimize-minimize --mode productiongithub

好比如下代碼web

export function getName() {
    return 'hello world';
}
export function getAge() {
    return 9999;
}
複製代碼

若是你只引用了其中一個,那麼經過Tree Shaking會剔除另外一個未用到的,打包的時候直接忽略。json

{
    test: /\.js/,
    use: {
        loader: 'babel-loader',
        query: {
            presets: ["env", {
+                                   modules: false //關閉 Babel 的模塊轉換功能,保留本來的 ES6 模塊化語法
+                               }]
        }
    }
}
const UglifyJSPlugin = require('uglifyjs-webpack-plugin');
plugins: [
    new UglifyJSPlugin()
 ]
webpack --display-used-exports --optimize-minimize
複製代碼

提取公共代碼

這個變化仍是很大的,以前的webpack版本用的都是commonchunkplugin,可是webpack4開始使用common-chunk-and-vendor-chunk 配置以下:瀏覽器

optimization: {
	splitChunks: {
		cacheGroups: {
			commons: {
				chunks: "initial",
				minChunks: 2,
				maxInitialRequests: 5, // The default limit is too small to showcase the effect
				minSize: 0 // This is example is too small to create commons chunks
			},
			vendor: {
				test: /node_modules/,
				chunks: "initial",
				name: "vendor",
				priority: 10,
				enforce: true
			}
		}
	}
}
複製代碼

Scope Hoisting

做用域提高,這是在webpack3中所提出來的。它會使代碼體積更小,由於函數申明語句會產生大量代碼.bash

const ModuleConcatenationPlugin = require('webpack/lib/optimize/ModuleConcatenationPlugin');
plugins: [
// 開啓 Scope Hoisting
new ModuleConcatenationPlugin(),
],
複製代碼

CDN

對於靜態資源的處理,放入CDN是一個很好的選擇,webpack中配置CDN的方式以下:

output: {
    path: path.resolve(__dirname, 'dist'),
    filename: '[name]_[hash:8].js',
    publicPath: 'http://static.xxxx.com/'
},
複製代碼

多進程之HappyPack

HappyPack就能讓Webpack把任務分解給多個子進程去併發的執行,子進程處理完後再把結果發送給主進程,其中子進程的個數爲cpu的個數減去1,須要在loader處修改以下

use: 'happypack/loader?id=babel',
複製代碼

而且在plugin中添加如下代碼:

new HappyPack({
    id: 'babel',
    //如何處理.js文件,和rules裏的配置相同
    loaders: [{
        loader: 'babel-loader',
        query: {
            presets: [
                "env", "stage-0"
            ]
        }
    }]
}),
複製代碼

小結

以上爲webpack配置中的一些常見優化方案,可是根據項目的不一樣,須要選擇的方案也不太同樣,多嘗試,根據特定的環境選擇特定的優化方案,我以爲是一件比較不錯的事情。

相關文章
相關標籤/搜索