美文网首页
webpack code spliting 代码分割

webpack code spliting 代码分割

作者: 弹力盒 | 来源:发表于2021-07-21 09:35 被阅读0次

1、目的

避免打包生成一个大文件,致力于将打包文件拆分成适当个数的小文件

2、方法一、webpack 配置多入口模式

该方法需要将 webpack 设置成多入口模式,具体步骤如下,以 lodash.js 引用模块假设为大文件引用模块

  • a、新建一个 loadsh.js 文件用于将 lodash 绑定到全局对象 window 中
import _ from 'lodash'

// 将 lodash 绑定到全局对象 window 中,供全局使用
window._ = _
  • b、在 webpack 的 entry/output 配置像新加一个 lodash.js 的入口
entry: {
  // 要在 main 入口之前,先将 lodash 绑定到 window 中
  lodash: path.resolve(__dirname, '../src/lodash.js'),
  main: path.resolve(__dirname, '../src/main.js')
},
output: {
  /**
   * 打包文件的名称,[name] 对应的是 entry 对象中的 key 值
   * 多入口时必须为 [name]
   */
  filename: '[name].js',
  // 打包文件的路径
  path: path.resolve(__dirname, '../dist')
}

以上配置最终会将原本打包一个 main.js 拆分成了 main.js 和 lodash.js,将打包后的大文件拆分成了小文件

  • c、在 main.js 项目入口文件中直接使用 lodash 的 join 功能,可以运行正常
/**
 * 因为有 loadsh.js 先引入了 lodash 依赖,并绑定到 window 对象
 * 因此这里可以这么用,能够正常输出
 */

console.log(_.join(['a', 'b', 'c']))

在实际开发,不修改 lodash.js 文件时,项目业务代码发生改变不会重新加载 lodash.js 文件,只会重新加载发生改变的文件

3、方法二、webpack 配置 optimization 配置项

  • a、配置 optimization 的 splitChunks 选项
module.exports = {
  optimization: {
    /**
     * 开启代码分割功能
     * webpack 会自动识别是否为第三方依赖
     * 将第三方依赖打包到 vendors~main.js 中(名字不固定)
     */
    splitChunks: {
      /**
       * chunks 表示webpack打包时支持的类型,默认值为 async
       * all 时表示支持所有类型
       * async 支持异步类型
       * initial 支持同步类型
       */
      chunks: 'async',
      /**
       * cacheGroups 是同步代码分割才会起作用的
       */
      cacheGroups: {
        // vendors 为 false 时,打包的第三方文件将不会以 vendors 开头命名
        // vendors: false,
        /**
         * webpack 判断当前要打包的第三方文件通过 chunks 类型后
         * 继续判断是否符合 test 的校验
     * 是的话即将该文件打包成一个 vendors 开头的文件
         * 既满足 vendors 的模块,被打包时也一定满足 default 的
     * 因为所有的打包模块都会满足 default
         * 因此需要有一个 priority 优先级来区分到底要将模块打包到那个文件中
         */
        vendors: {
      // 不再这个位置的会走 default 配置项
          test: /[\\/]node_modules[\\/]/,
          // 优先级,越大表示打包时就存放到对应的文件中
          priority: -10,
          // 统一打包到 vendors.js 中
          filename: 'vendors.js'
        },
        /**
         * 当前打包模块不符合 vendors 配置项时,便会走到 default 配置项来
         * default 为 false 时是不会进行代码分割的
     * 只有当default 设置了某些配置项时
         * 同步代码分割才会生效
         */
        default: {
          priority: -20,
          /**
           * 如果当前打包模块被打包过了,那么将不会在对该模块继续打包
           * 而是使用之前打包好的
           */
          reuseExistingChunk: true,
          // 统一打包到 common.js 中
          filename: 'common.js'
        }
      },
      // 当前要打包的模块最小需要的文件大小
      minSize: 0,
      // 当前打包的文件最少被引用 n 次时,才会开始代码分割打包处理
      minChunks: 1
    }
  }
}
  • b、打包后自动将第三方依赖生成到一个文件中


    image.png

4、方法三、import 异步加载 lodash.js 文件

  • a、安装 @babel/plugin-syntax-dynamic-import 依赖,支持babel 识别 import 的异步加载代码
cnpm i @babel/plugin-syntax-dynamic-import -D
  • b、配置 .babelrc 文件
{
  "plugins": [
    // 允许 babel 去翻译 import 异步加载文件
    "@babel/plugin-syntax-dynamic-import"
  ]
}
  • c、入口文件执行异步加载 lodash.js 代码
// 异步加载 lodash.js

function getComponent () {
  return import(/* webpackChunkName: "lodash" */ 'lodash').then((_) => {
    const element = document.createElement('div')
    element.innerHTML = _.join(['tang', 'li', 'he'], '-');
    return element
  })
}

setTimeout(() => {
  getComponent()
    .then((element) => {
      document.body.appendChild(element)
    })
}, 1000)

最终打包文件如下图


image.png

相关文章

网友评论

      本文标题:webpack code spliting 代码分割

      本文链接:https://www.haomeiwen.com/subject/roxypltx.html