• Welcome to the world's largest Chinese hacker forum

    Welcome to the world's largest Chinese hacker forum, our forum registration is open! You can now register for technical communication with us, this is a free and open to the world of the BBS, we founded the purpose for the study of network security, please don't release business of black/grey, or on the BBS posts, to seek help hacker if violations, we will permanently frozen your IP and account, thank you for your cooperation. Hacker attack and defense cracking or network Security

    business please click here: Creation Security  From CNHACKTEAM

Recommended Posts

什么是代码分离

代码拆分是webpack的一个非常重要的特性。

他的主要目的是将代码分成不同的包,然后我们可以按需或并行加载这些文件。

例如,默认情况下,所有JS代码(业务代码、第三方依赖项、显示未使用的模块)都加载在主页上。

会影响主页的加载速度。

代码分离可以分离较小的包,控制资源加载优先级,并提高代码加载性能。

webpack中通常使用三种代码分离

起点:使用entry来配置手动代码分离

防止重复:使用条目依赖或SplitChunksPlugin来复制和分离代码。

动态导入:代码由模块的内联函数调用分隔。

Entry Dependencies(入口依赖)

输入手动分离代码

条目: {

main: '。/src/main.js ',

索引:/src/index.js ',

},

输出: {

path: resolveApp('。/build’),

filename: '[name].bundle.js ',

},

但是这样会有缺点。

比如我在main.js中引入了lodash库,在index.js中引入了lodash库,所以webpack在打包的index.js中有一个lodash,在main.js中有一个lodash,相当于生成了两个lodash。

我们不想在打包后引用第三方依赖项的每个js文件中打包第三方依赖项。这时候就需要把第三方代码分开。

条目: {

//也可以写成数组

main: { import: '。/src/main.js ',dependOn: 'lodash' },

index: { import: '。/src/index.js ',dependOn: 'lodash' },

洛达什: '洛达什':

},

此时lodash会生成一个单独的js文件,webpack通过模块化加载lodash。

如果我在主文件和索引文件中引入dayjs的第三方库时需要分离dayjs,该如何设置?

我们可以这样设置:

条目: {

main: { import: '。/src/main.js ',dependOn: ['lodash ',' dayjs'] },

index: { import: '。/src/index.js ',dependOn: ['lodash ',' dayjs'] },

洛达什: '洛达什':

dayjs: 'dayjs ',

},

也可以这样设置:

条目: {

//如果它们的两个依赖库相同,可以添加一个共享属性。

main: { import: '。/src/main.js ',dependOn: 'shared' },

index: { import: '。/src/index.js ',dependOn: 'shared' },

shared: ['lodash ',' dayjs'],

},

当我们构建的时候,会为我们生成一个LICENSE.txt文件,那么我们如何摆脱它呢?

const terser plugin=require(' terser-web pack-plugin ');

//和条目是同级。

优化: {

minimizer: [

新的TerserPlugin({

extractComments: false,

}),

],

},

Split Chunks

它是使用SplitChunksPlugin实现的。

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

您只需要提供与SplitChunksPlugin相关的配置信息。

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

例如,在默认配置中,块仅用于异步请求,异步我们可以将它们设置为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)
Link to comment
Share on other sites