美文网首页
日更挑战-Webpack打包拆包流程

日更挑战-Webpack打包拆包流程

作者: 愿你我皆是黑马 | 来源:发表于2021-05-31 21:23 被阅读0次

越不懂的越爱装
大家都同等:IT世界没有难不难,只有是否了解过

挑战目录

什么是Webpack

是一个将各种资源(包括浏览器不能直接识别的),打包成浏览器能识别的模块化打包工具。


如何打包

  1. 从配置文件和命令行中合并参数
  2. 用上面的参数创建Compiler对象,加载所有配置的插件
  3. 执行Compiler的run方法开始构建
  4. 通过配置文件配置的入口文件,串行开始,递归搜索所有依赖的文件(一切文件都看做模块)。
  5. 每找到一种后缀的文件时,将文件传入通过rules配置的loader处理后生成处理过的数据。
  6. 根据上述处理出的文件数据,和依赖关系。组装成一个个chunk,然后将chunk转成一个个文件。加入到输出列表
  7. 根据配置将文件输出到输出目录
  8. 在上述过程中广播各种事件通知响应的插件进行处理。获得最终的处理文件。

什么是 module、chunk和bundle

  • module:指要处理的原始文件
    1. 所有文件都被视为模块,简单来说就是你通过import语句引入的代码
  • chunk:指文件数据
    1. chunk对应module,可能是一对多也可能是一对一。

    2. webpack根据功能拆分出来的。
      拆分依据主要有以下三种:

      1. 项目入口(entry)
          入口会拆成一个chunk,多个项目入口会拆分成多个不同的chunk
      2. 通过import()动态引入的代码
          例如路由里组件的动态载入,导致每个路由界面都会拆成一个chunk
      3. 通过splitChunks拆分代码
          看下面"通过splitChunks拆分代码"的具体介绍
      
  • bundle:指文件,
    1. 一般和chunk是一对一的关系
    2. 对chunk进行编译压缩打包等处理之后的产出

通过splitChunks拆分代码

  • splitChunks默认配置(webpack4什么都不做时)

    splitChunks配置项都是作用于cacheGroup上的

    module.exports = {
      //...
      optimization: {
        splitChunks: {
          chunks: 'async',
          minSize: 30000,
          minChunks: 1,
          maxAsyncRequests: 5,
          maxInitialRequests: 3,
          automaticNameDelimiter: '~',
          name: true,
          cacheGroups: {
            vendors: {
              test: /[\\/]node_modules[\\/]/,
              priority: -10
            },
            default: {
              minChunks: 2,
              priority: -20,
              reuseExistingChunk: true
            }
          }
        }
      }
    };
    
    1. chunks 拆分模块的范围(async、initial和all),没有单独拆分出来的放到cacheGroups配置的chunk里面

      async:只从异步加载得模块(动态加载import())里拆分新的chunk

      initial:只从入口模块进行拆分新的chunk

      all:以上两者都包括

    2. cacheGroups 配置其他的模块组合起来的大类(将多个模块组成一个大的chunk)

    3. maxInitialRequests 一个入口最多拆分出来的chunk个数,超过这个就不会再单独拆分出来chunk

      • 入口文件算一个
      • 动态加载的模块不算
      • runtimeChunk拆分出的runtime不算
      • 只算js文件
      • 在maxInitialRequests临界点时: 更大的模块会被拆分优先
    4. maxAsyncRequests 动态加载的模块,导入操作时连带的最多chunk个数

      • import()文件本身算一个
      • 不算js以外的公共资源请求
      • 在maxAsyncRequests临界点时: 更大的模块会被拆分优先
    5. minChunks、maxAsyncRequests、maxInitialRequests的值必须设置为大于等于1的数

    6. 当chunk没有名字时,通过splitChunks分出的模块的名字用id替代,当然你也可以通过name属性自定义

    7. 当父chunk和子chunk同时引入相同的module时,并不会将其分割出来而是删除掉子chunk里面共同的module,保留父chunk的module,这个是因为 optimization.removeAvaliableModules 默认是true

    8. 当两个cacheGroup.priority相同时,先定义的会先命中

    9. 除了js,splitChunks也适用于css

  • splitChunks配置大全:
    pass


如何优化输出结果,提高构建速度

  1. UglifyJSPlugin优化项

    • 压缩js,删除日志和debugger,使用uglifyjs插件压缩js代码
    • 使用多进程并行运行来提高构建速度
    • 启用文件缓存来提高构建速度
    configureWebpack: config => {
     if (process.env.NODE_ENV === "production") {
       const plugins = [];
       plugins.push(
         new UglifyJSPlugin({
           uglifyOptions: {
             //删除注释
             output: {comments: false},
             //删除console 和 debugger  删除警告
             compress: {
               warnings: false,
               drop_debugger: true,
               drop_console: true
             }
           },
           cache: true, // 启用文件缓存
           parallel: true // 使用多进程并行运行来提高构建速度
         })
       );
       config.plugins = [...config.plugins, ...plugins];
     }
     },
    
  2. 提取公共代码:

    • 抽取公共模块(文件)代码
    • 抽取公共依赖(第三方模块)
    1. 通过前面的splitChunks配置
    2. 通过commons-chunk-plugin插件
    3. 通过externals配置来提取常用库
    
  3. 压缩css:使用cssnano插件压缩css代码

    • 在配置loader是追加参数css-loader?minimize
  4. cdn加速:

    • 将引用的静态文件设置为cdn上的路径
  5. 删除死代码:在启动webpack时追加参数

    • 启动webpack时追加参数--optimize-minimize,自动识别不会走到的代码并删除。
  6. 预编译资源模块:

    • 通过 DllPlugin对不会修改的npm包来进行预编译
    • 通过DllReferencePlugin将预编译的模块加载进来
  7. 多线程加载编译:使用happypack

  8. 提高uglify的速度:使用webpack-uglify-parllel多核并行压缩

  9. 剔除多余代码:使用tree shocking和scope

  10. 剔除组件库中的多余组件:使用官方的插件


什么是loader

  • 加载器:加载和解析非js文件的能力。

  • 自定义loader:满足以下规则的,则认为是一个loader

    在模块的入口js文件中,导出一个


什么是plugin

扩展功能:或者webpack的功能。要知道这里的作用需要发挥想象力。


常用的loader

  • file-loader
  • url-loader:可以在文件很小的时候,通过转成base64进行加速
  • source-map-loader:生成额外的source-map文件,方便浏览器调试。
  • img-loader:
  • eslint-loader:通过eslint检测代码。

常用的plugin

  • define-plugin:定义环境变量
  • commons-chunk-plugin:提取公共代码
  • uglifyjs-webpack-plugin:压缩(丑化)js代码

相关文章

网友评论

      本文标题:日更挑战-Webpack打包拆包流程

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