AST抽象语法树webpack逻辑解析

AST抽象语法树是什么?

树形语法结构,会对代码里的函数、变量声明、逻辑操作进行一些校验。

为什么要用AST?

手写了一段代码之后,编译器需要对不同风格的代码按照商定好的规则统一处理,处理成为规则能够顺利执行的语言,才可以发布执行。

编译逻辑:

将代码字符串解析数据单元,再解析成一段token数组,解析时比如方法里还有别的变量,逻辑等,就会形成嵌套,最终就是一个树形结构,然后再生成一个AST树,是一个JSON的数据格式,遍历AST,对内容进行一些变更,生成新的AST再根据它生成一套新的代码。

比如babel 编译一个es6的箭头函数时,会通过编译,输出为一个普通的function,转换成为兼容es6之下的语法。

编译过程总结:

    1. parsing:解析过程,词法分析、语法分析、构建AST;

        1) 词法分析:读取代码字符串,识别每一个单词及其种类,移除空格注释,按照预定规则合并成一个个的标识(token),产出一个token数组(令牌)

        2) 语法分析:读取令牌流,在语法约束下生成树形的中间表示,便于描述逻辑结构,给出了令牌流的结构表示,同时验证语法,如果有错误抛出语法错误

    2. transformation:转化过程,将上一步的解析后的内容按照编译器指定的规则进行处理,形成一个新的表现形式,即改写AST,根据当前AST生成一个新的AST,可以是相同语言或其他语言;

    3. code generation:代码生成,将上一步处理好的内容(AST)转化为新的代码

使用工具查看AST代码: astexplorer.net 网址

用一段代码逻辑表示就是:

function compiler(input){let tokens = tokenizer(input); // 生成tokens/*** 遍历代码字符,匹配到括号、字符、数字、引号等,分类push到tokens数组里 键值对push { type: 'number', value: '123' }*/let ast = parser(tokens); // 生成ast/*** 遍历type === 'number'时,ast.body就push一条 NumberLiteral 类型的键值对, 如果是方法调用,就会继续遍历调用的params传入*/let newAst = transformer(ast); // 拿到新的ast/*** 核心功能,新逻辑注入,AST的转换过程*/let output = codeGenerator(nevAst); // 生成新代码return output;
}

AST在前端中的应用:

1. 代码优化 eg: 简易版esliint,禁止console

2. 代码检查 代码风格检查,安全检查

3. 代码编辑器和插件 语法高亮 代码提示

webpack篇

webpack5和webpack4的区别

1. 性能优化: Webpack 5引入了许多性能优化,包括持久性缓存、更好的树摇(Tree Shaking)和模块联邦(Module Federation)等特性,以提高构建速度和应用程序性能。

2. 持久性缓存: Webpack 5引入了持久性缓存,通过为构建生成的文件添加哈希值,可以更好地利用浏览器缓存, 从而减少用户下载更新后的代码量。减少了打包的工作量,可以在.cache里取chunk。

3. 模块联邦(Module Federation):这是Webpack 5的一个重要特性,允许多个独立的Webpack构建共享模块从而提高应用程序之间的代码共享和分发。避免重复打包,优化打包时间。

webpack5 在默认情况下,cache 属性值在开发环境中为true,等同于cache:{type:'memory'},而在生产环境下则是被禁用。

对于持久化缓存,则需要指定 cache.type 的属性值为 filesystem,开启这个配置之后,默认会在node_modules 下创建一个.cache 的目录,用来存放生成的缓存文件。

webpack 优化方向:

1. 构建时间优化

2. 打包体积优化

1. 构建时间优化

如何知道webpack编译速度?

 progress-bar-webpack-plugin: 查看编译进度; 安装插件,获取进度条

speed-measure-webpack-plugin: 查看编译速度; 安装插件,获取细粒度的时间

