webpack打包优化

216 阅读1分钟

依赖外置

  • 提前定义好需要外置的第三方库
const cdn = { 
  js : [
    'https://cdn.bootcdn.net/ajax/libs/lodash.js/4.17.20/lodash.core.js',
    'https://cdn.bootcdn.net/ajax/libs/axios/0.20.0/axios.min.js',
    'https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.js',
    'https://unpkg.com/element-ui@2.13.2/lib/index.js',
    'https://cdn.jsdelivr.net/npm/vue'
  ],
  externals : {
    'vue':'Vue',
    'element-ui':'ELEMENT',
    'axios': 'axios',
    'jquery':'jQuery',
    "lodash": {
      commonjs: "lodash",//如果我们的库运行在Node.js环境中,import _ from 'lodash'等价于const _ = require('lodash')
      commonjs2: "lodash",//同上
      amd: "lodash",//如果我们的库使用require.js等加载,等价于 define(["lodash"], factory);
      root: "_"//如果我们的库在浏览器中使用,需要提供一个全局的变量‘_’,等价于 var _ = (window._) or (_);
    }
  }
}
  • 在webpack配置externals
module.exports = {
    externals:cdn.externals
}
  • 自定义插件动态添加自定义js
module.exports = {
    externals:cdn.externals,
    plugins: [
        new AddCommonScript({
          paths: cdn.js
        })
    ]
}
  • AddCommonScript插件 添加自定义的js
//旧版写法
class AddCommonScript {
    constructor (options) {
        this.options = options
    }
    apply (compiler) {
        let paths = this.options.paths
        compiler.plugin('compilation', (compilation, options) => {
            compilation.plugin('html-webpack-plugin-before-html-processing', (htmlPluginData, callback) => {
                paths.forEach((path) => {
                    htmlPluginData.assets.js.unshift(path)
                })
                callback(null, htmlPluginData)
            })
        })
    }
}

module.exports = AddCommonScript


//新版写法
class AddCommonScript {
  constructor (options) {
      this.options = options
  }
  apply (compiler) {
      let paths = this.options.paths
      compiler.hooks.compilation.tap('AddCommonScript', (compilation, options) => {
          compilation.hooks.htmlWebpackPluginBeforeHtmlProcessing.tap('AddCommonScript',htmlPluginData => {
              paths.forEach((path) => {
                  htmlPluginData.assets.js.unshift(path)
              })
          })
      })
  }
}

module.exports = AddCommonScript

多线程编译

  • 安装依赖
npm i happypack -D
  • 引入
const HappyPack = require('happypack')
const os = require('os')
const happyThreadPool = HappyPack.ThreadPool({ size: os.cpus().length });
  • 修改rules id对应插件里的id
module.exports = {
    module:{
        rules:[{
            test: /\.js$/,
            include: [
              utils.resolve("src"),
              utils.resolve("node_modules/element-ui/src"),
              utils.resolve("node_modules/element-ui/packages")
            ],
            // use: ["babel-loader"]
            use:"HappyPack/loader?id=js"
          },
          {
            test: /\.vue$/,
            include: [
              utils.resolve("src"),
              utils.resolve("node_modules/element-ui/src"),
              utils.resolve("node_modules/element-ui/packages")
              //utils.resolve('node_modules/element-ui/packages/date-picker/src/basic')
            ],
            use:'HappyPack/loader?id=vue'
            // loader: "vue-loader",
            // options: vueLoaderConfig
          }
        ],
        plugins:[
            new HappyPack({
                id:'js',
                loaders:['babel-loader?cacheDirectory=true'],
                threadPool:happyThreadPool
               }),
            new HappyPack({
              id:'vue',
              loaders:[{
                loader: "vue-loader",
                options: vueLoaderConfig
              }]
            })
        ]
    }
}

编译缓存

  • 安装依赖
npm i hard-source-webpack-plugin -D
  • webpack 配置
var HardSourceWebpackPlugin = require('hard-source-webpack-plugin');
module.export = {
    plugins:[
        new HardSourceWebpackPlugin()
    ]
}

辅助功能,查看包体积,可用于分析哪些包需要外置

  • 安装依赖
npm i webpack-bundle-analyzer -D
  • webpack 配置
const BundleAnalyzerPlugin = require("webpack-bundle-analyzer").BundleAnalyzerPlugin;
module.export = {
    plugins:[
        new BundleAnalyzerPlugin()
    ]
}