webpack性能優化之DllPlugin插件的使用

在我們的項目開發中,如果使用webpack來打包編譯我們的項目,我們都會遇到一個問題,當項目的依賴變得越來越多時,我們會發現webpack的打包速度會越來越慢,怎麼去解決這個問題呢。首先我們先思考一個問題,webpack打包的時候是把所有文件都打包,但是對於我們引入的那些第三方庫它是不會變的,有必要每次都打包嗎?我們是不是可以把這些東西都提取出來,只打包一次,讓頁面引入我們打包生成的庫文件,這樣以後每次打包就都把這個第三方的庫排除在外了,只在第一次打包的時候打包一次。這個功能的實現就是我們今天要說到的webpack-dllPlugin的使用
新建webpack.dll.js文件

 // webpack.dll.js
var path = require('path');
module.exports = {
   entry: {
       vendor: ['loadsh'] // 這裏面放我們需要打包的第三方庫文件,數組形式逗號隔開, 這裏以lodash爲例
   },
   output: {
       path: path.resolve(__dirname, 'dll'), // 講lodash打包到dll目錄下面
       filename: '[name].dll.js',
       library: '[name]'  // 全局變量verdor 會被掛載到window上
   }
}

在package.json 文件中配置打包命令

{
	"script": {
		"build:dll": "webpack --config  webpack.dll.js"
	}
}

執行命令就在dll目錄下生成了vendor.dll.js文件,裏面包含我們的lodash

npm run build:dll

我們已經生產了lodash的vendor文件,但是它沒有被用到呀,我們需要將它引入到html文件中,使用插件add-asset-html-webpack-plugin。記得一定要先npm install。我們在webpack.config.js裏面配置, plugins新增項

// webpack.config.js
plugins: [
    new AddAssetHtmlWebpackPlugin({
           filepath: path.resolve(__dirname, 'dll/vendor.dll.js') // 引入靜態資源路徑
     })
]

到了這一步,我們已經把生產的庫文件引入到html中了,但是我們項目中還是使用的是node_modules 裏面的第三方模塊, 並沒有使用我們打包dll裏面的vendor模塊。還需要在dll的配置中新增plugins對庫文件進行分析,產生一個json的隱射文件, 然後在webpack.congfig.js中就可以使用這個json文件來分析使用哪裏的庫
1.生成manifest.json映射文件

// webpack.dll.js
var webpack = require('webpack')
 plugins: [
       // 對要打包的庫文件進行分析(路徑隱射關係),分析的結果放在dll目錄下的manifest.json文件的中
       new webpack.DllPlugin({
           name: '[name]',
           path: path.resolve(__dirname, 'dll/[name].manifest.json') //
       })
   ]

2.webpack.config.js 分析映射文件

// webpack.config.js
 var webpack = require('webpack')
 plugins: [
      	new AddAssetHtmlWebpackPlugin({
           filepath: path.resolve(__dirname, 'dll/vendor.dll.js') // 
       }),
       // 新增 
       new webpack.DllReferencePlugin({
           manifest: path.resolve(__dirname, 'dll/vendor.manifest.json')
       })
 ]

代碼優化

以上就完成了我們第三庫文件打包的分離,只在第一次打包的時候打包。其它時候不打包,極大的加快了我們的webpack性能。
代碼優化, 上述代碼只打包了一個lodash,如果你想分開打包其它庫的時候,這裏不多解釋直接上代碼(完整代碼)。

  • webpack.dll.js新增打包項
// webpack.dll.js
var path = require('path');
var webpack = require('webpack')
module.exports = {
    mode: 'production',
    entry: {
        vendor: ['lodash'], 
        react: ['react', 'react-dom'] // 新增
    },
    output: {
        path: path.resolve(__dirname, 'dll'), 
        filename: '[name].dll.js',
        library: '[name]'
    },
    plugins: [
        // 對要打包的庫文件進行分析(路徑隱射關係),分析的結果放在dll目錄下的manifest.json文件的中
        new webpack.DllPlugin({
            name: '[name]',
            path: path.resolve(__dirname, 'dll/[name].manifest.json') //
        })
    ]
}
  • webpack.config.ls 代碼抽離優化
var fs = require('fs')
var path = require('path');
// 將plugins抽離
let plugins = [new HtmlWebpackPlugin({ template: 'index.html' }), new CleanWebpackPlugin()];
let dll = path.resolve(__dirname, 'dll')
// 獲取dll目錄下的文件名(有多個dll.js和多個manifest.json)
const files = fs.readdirSync(dll);
if (files && files.length) {
    files.forEach((file) => {
        // 當該文件是dll.js的文件
        if (/.*\.dll.js/.test(file)) {
            plugins.push(
                new AddAssetHtmlWebpackPlugin({
                    publicPath: 'js',
                    outputPath: 'js',
                    filepath: path.resolve(dll, file)
                })
            );
        }
        if (/.*\.manifest.json/.test(file)) {
            plugins.push(
                new webpack.DllReferencePlugin({
                    manifest: path.resolve(dll, file)
                })
            );
        }
    });
}
module.exports = {
	"plugin": plugins 
}

本文到此就結束了,使用該插件進行打包優化,速度快了很多,很高興今天和大家一起學習,下次再見~

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