真香 - Webpack5 新特性之增量编译

简介: webpack作为最使用最广泛的前端打包工具,已经成为前端工程化基础设施的一部分。webpack5正式发布于2020年10月10号,距离上一个大版本Webpack4更新已经是2年前年了,每个大版本的升级都会有相当多的改变和提升,今天咱们就来看看增量编辑和长期缓存。

webpack作为最使用最广泛的前端打包工具,已经成为前端工程化基础设施的一部分。

webpack5正式发布于2020年10月10号,距离上一个大版本Webpack4更新已经是2年前年了,每个大版本的升级都会有相当多的改变和提升,今天咱们就来看看增量编辑和长期缓存。

增量编译(官方称作:优化持久化缓存)


Webpack5之前在构建时,会以配置的 entry 为入口,递归解析模块依赖,构建出一个依赖图(graph),该依赖图记录代码中各个 module 之间的关系。

ps: graph  是什么?图是一种数据结构,类似下面这样

ba2d6abdfa4603fc8dae6b00188ec788_640_wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1.png


每当有文件内容更新的时候,会重新递归生成依赖图,如果简单粗暴地重建依赖图再编译,会有很大的性能开销。在webpack5中,利用缓存实现增量编译,从而提升构建性能。每当代码变化、模块之间依赖关系改变导致依赖图改变时, Webpack 会读取记录做增量编译。

缓存(内存 / 磁盘两种形式)中的主要内容是 module objects,在编译的时候会将依赖图以二进制或者 json 文件存储在硬盘上。

之前持久缓存的方式


  • 使用 cache-loader 可以将编译结果写入硬盘缓存,Webpack 再次构建时如果文件没有发生变化则会直接拉取缓存。
  • 还有一部分 loader 自带缓存配置,比如 babel-loader,可以配置参数 cacheDirectory 使用缓存,将每次的编译结果写进磁盘(默认在 node_modules/.cache/babel-loader 目录)
  • terser-webpack-plugin 开启缓存

webpack5持久缓存方式


v5 中缓存默认是 memory,你可以修改设置写入硬盘:

module.export={
    cache{
       type:'filesystem',  //  'memory' | 'filesystem'
        cacheDirectory: 'node_modules/.cache/webpack', // 默认将缓存存储在 node_modules/.cache/webpack
        // 缓存依赖,当缓存依赖修改时,缓存失效
        buildDependencies:{
         // 将你的配置添加依赖,更改配置时,使得缓存失效
         config: [__filename]
     } 
    }
}

增量编译体验


下面来尝试下这个功能,并同时和webpack4做下对比

7b7e9a627c6c07e25d7c25772d0a51d9_640_wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1.png

为了能够看出对比效果,搞了一堆模块,不过代码量都很少。

配置环境 - webpack4 安装

下面使用yarn 安装,本人习惯用yarn,因为速度够快

// webpack4
 yarn add webpack@4 webpack-cli@3 babel-loader @babel/core  @babel/preset-env -D
const path=require('path'); 
module.exports={
    mode:"development",
    entry:{
        index:'./src/pages/home/index.js' //入口文件
    },
    output:{
        filename:'[name].js', 
        path:path.resolve(__dirname,'./dist') //指定生成的文件目录
    },
    // 模块
   module:{
    rules:[
      {
        test:/\.js$/,
        exclude:/node_modules/,
        use:[
          {
            loader:'babel-loader',
            options:{
              presets:[
                '@babel/preset-env',
              ]
            },
          }
        ]
      },
    ]
  },
}

配置环境 - webpack5 安装

// webpack5
 yarn add webpack webpack-cli babel-loader @babel/core  @babel/preset-env -D
const path=require('path'); 、
module.exports={
    mode:"development", 、
    entry:{
        index:'./src/pages/home/index.js' 、
    },
    output:{
        filename:'[name].js',、
        path:path.resolve(__dirname,'./dist')、
    },
    cache: {
        type: 'filesystem',//使用文件缓存
        // cacheDirectory 默认路径是 node_modules/.cache/webpack
        cacheDirectory: path.resolve(__dirname, './temp_cache') //本地目录
      },
    // 模块
   module:{
    rules:[
      {
        test:/\.js$/,
        exclude:/node_modules/,
        use:[
          {
            loader:'babel-loader',
            options:{
              presets:[
                '@babel/preset-env',
              ]
            },
          }
        ]
      },
    ]
  },
}

配置启动命令

"scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "webpack --config webpack.config.js"
  },

构建结果对比

