zoukankan      html  css  js  c++  java
  • 提升webpack构建速度(二)

    分离基础脚本

    一、 使用DllPluginDllReferencePlugin,将不会经常更新的模块提前进行构建(有更新的话再构建一次),每次构建只是针对于变化的模块。总构建时间理论上会减少(视情况而定)。。。

    项目结构:

    首先在build文件夹下新增webpack.dll.conf.js文件:使用DllPlugin

    const webpack = require("webpack")
    const path = require('path')
    const os = require('os')
    const {CleanWebpackPlugin} = require('clean-webpack-plugin')
    const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
    const resolve = (dir) => path.join(__dirname, '..', dir);
    
    const env = process.env.NODE_ENV === 'testing'
      ? require('../config/test.env')
      : require('../config/prod.env')
    
    module.exports = {
      entry: {
        vendor: ['v-viewer', 'vuescroll', 'vue-i18n', 'bignumber.js'] // 这4个模块不经常更新
      },
      output: {
        path: resolve('dll_static'),
        library: '_dll_[name]_[hash]',
        filename: '_dll_[name]_[hash].js'
      },
      plugins: [
        // 去除开发环境提醒:You are running Vue in development mode.
        new webpack.DefinePlugin({
          'process.env': env
        }),
        new CleanWebpackPlugin(),
        new webpack.DllPlugin({
          name: '_dll_[name]_[hash]', //和output.library中一致,值就是输出的manifest.json中的 name值
          path: path.join(__dirname, '../dll_static', '[name].manifest.json')
        }),
        new UglifyJsPlugin({
          uglifyOptions: {
            compress: {
              warnings: true,
              drop_debugger: true,
              drop_console: true
            }
          },
          sourceMap: false,
          parallel: os.cpus().length - 1
        }),
      ]
    }
    

    webpack.base.conf.js文件中加入:使用DllReferencePlugin

    plugins: [
        // 引用动态链接库
        new webpack.DllReferencePlugin({
          manifest: path.resolve(__dirname, '../dll_static/vendor.manifest.json')
        }),
      ]
    

    package.json文件scripts中新增一项 "build:dll": "webpack --config build/webpack.dll.conf.js"

    在项目根目录下运行 npm run build:dll 后,会生成dll_static文件夹:包括所有模块(js)和映射关系文件(json),如项目结构图中的dll_static。由于这些dll.js没有包含在bundle.js中,我们在入口文件中直接用是会报错的,我们需要将dll.js插入到index.html文件中去(注:需要在bundle.js之前)

    • 在构建完成后,手动将dll.js写入index.html文件中去
    • 使用add-asset-html-webpack-plugin插件
    • 修改index.html入口文件(使用htmlWebpackPlugin.options

    add-asset-html-webpack-plugin

    // 文件动态添加到html中
    new AddAssetHtmlPlugin([
          {
            filepath: path.resolve(__dirname, '../dll_static/*.js'),
            outputPath: 'dll_static',
            publicPath: 'dll_static',
            includeSourcemap: false,
            hash: true,
          }
    ]),
    
    // 结果如下
    <script type=text/javascript src=./static/js/manifest.a41c74cbe64915cdf684.js></script>
    <script type=text/javascript src=./static/js/vendor.7a69e6c902f4c682ee3e.js></script>
    <script type=text/javascript src=./static/js/app.65ee13921c33c87b3f8d.js></script>
    <script src=static/dll_static/_dll_vendor_9f972cb316fca89ce8c5.js?=9f972cb316fca89ce8c5></script>
    

    这个插件老是将代码插入到body最底部,导致上述模块undefined。网上说可以,我目前是没成功。。。

    利用htmlWebpackPlugin.options

    webpack.base.conf.jswebpack.prod.conf.js文件中加入:

    // 注:①
    new CopyWebpackPlugin([
          {
            from: path.resolve(__dirname, '../dll_static'),
            to: config.dev.assetsSubDirectory + '/dll_static',
            ignore: ['**/*.json'] // 不复制json文件
          }
    ])
    
    new HtmlWebpackPlugin({
          // dll存着dll.js的引用地址
          dll: (function () {
                  let name = require(path.resolve(__dirname, `../dll_static/vendor.manifest.json`)).name
    
                  return `static/dll_static/${name}.js`
          })()
    })
    

    html-webpack-plugin的入口文件index.html文件中写入: <script src="<%= htmlWebpackPlugin.options.dll %>"></script>,最终效果:

    <script src=static/dll_static/_dll_vendor_9f972cb316fca89ce8c5.js></script>
    

    ①:我们上文提到的理论构建时间较少,才用DllPlugin时候比全量编译构建时间只少了2s-3s左右,原因分析:虽然我们每次不构建dll.js,但是每次构建的时候我们需要复制dll.js到指定目录(dev为以项目根目录起的内存文件系统,dev为硬盘文件系统),我开发用的电脑系统是windows 10,经常性的磁盘占用率100%(机械硬盘),感觉复制dll.js文件占用了好多时间。。。(全量编译时间 - 复制时间 = 2s-3s),其实没减少多少,如果换成ssd的话应该效果会提升。

    二、 externals,使用外部脚本引入方式,需修改index.html入口文件

    修改webpack.base.conf.js文件

    module.exports = {
          externals: {
              "BMap": "BMap",
              'vue': 'Vue',
              'vue-router': 'VueRouter',
              'vuex': 'Vuex',
              'axios':'axios',
              'element-ui': 'ElementUI',
              'echarts': 'echarts'
         },    
    }
    

    index.html文件中引入

    // 以cdn引入vue为例
    <script src="https://cdn.jsdelivr.net/npm/vue"></script>
    

    总结

    其实上边提到的两种方法的思路都是将公共依赖剥离出来,减少webpack构建的文件数量

    参考

    Webpack DllPlugin 让构建速度柔顺丝滑
    webpack构建速度优化

  • 相关阅读:
    django笔记
    pandas dataframe的合并(append, merge, concat)
    pandas删除行删除列,增加行增加列
    github上值得关注的前端项目
    CSS布局奇淫技巧之--各种居中
    级联菜单
    鼠标移入移出改变透明度
    图片轮播特效
    图片放大镜效果
    css3多列布局
  • 原文地址:https://www.cnblogs.com/hanshuai/p/13523188.html
Copyright © 2011-2022 走看看