ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

18_webpack代码分离

2022-05-03 01:03:54  阅读:216  来源: 互联网

标签:lodash 18 代码 js webpack import main


什么是代码分离

代码分离(Code Splitting)是webpack一个非常重要的特性

他主要的目的是将代码分离到不同的bundle中,之后我们可以按需加载,或者并行加载这些文件

比如默认情况下,所有的JS代码(业务代码,第三方依赖,展示没有用到的模块)在首页全部都加载
就会影响首页的加载速度

代码分离可以分出更小的bundle,以及控制资源加载优先级,提供代码的加载性能

webpack中常用的代码分离有三种
  入口起点:使用entry配置手动代码分离
  防止重复:使用Entry Dependencies或者SplitChunksPlugin去重和分离代码
  动态导入:通过模块的内联函数调用来分离代码

 

Entry Dependencies(入口依赖)

 

入口手动分离代码

 entry: {
    main: "./src/main.js",
    index: "./src/index.js",
  },
  output: {
    path: resolveApp("./build"),
    filename: "[name].bundle.js",
  },

但是这样子会有缺点

如:我在main.js引入了lodash库,在index.js也引入了lodash这个库,那么webpack在打包后的index.js中有一份lodash,main.js中也有一份lodash,相当于生成了两份lodash

我们不想在打包后的每个引用第三方依赖的js文件中都把第三方的依赖都打包进去,这个时候我们就需要对第三方代码进行一个分离

 entry: {
                      //也可以写成一个数组 main: { import: "./src/main.js", dependOn: "lodash" }, index: { import: "./src/index.js", dependOn: "lodash" }, lodash: "lodash", },

那么这个时候,lodash就会生成一个单独的js文件,webpack会通过模块化加载lodash

假如我在main和index文件又引入了dayjs第三方库的时候,我们还需要对dayjs进行分离,那么改如何设置呢?
我们可以这样设置:

  entry: {
    main: { import: "./src/main.js", dependOn: ["lodash", "dayjs"] },
    index: { import: "./src/index.js", dependOn: ["lodash", "dayjs"] },
    lodash: "lodash",
    dayjs: "dayjs",
  },

也可以这样设置:

  entry: {
    //他们两个依赖的库是一样的话可以添加一个shared属性
    main: { import: "./src/main.js", dependOn: "shared" },
    index: { import: "./src/index.js", dependOn: "shared" },
    shared: ["lodash", "dayjs"],
  },

 

当我们build的时候会给我们生成一个LICENSE.txt文件,那么我们如何去掉呢?

const TerserPlugin = require("terser-webpack-plugin");

// 和entry同级
optimization: {
    minimizer: [
      new TerserPlugin({
        extractComments: false,
      }),
    ],
  },

 

 

Split Chunks

它是使用 SplitChunksPlugin来实现的

  因为该插件webpack已经默认安装和集成,所以我们并不需要单独安装,直接使用该插件

  只需要提供SplitChunksPlugin相关的配置信息即可

webpack提供了SplitChunksPlugin默认的配置,我们也可以手动来修改它的配置:

  比如默认配置中,chunks仅仅针对于异步(async)请求,我们可以设置为initial或者all

 

如:我们使用import语句导入的dayjs和lodash,他们相当于是同步的,所以该插件并不会对他进行任何的分离,所以我们需要修改其中的chunks值

require()和import()就是异步加载js文件所以该插件会对导入的其js代码进行分离

  optimization: {
    minimizer: [
      new TerserPlugin({
        extractComments: false,
      }),
    ],
    splitChunks: {
      // async:require,import函数
      // initial:同步导入如:import语句
      // all:异步/同步都支持
      chunks: "all",
    },
  },

你会发现在我们的build文件夹已经生成了一个叫xxx(数字).bundle.js文件,就已经对代码进行了一个分离

 

因为我们所有的分离都是使用SplitChunksPlugin来实现的,所以我们需要对它的配置有所了解

   splitChunks: {
      // async:require,import函数
      // initial:同步导入如:import语句
      // all:异步/同步都支持
      chunks: "all",
      // 最小值:默认值为:20000kb,如果我们拆分出来一个包,那么拆分出来的这个包的大小最小为minSize,如果达不到就不拆分了
      // minSize的优先级大于maxSize的优先级
      minSize: 2000,
      // 将大于maxSize的包拆分成不小于minSize的包,
      maxSize: 2000,
      // minChunks表示引入的包,至少被引入了一次
      minChunks: 1,
      // 缓存组:b把匹配的文件打包到vendors中
      // 把来自node_modules文件夹的代码(第三方库)打包到vendors中
      // 当匹配到了lodash不会立即做一个输出,先缓存,等到把所有的匹配都加载完成之后,一起用filename命名的名字一起做一个输出
      cacheGroups: {
        vendors: {
          test: /[\\/]node_modules[\\/]/,
          filename: "[id]_vendors.js",
          //优先级,如果vendors和default都满足的情况下,它会优先使用default
          priority: -20,
        },
        /* bar: {
          test: /bar_/,
          filename: "[id]_bar.js",
        }, */
        default: {
          //如果有一个文件被引用了两次,会被打包成一个单独的文件
          minChunks: 2,
          filename: "common_[id].js",
          //优先级 一般是负数
          priority: -10,
        },
      },
    },

这些配置我们一般都不需要进行配置的,使用默认的就好了。

 

动态导入(dynamic import)

另外一个代码拆分是动态导入时,webpack提供了两种实现动态导入的方式
  使用ECMAScript中的import()语法来完成,也是目前推荐的方式
  使用webpack遗留的require.ensure,目前已经不推荐使用

在vue中同步打包出来的文件最多的就4个
1.main.bundle.js
2.vendors_chunks.js
3.common_chunks.js
4.runtime.js

只要是异步导入的代码,webpack都会进行代码分离
无论你的splitChunksPlugin设置的是什么,webpack都会对异步导入的代码进行分离   当我们使用import()函数动态导入,在打包的文件夹中会生成一个[id].bundle.js
打包过后的文件名字来自于哪里呢?
  默认情况下如果你没有告诉他,打包过后的文件叫什么名字,它会根据output.filename来进行命名,但是我这里的filename设置的是 [name].bundle.js ,为什么我的name是一个数字,这个数字来自哪里,它来自optimization的属性中有一个叫chunkIds,他就来自这里  

optimization.chunkIds配置

Optimization | webpack

optimization.chunkIds配置用于告知webpack模块的id采用什么算法生成

boolean = false string: 'natural' | 'named' | 'size' | 'total-size' | 'deterministic'   natural:使用自然数,不推荐,不利于浏览器缓存,假如我对应a.js是1_vendors.js b.js是2_vendors.js,那么我把a.js删除掉了,下次再进行打包的时候,1_vendors.js对应的就是b.js了   named:使用包所在的目录作为name(开发环境推荐)   deterministic:生成id,针对相同的文件,生成的id是不变的(默认)     一般我们的异步代码不叫xxx.bundle.js,应该是xxx.cunk.js,那么该怎么设置呢?
  output: {
    path: resolveApp("./build"),
    filename: "[name].bundle.js",
    chunkFilename: "[name].chunk.js",
  },
但是我们就算设置了[name].chunk.js,那么它生成的文件还是id.chunk.js那么该怎么办呢?
我们可以使用我们的魔法注释(magic comments)

标签:lodash,18,代码,js,webpack,import,main
来源: https://www.cnblogs.com/Mr-Hou88888/p/16217467.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有