webpack学习笔记-webpack多入口打包以及优化 - code split

522 阅读3分钟

Code Split

打包代码时会将所有的js打包到一个文件夹中,代码体积太大,如果我们只要渲染首页,就应该只加载首页的js代码,其它文件不加载。

所以我们需要将打包生成的文件进行代码分割,生成多个js文件,渲染哪个页面的js文件,就只加载某个js文件,这样加载的文件就少,速度更快。

代码分割(code split)主要做两件事

  • 分割文件:将打包生成的文件进行分割,生成多个js文件
  • 按需加载:需要哪个文件就加载那个文件

怎么使用呢?

1. 多文件打包入口

const path = require('path')
const HtmlwebpackPlugin = require("html-webpack-plugin")
module.exports = {
  entry:{
    //有多个入口文件,entry为对象模式
    main: './src/main.js',
    app: './src/app.js'
  },
  output:{
    path: path.resolve(__dirname, 'dist')
    filename: '[name].js'// webpack命名方式,[name]为文件自己命名: main、app
  },
  plugins:[
    new HtmlwebpackPlugin({
      template: path.resolve(__dirname, "./public/index.html")
    })
  ],
  mode: 'production'
}

image.png

多个打包入口就有多个输出

2. 提取公共模块

如果多个入口使用了同一份代码,我们可以把这一份代码单独提取打包。

我们需要使用到 cplitChunks 配置 参考地址

module.exports = {
  //...
  optimization: {
    splitChunks: {
      chunks: 'async',//三选一:"initial" 初始化,"all"(默认就是all),"async"(动态加载)
      minSize: 20000,//当导入的模块最小是多少字节才会进行代码分割 也就是说chunk体积大于20kb才会拆分。
      minRemainingSize: 0,// 类似于minSize,最后确保提取的文件大小不能为0
      minChunks: 1,//当一个模块被导入(引用)至少多少次才对该模块进行代码分割
      maxAsyncRequests: 30,//按需加载时的最大并行请求数
      maxInitialRequests: 30,//入口点的最大并行请求数
      enforceSizeThreshold: 50000,//超过50kb一定会单独打包(会忽略minRemainingSize,maxAsyncRequests,maxInitialRequests)
      cacheGroups: {//缓存组,这里是我们表演的舞台,抽取公共模块什么的,都在这个地方
        defaultVendors: {
          test: /[\\/]node_modules[\\/]/,
          priority: -10,//优先级
          reuseExistingChunk: true,
        },
        default: {
          minChunks: 2,
          priority: -20,
          reuseExistingChunk: true,reuseExistingChunk: true, //当已经存在分割时,使用已经存在且分割好的模块
        },
      },
    },
  },
};

字段解析

  • chunks

all模式下,包括所有类型的chunks都进行分割 initial: 会将入口文件中的依赖包重新切割为一个新的文件,其他文件中动态引入的不会进行拆分,和async优点相反。

  • cacheGroups

缓存组,这里配置抽取模块

  1. priority: 优先级,决定执行的顺序
  2. minSize: 最小大小, 当抽取的公共模块大于minSize所设置的值才起作用
  3. minChunk: 最小块, 当块的数量大于等于minChunks时,才起作用
  4. maxSize: 如果引入的包已经超过了设置的最大值,那么webpack会尝试对该包再进行分割

3. 按需加载动态导入

想要实现按需加载,动态导入模块, 需要使用导入语法 import()

  • main.js

document.getElementById('btn').onclick = function () {
  import ('./count.js')
  .then(res => {
    res.default(4, 1)
  })
}
  • public/index.html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <button id="btn">按钮</button>
  </body>
</html>