webpack-bundle-analyzer: 打包体积分析(这个插件需要跑起来项目,看到各个部分占据的体积,将较大占用的功能按需引用,可减小体积。)

 npm run eject 可以拿到所有的webpack配置,包含默认配置,安装插件之后,在webpack.config.js中引用,按照文档说明使用插件,在下次build时就能在控制台看到对应的编译数据,这样就可以在优化时有一个比较明确的针对方向。
 

  1) sourceMap 优化

   sourceMap 是将编译后的代码映射回开发时的代码的工具,根据map文件里的变量映射。

   在devtool 的地方修改,可以改变编译map方式。

   关键字: eval、inline、hidden、nosources、cheap

      [inline- | hidden- | eval-][nosources-][cheap-[module-]]source-map

      其中:

      inline- | hidden- | eval- : 三个值时三选一

      cheap 可选值,并且可以跟随 module的值;

      nosources: 可选值。

      常用配置推荐

        开发环境推荐使用

        1. eval-cheap-source-map

        2. eval-cheap-module-source-map

        生产环境推荐使用

        1. hidden-source-map

        2. nosources-source-map

  2) watch 优化

      1. 忽略不必要的文件

        可以通过配置watchOptions中的ignore选项,忽略不必要监视的文件或目录,这样可以避免监听一些不相关的文件,减少不必要的构建触发,从而提高性能。

      2. 增加检查延迟

        默认情况下,webpack会立即响应文件的变化并触发重新构建。通过调整watchOptions中的aggregateTimeout选项,增加检查的延迟时间,以减少频繁的构建触发,这样可以在一段时间内收集文件变化,然后一次性触发构建,避免过于频繁的构建。

      3. 使用增量编程

        webpack5中引入了增量编译功能,它只会重新编译发生变化的模块及其依赖,而不是整个项目,这样可以提高构建的速度,特别是在大型项目中。

 3) 缩小loader范围

      配置include、exclude,缩小loader对文件的搜索范围。

      比如配置解析范围在 src目录下的 ts、tsx、js、jsx文件,不包含node_modules

  4) 后缀配置的调整

      按照tsx、ts、jsx、js的顺序匹配,若没匹配到则报错

  5) 并行构建

      将thread-loader放在构建耗时较大的loader之前,会开启多进程进行打包,如果是轻量的loader,有可能会加重负担。

2. 打包体积的优化
  1) 代码分割

      把不变的第三方库、一些公共模块 比如 util.js 这些单独拆成一个chunk,在访问页面的时候就可以一直使用浏览器中缓存的资源。

  2) tree-shaking

      webpack5 默认开启tree-shaking

  3) 图片质量压缩

      image-webpack-loader 使用 type: 'asset' 选项可以将图片文件或其他资源文件类型视为Asset Module类型,这个类型是webpack5引入的新特性,允许将资源文件直接作为模块导入到代码中,无需手动配置额外的loader。

webpack打包流程?

  1. 初始化: 启动构建,读取与合并配置参数,加载Plugin,实例化Compiler

  2. 编译: 从 entry出发,针对每个 Module 串行调用对应的 loader 去翻译文件的内容,再找到该 Module 依赖的Module,递归地进行编译处理

  3. 输出:将编译后的 Module 组合成 Chunk,将 Chunk 转换成文件,输出到文件系统中

tree-shaking 实现原理是怎样的?

  1. 识别依赖关系: Tree-shaking 从应用程序的入口点开始,识别所有的依赖关系,包括ES6的import 和 require 语句。

  2. 构建依赖图: 根据识别到的依赖关系,建立一个依赖图。这个图用于表示模块之间的依赖关系和引用关系。

  3. 静态分析:在 Tree-shaking 过程中,不执行实际的代码,而是进行静态分析。这意味着它在编译时期(而不是运行时期)就能够确定哪些代码被引用,哪些代码未被引用。

  4. 标记未使用代码: 通过静态分析,Tree-shaking 标记所有未被引用的代码,包括模块、函数、变量等。

  5. 移除未使用代码: 最后,标记的未使用代码将从最终的打包文件中剔除,以减小文件大小。

