学到了!Webpack5 新特性之增量编译

news/2024/7/19 13:36:01 标签: python, js, java, redis, 编程语言
js_content">

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

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

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

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

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


每当有文件内容更新的时候,会重新递归生成依赖图,如果简单粗暴地重建依赖图再编译,会有很大的性能开销。在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做下对比

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

配置环境 - 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 缓存文件

v5首次编译

v5 无修改2次编译

直接读取缓存

v5修改后编译

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

v4 首次编译

v4 无修改2次编译

全量编译

v4 修改后编译

全量编译

总结

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

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

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

今日一提就到这里,希望对你点帮助。

Webpack V5还有非常多的特性,比如长期缓存、更智能的tree shaking、模块联邦 等,一起来探索吧。

最后

如果你觉得这篇内容对你挺有启发,我想邀请你帮我三个小忙:

  1. 点个「在看」,让更多的人也能看到这篇内容(喜欢不点在看,都是耍流氓 -_-)

  2. 欢迎加我微信「qianyu443033099」拉你进技术群,长期交流学习...

  3. 关注公众号「前端下午茶」,持续为你推送精选好文,也可以加我为好友,随时聊骚。

点个在看支持我吧,转发就更好了


http://www.niftyadmin.cn/n/717346.html

相关文章

Delphi调用REST

Delphi调用REST很简单,首先在界面上放上: RESTClient1: TRESTClient; RESTRequest1: TRESTRequest; RESTResponse1: TRESTResponse; 然后简单调用即可: RESTClient1.BaseURL:edtURL.Text; RESTRequest1.Execute; memLog.Text:RESTResponse1.C…

接口隔离原则(Interface Segregation Principle

接口隔离原则指出: CLIENTS SHOULD NOT BE FORCED TO DEPEND UPON INTERFACES THAT THEY DO NOT USE. 首先介绍接口污染。 一个没有经验的设计师往往想节省接口的数目, 将一些功能相近或功能相关的接口合并, 并将这看成是代码优化的一部分。…

js 人民币小写金额转换为大写

function smalltoBIG(n) {var fraction [角, 分];var digit [零, 壹, 贰, 叁, 肆, 伍, 陆, 柒, 捌, 玖];var unit [[元, 万, 亿],[, 拾, 佰, 仟]];var head n < 0 ? 欠 : ;n Math.abs(n);var s ;for (var i 0; i < fraction.length; i) {s (digit[Math.floor(n …

有关SD卡接线的探索(为什么标准SD卡是九根线,而一般原理图上都是11根线或更多呢?)

首先说几个概念&#xff1a; SD卡&#xff1a;<2GB SDHC卡&#xff08;SD High Capacity&#xff0c;大容量SD卡&#xff09;&#xff1a;4GB~32GB SDXC卡&#xff08;SD eXtended Capacity&#xff09;&#xff1a;64GB~2TB&#xff0c;这是2009年SD协会发布的新标准 S…

开发中经常遇到的JavaScript问题整理(超实用)

作者 chengyuming 原文地址&#xff1a;https://chengyuming.cn/views/basis/issue.html获取一个月有多少天今天遇到一个需求&#xff0c;已知月份&#xff0c;得到这个月的第一天和最后一天作为查询条件查范围内的数据new Date(year, month, date, hrs, min, sec)&#xff0c;…

CSS中的滑动门技术

原文作者&#xff1a;Douglas Bowman 原文出自&#xff1a;A List Apart 中文翻译&#xff1a;54player.comnobita 版权说明&#xff1a;本文中文翻译版权归译者54player.comnobita所有。需要转载发表的&#xff0c;请先与作者联系在CSS中&#xff0c;一个经常被人们讨论的先进…

protel或Altium Designer中各种栅格(grid)的意义

Snap Grid:捕获栅格。指光标移动的最小间隔。 Component Grid:元件放置捕获栅格。指放置元件时&#xff0c;元件移动的间隔。 Electrical Grid:电气栅格。电气栅格的作用是在移动或放置元件时&#xff0c;当元件与周围电气实体的距离在电气栅格的设置范围内时&#xff0c;元件…

面向对象JavaScript入门——来自Mozilla的官网教程

来源&#xff1a;http://www.ituring.com.cn/article/1324 尽管面向对象JavaScript与其他语言相比之下存在差异&#xff0c;并由此引发了一些争论&#xff0c;但毋庸置疑&#xff0c;JavaScript具有强大的面向对象编程能力。本文先从介绍面向对象编程开始&#xff0c;然后回顾J…