//执行
yarn start
首次编译 v5  done in 1.5s 左右  
首次编译 v4  done in 1.05s左    
后续无修改编译:v5 done in 0.6s 左右  
后续无修改编译:v4 done in 0.9s 左右
修改后编译:v5 done in 1.5s 左右  
修改后编译:v4 done in 1.5s 左右  
但v5里多了一个时间 webpack compiled successfully time,这个在v4里默认没有显示
V5 首次编译   webpack compiled successfully in 723 ms
V5 无修改编译 webpack compiled successfully in 100 ms
V5 修改后编译 webpack compiled successfully in 417 ms
但我们应该以 done in time 作为对比

构建产物和日志

v5 缓存文件

96eec1bfbf61dcd1712afd5f0b34b032_640_wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1.png

v5首次编译

fd3e400064d72bb0b4fd6f2856888601_640_wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1.png

v5 无修改2次编译

直接读取缓存

765521862e4f6c1bee96824abfb4db01_640_wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1.png

v5修改后编译

增量编译,只编译修改的模块

11310a752262caf4a2086d7e779783d3_640_wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1.png

v4 首次编译

dda4adfc01e051fac3f93c5d8ed5195a_640_wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1.png

v4 无修改2次编译

全量编译

3376ed9d8d2bf39d101c3eb6c1deebf7_640_wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1.png

v4 修改后编译

全量编译

7086ec1852dd4cee68ff0217dbcc1294_640_wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1.png

总结


模块较少,代码量少时,增量编辑的优势并不明显,甚至首次编译的速度还会低于v4的速度,因为v5需要处理缓存。

增量编译中:v5只编译了修改的模块,而v4每次编译都是所有模块重新编译,全量执行。

代码量较少,性能提升不明显,相信在复杂庞大的项目中会有更好的效果,因为增量编译无疑会更节省cpu和内存的使用率,后面试着把老项目升级下,看看最终的一个打包速度能提升多少。

目录
相关文章
|
JavaScript
Webpack Babel (编译ES6/7)
Webpack Babel (编译ES6/7)
86 0
|
JSON 前端开发 JavaScript
Webpack5新特性:使用 Assets Module 处理图片和字体资源
本文介绍了 Webpack5 的 Assets Module ,是其内置的用来处理图片字体文件等资源模块的新功能。相比与过去通过 loader 的方式去处理,更加方便和简洁。
1353 0
|
4月前
|
前端开发 开发者
在前端开发中,webpack 作为模块打包工具,其 DefinePlugin 插件可在编译时动态定义全局变量,支持环境变量定义、配置参数动态化及条件编译等功能。
在前端开发中,webpack 作为模块打包工具,其 DefinePlugin 插件可在编译时动态定义全局变量,支持环境变量定义、配置参数动态化及条件编译等功能。本文阐述 DefinePlugin 的原理、用法及案例,包括安装配置、具体示例(如动态加载资源、配置接口地址)和注意事项,帮助开发者更好地利用此插件优化项目。
122 0
|
7月前
|
缓存 资源调度 监控
Webpack 5新特性详解与性能优化实践
Webpack 5通过确定性的Chunk ID、模块ID和导出ID实现了长期缓存,这意味着相同的输入将始终产生相同的输出。这样,当你的用户再次访问更新后的网站时,浏览器可以重用旧的缓存,而不是重新下载所有资源。
92 2
|
7月前
|
前端开发
【专栏】`webpack` 的 `DefinePlugin` 插件用于在编译时动态定义全局变量,实现环境变量差异化、配置参数动态化和条件编译
【4月更文挑战第29天】`webpack` 的 `DefinePlugin` 插件用于在编译时动态定义全局变量,实现环境变量差异化、配置参数动态化和条件编译。通过配置键值对,如 `ENV: JSON.stringify(process.env.NODE_ENV)`,可以在代码中根据环境执行相应逻辑。实际应用包括动态加载资源、动态配置接口地址和条件编译优化代码。注意变量定义的合法性和避免覆盖,解决变量未定义或值错误的问题,以提升开发效率和项目质量。
354 3
|
开发工具
(已解决)求助!!!webpack编译失败,vue___jb_tmp___ ,但是加一个回车,或者打个空格就好了..
求助!!!webpack编译失败,.vue___jb_tmp___ (Permission denied)错误解决办法
110 0
|
存储 缓存 JSON
webpack拓展篇(六十七):webpack5 新特性解析
webpack拓展篇(六十七):webpack5 新特性解析
409 0
webpack拓展篇(六十七):webpack5 新特性解析
|
前端开发
webpack学习笔记(四) 自动编译
webpack学习笔记(四) 自动编译
121 0
node编译TS时,tsconfig.json中的基础配置 与 webpack编译TS时webpack.config.js中的基础配置
node编译TS时,tsconfig.json中的基础配置 与 webpack编译TS时webpack.config.js中的基础配置