实现 Tree-shaking 的前提是,应用程序必须使用 ES6 模块系统,这通常意味着在开发中避免使用CommonJs 的require 语句,因为它们不具备静态特性,无法被Tree-shaking 移除。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/768684.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Window全网解析网站下载视频

全网解析网站下载视频 介绍m3u8格式cbox格式 解析视频下载的方法方法一解析视频下载视频 方法二老王浏览器下载使用浏览器解析下载视频 总结 介绍 今天分享一下如何解析网页中的视频进行下载。通常情况下我们打开的某某网站的视频是不提供下载接口的,甚至说你下载了…

[JavaEE -- 传输层中UDP和TCP的api实现原理]

传输层中UDP和TCP的api实现原理 1. UDP和TCP协议特点1.1 TCP1.2 UDP 2. UDP协议中socket api的使用2.1 服务器:2.2 客户端2.3 整个流程 3. TCP协议中的api使用3.1 TCP服务器3.2 TCP客户端3.3 整个流程 1. UDP和TCP协议特点 1.1 TCP 有连接:抽象&#x…

ClickHouse--11--物化视图

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 1.物化视图什么是物化视图? 1.1 普通视图1.2 物化视图1.3 优缺点1.4 基本语法1.5 在生产环境中创建物化视图1.6 AggregatingMergeTree 表引擎3.1 概念3.2 Aggregat…

面试算法-87-分隔链表

题目 给你一个链表的头节点 head 和一个特定值 x ,请你对链表进行分隔,使得所有 小于 x 的节点都出现在 大于或等于 x 的节点之前。 你应当 保留 两个分区中每个节点的初始相对位置。 示例 1: 输入:head [1,4,3,2,5,2], x …

【JAVA】通过JAVA实现用户界面的登录

🌈个人主页: Aileen_0v0 🔥热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法|MySQL| ​💫个人格言:“没有罗马,那就自己创造罗马~” #mermaid-svg-wyCvaz0EBNwHcwsi {font-family:"trebuchet ms",verdana,arial,sans-serif;f…

NPM 国内镜像

一、修改成腾讯云镜像源 1. 设置命令 npm config set registry http://mirrors.cloud.tencent.com/npm/ 验证命令 npm config get registry 如果返回 http://mirrors.cloud.tencent.com/npm/,说明镜像配置成功。 二、修改成淘宝镜像源 设置命令 npm config set…

Linux系统——硬件命令

目录 一.网卡带宽 1.查看网卡速率——ethtool 网卡名 2.查看mac地址——ethtool -P 网卡名 二、内存相关 1.显示系统中内存使用情况——free -h 2.显示内存模块的详细信息——dmidecode -t memory 三、CPU相关 1.查看CPU架构信息——lscpu 2.性能模式 四、其他硬件命…

C语言字节对齐关键字#pragma pack(n)的使用

0 前言 在进行嵌入式开发的过程中,我们经常会见到对齐操作。这些对齐操作有些是为了便于实现指针操作,有些是为了加速对内存的访问。因此,学习如何使用对齐关键字是对于嵌入式开发是很有必要的。 1 对齐规则 1.0 什么叫做对齐 众所周知&a…

牛客NC170 最长不含重复字符的子字符串【高频 中等 map、滑动窗口 Java,Go,PHP】

题目 题目链接: https://www.nowcoder.com/practice/48d2ff79b8564c40a50fa79f9d5fa9c7 思路 用一个hashmap记录每个字母的index如果这个字母已经在map里了说明已经有重复了这样就更新看这个字母上次出现的index需要注意的是这种情况:“bacbca”这里的a…

PCB中常用电子器件封装学习——【一网打尽】

‘ 上图是这个世界上大概所有的封装种类,当然我们日常硬件电路设计肯定用不到这么多,接下来我将介绍几种工程上常用的封装,配以图片方便大家理解学习。在电子器件选型的时候,避免选择到一些非常难以焊接的封装电子器件。

