zoukankan      html  css  js  c++  java
  • webpack高级概念code splitting 和 splitChunks (系列五)

    当你把所有的代码都打包到一个文件的时候,每次改一个代码都需要重新打包。且用户都要重新加载下这个js文件。但是如果你把一些公共的代码或第三方库抽离并单独打包。通过缓存加载,会加快页面的加载速度。(分割成多个文件,不必打包成一个文件,提高性能)

    1. 异步加载的代码,webpack会单独打包到一个js文件中
    2. 同步加载的代码有两种方式

    入口文件index.js

    引入的第三方库
    import _ from 'lodash'
    
    业务逻辑代码
    console.log(666)

    打包后的文件main.js

    main.js 551 KiB main [emitted] main
    可以看到,webpack将业务代码跟lodash库打包到一个main.js文件了,每次更改业务代码,就要重新被打包一次,浪费性能

    方法一:手动代码分割,不推荐

    index.js

    业务逻辑代码
    console.log(666)

    创建一个新文件lodsh.js入口, 将第三方的库单独抽离

    import _ from 'lodash'
    window._ = _

    将文件挂载到 window 对象上,这样其他地方就可以直接使用了。

    然后在webpack配置文件中的entry增加一个入口为该文件。

    module.exports = {
        entry: {
            main: './src/index.js',
         //新增一个打包的文件,lodash为打包后的文件名称 ./src/lodash.js为入口文件, 映射关系 lodash:
    './src/lodash.js' },
        output: {
         //模糊匹配entry需要打包文件名称  filename:
    '[name].js', path: path.resolve(__dirname, '../dist') }

    打包后,打包成main,js和lodash.js两个文件,html会引入这两个文件。

    当我们业务逻辑更改,webpack重新打包只需打包main.js,lodash.js会缓存在浏览器中代码分割打包,此时提高了性能

    Asset      Size  Chunks             Chunk Names
    lodash.js   551 KiB  lodash  [emitted]  lodash
      main.js  3.79 KiB    main  [emitted]  main


    方法二: webpack自动代码分割

    2.1,同步引入第三方库

    入口文件index.js

    // 同步加载lodash
    import _ from 'lodash'
    console.log(_.join(['a','b','c','***']))

    在webpack.base.js配置optimization配置参数

        optimization: {
            // 代码分割配置
            splitChunks: {
                chunks: 'all'
            }
        },
        output: {
            filename: '[name].js',
            path: path.resolve(__dirname, '../dist')
        }
    module.exports = {
        entry: {
            main: './src/index.js'
        },

    打包后的文件,webapck的optimization会自动将诸如lodash等库抽离成单独的chunk,还会将多个模块公用的模块抽离成单独的chunk,提高性能

    2.2,异步引入代码第三方库

    index.js入口文件

    function getComponent() {
        // 异步加载lodash
        return import('lodash').then(({ default: _ }) => {
            var element = document.createElement('div');
            element.innerHTML = _.join(['Dell', 'Lee'], '-');
            return element;
        })
    }
    
    getComponent().then(element => {
        document.body.appendChild(element);
    });

    不需要webpack做任何配置

    打包后文件, lodash第三方库自动打包成单独的0.js,   vue中的路由懒加载就是这样,import函数

    总结

    // 代码分割,和webpack无关
    // webpack中实现代码分割,两种方式
    // 1. 同步代码: 只需要在webpack.common.js中做optimization的配置即可
    // 2. 异步代码(import): 异步代码,无需做任何配置,会自动进行代码分割,放置到新的文件中

    splitChunks里面还可以在添加个参数cacheGroups

    optimization: {
        splitChunks: {
            chunks: 'all',
            cacheGroups: {
                  // 下面的意思是:将从node_modules中引入的模块统一打包到一个vendors.js文件中
                vendors: {
                    test: /[\/]node_modules[\/]/,
                    priority: -10,
                    filename: 'vendors.js'
                },
                default: false
            }
        }
    }

     index.js入口文件

    同步加载lodash
    import _ from 'lodash'
    console.log(_.join(['a','b','c','***']))

    打包加载后,cacheGroupsvendors配置表示将node_modules中引入的模块(所有引入的第三方库)统一打包到一个vendors.js文件中

     如果venders的 filename: 'vendors.js',属性注释掉,那么默认会把第三方库lodash统一打包到vendors~main.js文件中(main.js为第三方库引入的文件)

     

    splitChunksdefault参数:

    根据上下文来解释,如上配置了vendors,打包node_modules文件夹中的模块,

    那么default将会打包自己编写的公共方法

    添加default的配置

    optimization: {
        splitChunks: {
            chunks: 'all',
            cacheGroups: {
                  // 下面的意思是:将从node_modules中引入的模块统一打包到一个vendors.js文件中
                vendors: {
                    test: /[\/]node_modules[\/]/,
                    priority: -10,
                    filename: 'vendors.js'
                },
                // 打包除上面vendors以外的公共模块
                default: {
                    priority: -20,
                    reuseExistingChunks: true, // 如果该chunk已经被打包进其他模块了,这里就复用了,不打包进common.js了
                    filename: 'common.js'
                }
            }
        }
    }

    新增test.js

    export default {
        name: 'Dell Lee'
    }

    入口文件index.js,引入test模块

    import test from './test.js';
    console.log(test.name);

    打包后,自己编写test.js的公共模块打包成common.js文件

    splitChunks: {
      chunk: 'all', // all(全部), async(异步的模块),initial(同步的模块)
      minSize: 3000, // 表示文件大于3000k的时候才对他进行打包
      maxSize: 0,
      minChunks: 1, // 当某个模块满足minChunks引用次数时,才会被打包。例如,lodash只被一个文件import,那么lodash就不会被code splitting,lodash将会被打包进 被引入的那个文件中。如果满足minChunks引用次数,lodash会被单独抽离出来,打出一个chunk。
      maxAsyncRequests: 5, // 在打包某个模块的时候,最多分成5个chunk,多余的会合到最后一个chunk中。这里分析下这个属性过大过小带来的问题。当设置的过大时,模块被拆的太细,造成并发请求太多。影响性能。当设置过小时,比如1,公共模块无法被抽离成公共的chunk。每个打包出来的模块都会有公共chunk
      automaticNameDelimiter: '~', // 当vendors或者default中的filename不填时,打包出来的文件名就会带~
      name: true,
      cashGroups: {} // 如上
    }

    注意;chunk:'all' 默认等于下面一大窜的配置,我们一般默认all即可就行了

        optimization: {
            // 代码分割配置
            splitChunks: {
                chunks: 'all'
            }
        },
        optimization: {
         splitChunks: {
          chunks: 'all',
          minSize: 30000,
          minChunks: 1,
          maxAsyncRequests: 5,
          maxInitialRequests: 3,
          automaticNameDelimiter: '~',
          name: true,
          cacheGroups: {
            vendors: {
              test: /[\/]node_modules[\/]/,
              priority: -10,
              // filename: 'vendors.js',
            },
            default: {
              priority: -20,
              reuseExistingChunk: true,
              filename: 'common.js'
            }
          }
        }
        },
  • 相关阅读:
    CaseStudy(showcase)布局篇列表的排放与遮罩
    CaseStudy(showcase)布局篇全屏效果
    Css 学习
    JavaScript 学习之 修改对象创建新方法
    等额本息java实现
    纠结了一天的JAVA简单客户端服务器Socket编程终于解决了
    rhostudio备忘
    sql server学习
    enumeration学习
    cookie和session
  • 原文地址:https://www.cnblogs.com/fsg6/p/14490618.html
Copyright © 2011-2022 走看看