使用amd架构的计算机部署其他架构的虚拟机(如:arm)

1 下载quem模拟器 https://qemu.weilnetz.de/w64/2 QEMU UEFI固件文件下载(引导文件) 推荐使用:https://releases.linaro.org/components/kernel/uefi-linaro/latest/release/qemu64/QEMU_EFI.fd3 QEMU 安装 安装完成之后,需要将安装目录添加到环境变…

android11 系统的启动流程 的面试题目

Android 11 系统的启动流程包括哪些阶段? 答:Android 11 系统的启动流程主要包括 Boot ROM、Bootloader、Linux Kernel、Init 进程、Zygote 进程等阶段。具体流程包括硬件初始化、引导加载程序加载 Linux 内核、Linux 内核初始化、启动 Init 进程等。 B…

‘pyrcc5‘ 不是内部或外部命令,也不是可运行的程序 或批处理文件。

在初次配置启动labelImg的时候遇到些问题,特地在此记录下: 报错信息 "pyrcc5 不是内部或外部命令、可运行程序或批处理文件" 表明系统无法识别 pyrcc5 命令。pyrcc5 是 PyQt5 的一部分,用于将 .qrc 文件(资源文件&#…

Jenkins的快速入门

文章目录 一、Jenkins是什么?二、Jenkins安装和持续集成环境配置1.持续集成流程说明2.Gitlab代码托管服务器安装Gitlab简介:Gitlab安装Gitlab的使用切换中文添加组创建用户将用户添加到组创建项目idea中代码上传Gitlab 3.Jenkins持续集成环境服务器安装J…

华为北向网管NCE开发教程(5)打包org.omg.CosNotification找不到

1问题描述 在IDE中,代码能正常运行,但是打包的时候,会抱不到一些类 2问题原因 导入的本地包中,能在IDE中找到,但是在使用maven打包时,maven找不到这些依赖包 3解决办法 将依赖包通过maven安装到maven…

5.87 BCC工具之tcpsubnet.py解读

一,工具简介 tcpsubnet工具根据目标子网统计吞吐量。 这个工具只在IPv4环境下工作,并允许用户指定特定的子网进行监控。通过使用tcpsubnet,用户可以实时地观察特定子网内TCP流量的变化和分布情况,从而帮助进行网络性能调优、故障排查和安全监控等工作。 二,代码示例 #…

通过 Socket 手动实现 HTTP 协议

你好,我是 shengjk1,多年大厂经验,努力构建 通俗易懂的、好玩的编程语言教程。 欢迎关注!你会有如下收益: 了解大厂经验拥有和大厂相匹配的技术等 希望看什么,评论或者私信告诉我! 文章目录 一…

[Python人工智能] 四十四.命名实体识别 (5)利用bert4keras构建Bert-CRF实体识别模型(实体位置)

从本专栏开始,作者正式研究Python深度学习、神经网络及人工智能相关知识。前文讲解如何实现中文命名实体识别研究,构建BiGRU-CRF模型实现。这篇文章将继续以中文语料为主,介绍融合Bert的实体识别研究,使用bert4keras和kears包来构建Bert+BiLSTM-CRF模型。然而,该代码最终结…

红外遥控器的使用和详细解释

infrared.c #include "infrared.h"/* 红外 --- PA8*/void Infrared_Init(void) {GPIO_InitTypeDef GPIO_InitStruct; EXTI_InitTypeDef EXTI_InitStruct;NVIC_InitTypeDef NVIC_InitStruct;//使能SYSCFG时钟RCC_APB2PeriphClockCmd(RCC_APB2Periph_SYSCFG, E…

34.网络游戏逆向分析与漏洞攻防-游戏网络通信数据解析-登录数据包的监视与模拟

免责声明:内容仅供学习参考,请合法利用知识,禁止进行违法犯罪活动! 如果看不懂、不知道现在做的什么,那就跟着做完看效果 内容参考于:易道云信息技术研究院VIP课 上一个内容:33.游戏登录数据…