Babel 7入门基础知识 全面 实践案例篇【1】推荐。

news2024/11/16 3:14:44

babel前面我们梳理总结 webpack入门基础知识的时候已经用过了。趁着这个机会顺便把Babel基础知识回顾梳理一下,也欢迎正在使用babel的同学一起交流探讨,感谢。

目录

一、Babel是什么?

二、.Babel是如何工作的呢?或者原理是什么?

 2.1 解析【parser】

2.1.1 什么是词法分析?

2.1.2 什么是语法分析?

2.2 转换【transform】

2.3 生成【generate】

三、Babel 预设presets

3.1 语法插件和转译插件

3.1.1 语法插件

3.1.2 转译插件

3.2  常用的预设【preset】

四、Babel的核心 【@babel/core】 

4.1 核心周边【Babel的工作过程】

4.2 集成

4.2.1 @babel-cli

4.2.2 @babel-register

4.2.3 @babel-polyfill

4.2.4 @babel-runtime 和 @babel-plugin-transform-runtime

4.2.5 babel-loader


一、Babel是什么?

关于这个问题Babel官方是这样写的:Babel 是一个 JavaScript 编译器。

Babel 是一个工具链,主要用于将采用 ECMAScript 2015+ 语法编写的代码转换为向后兼容的 JavaScript 语法,以便能够运行在当前和旧版本的浏览器或其他环境中。 

也就是说把ES2015中的一些新特性比如我们在前面使用 React 前端框架做的案例中用到的箭头函数等有些浏览器是不支持的,而我们通过使用Babel的插件后就能使用在当前及旧版浏览器或者其他环境中了。

babel官方为了让我们更好理解,给我们举了例子。

// Babel 接收到的输入是: ES2015 箭头函数
[1, 2, 3].map(n => n + 1);

// Babel 输出: ES5 语法实现的同等功能
[1, 2, 3].map(function(n) {
  return n + 1;
});

上面我们可以看到我们输入代码用的是ES2015新特性箭头函数,而经过Babel处理之后输出的是es5的语法,这就是Babel,它的工作原理是什么? 

二、.Babel是如何工作的呢?或者原理是什么?

下面这张图片是来源Babel官网,属于工具软件包,我们要知道Babel是工具链,其本身不具备转化功能,而是将转化功能分解到插件中,不过不配置任何插件,经过Babel的代码输入和输出是没有区别的

Babel的主要工作流程分为三个阶段: 解析(parser) 转换(transform) 生成(generate)

 2.1 解析【parser】

通过 @babel/parser 把源代码字符串转成抽象语法树(AST),在解析过程中主要是两个阶段:词法分析语法分析。

2.1.1 什么是词法分析

词法分析阶段把字符串形式的代码解析成一个个具有实际意义的语法单元组成的数据,这种数据被称之为令牌(tokens)流。ps:语法单元就是被解析语法当中具备实际意义的最小单元

JavaScript 中常见的语法单元:空白、注释、字符串、数字、标识符、运算符、括号及其他。

2.1.2 什么是语法分析

语法解析器把 Tokens 转换为抽象语法树 AST。抽象语法树 ,它是源代码语法结构的一种抽象表示。它以树状的形式表现编程语言的语法结构,树上的每个节点都表示源代码中的一种结构。

举例:下图是console.log('hello world') 代码转换为抽象语法树的数据。参考网站:https://astexplorer.net/

 

类似上面的结构叫做节点,一个 AST 是由单个或者多个这样的节点构成的,节点内部还可以有子节点,构成一棵语法树。

2.2 转换【transform

通过@babel/traverse遍历抽象语法树(AST),并调用Babel配置文件中的插件,对抽象语法树(AST)进行增删改。

2.3 生成【generate

通过@babel/traverse遍历抽象语法树(AST),并调用Babel配置文件中的插件,对抽象语法树(AST)进行增删改。

三、Babel 预设presets

我们前面也说了 Babel 本身不具备转化功能,而是将转化功能分解到插件中,Babel的插件主要分为语法插件转译插件。插件只对单个功能进行转换,当配置插件比较多时,就可以封装成预设(presets)以此来简化插件的使用,预设简单说就是一组原先设定好的插件,是一组插件的集合

3.1 语法插件和转译插件
3.1.1 语法插件

语法插件只允许Babel解析语法,添加语法插件后,Babel能够解析更多的语法。比如我们调用方法时最后一个参数之后添加逗号就是非法的,如果源码这种写法经过Babel之后就提示语法错误。

但最近的 JS 提案中已经允许了这种新的写法(让代码 diff 更加清晰)。为了避免 babel 报错,就需要增加语法插件 babel-plugin-syntax-trailing-function-commas

3.1.2 转译插件

当添加转译插件后,会将源代码进行转译输出。例如:箭头函数 (b) => b 就会转化为 function (b) {return b}。完成这个工作的插件叫做 babel-plugin-transform-es2015-arrow-functions

当插件配置比较多时,可以把插件预先设定好封装成预设(presets)以此来简化插件的使用,所以预设就是一组插件的集合。

3.2  常用的预设【preset】

常见的预设有四种:

@babel/preset-env、babel/preset-react、babel/preset-typescript、babel/preset-flow。

  1. @babel/preset-env 主要可以根据配置的目标浏览器或者运行环境来自动将ES2015+的代码转换为es5
  2. @babel/preset-react react框架需要的
  3. @babel/preset-flow flow需要的。Flow 是一个静态类型检测工具,进行类型检查,类似于ts
  4. @babel/preset-typescript typescript需要的

可参考Babel的官网:

关于执行顺序: 

  • Plugin 会运行在 Preset 之前
  • Plugin 会从前到后顺序执行
  • Preset 的顺序则从后向前

preset 的逆向顺序主要是为了保证向后兼容,因为大多数用户的编写顺序是 ['es2015', 'stage-0']。这样必须先执行 stage-0 才能确保 babel 不报错。因为低一级的 stage 会包含所有高级 stage 的内容

四、Babel的核心 【@babel/core】 

@babel/core是 babel的核心,主要作用就是根据我们的配置文件转换代码,配置文件一般是.babelrc(静态文件)或 babel.config.js(可编程)。

4.1 核心周边【Babel的工作过程】
  1. Parser( @babel/parser ) : 将源代码解析为 AST
  2. Traverser( @babel/traverse ) : 对 AST 进行遍历,转换插件会通过它获取感兴趣的AST节点,对节点继续操作
  3. Generator( @babel/generator ) : 将 AST 转换为源代码

4.2 集成

Babel的集成 @babel-cli、@babel-node、@babel-register、@babel-polyfill、@babel-runtime 和 @babel-plugin-transform-runtime

4.2.1 @babel-cli

Babel 自带了一个内置的 CLI 命令行工具,可通过命令行编译文件。此外,各种可直接调用脚本都存放在 @babel/cli/bin 中。一个可通过 shell 执行的实用脚本 - babel-external-helpers.js,以及 Babel cli 主脚本 babel.js

4.2.2 @babel-register

babel-register模块改写 require 命令,为它加上一个钩子。此后,每当使用 require 加载 js jsx es es6 后缀名的文件,会使用 babel 进行转码。

使用时,必须首先加载 require ('babel-register'),需要注意的是,babel-register 只会对 require 命令加载的文件转码,不会对当前文件转码,另外由于是实时转码,所以只适合在开发环境中使用。

4.2.3 @babel-polyfill

babel 默认值转换 js 语法,而不转换新的 API,比如 Generator、Maps等全局对象,以及一些定义在全局对象上的方法(Object.assign)都不会转码。

例如:es5 在 Array 对象上新增了 Array.from方法,babel 不会转码这个方法,如果要使用这个方法运行,必须使用 babel-polyfill

使用时,在所有代码运行之前增加 require('babel-polyfill')。或者更常规的操作是在 webpack.config.js 中将 babel-polyfill 作为第一个 entry。因此必须把 babel-polyfill 作为 dependencies 而不是 devDependencies

主要缺点:

  • 使用 babel-polufill 导致打出来的包体积比较大,因为 babel-polyfill 是一个整体,把所有方法都会加到原型链上。比如使用了 Array.from,但它会把 Object.defineProperty也给加上,属于一种浪费,要解决这个问题,可以通过单独使用 core-js 的某个类库解决,core-js 是分开的
  • babel-polyfill 会污染全局变量,给很多的原型链上作出修改,所以会比较倾向于使用 babel-plugin-transform-runtime

注意:如果代码中使用了较高版本的 js实例方法, 比如 [1,2,3].includes(1),此时还是需要使用 polyfill

4.2.4 @babel-runtime 和 @babel-plugin-transform-runtime

有时语法的转换相对复杂,有时会需要一些 helper 函数,比如转换 es6 的 class,es6的 class 需要一个 _classCallCheck 的辅助函数,如果有多个文件都用到了 es6 的 class,则需要在每个文件中都要定义一遍 ,会造成一种浪费;如果将 helper 函数都抽离到一个包中,所有用到的文件都可以引用可减少代码量。@babel/runtime ,提供了各种 helper 函数;那么问题又来了,我们该如何知道该引入哪个 helper 函数呢? 所以又有了 @babel/plugin-transform-runtime插件帮我们自动引入 helper

/* test.js */
const Test {}
/* test-compiled.js */
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
var Test = function Test() {
  _classCallCheck(this, Test);
};
4.2.5 babel-loader

babel-loader中的 loader 的主要作用是在 webpack 打包的时候,用 babel 将 ES6 的代码转换成 ES5 版本的,如下图所示:

 关于 webpack基础知识以及案例 前面已经梳理过,有需要回顾的请参考。 

到这里关于Babel的基础知识包括:

  • Babel的概念、代码转译的过程、
  • 常用的预设
  • Babel的核心概念@babel/core 
  • 集成 @babel-cli、@babel-register、@babel-polyfill 等内容。

Babel实践案例放到另外一篇:Babel入门基础知识 全面 实践案例篇【2】

MySQL在Node.js中的应用:MySQL 预处理、如何在 [Node.js] 中使用 MySQL?-CSDN博客

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

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

相关文章

Windos 执行.sh文件提示没有足够权限执行的解决办法

找到Git安装目录下的sh.exe文件 右键以管理员方式运行 cd到.sh文件所在目录,注意使用 / 而不是 \ 执行.sh文件即可

JavaScript中闭包的概念与其造成的性能问题

如果一个函数没有访问任何外部作用域的变量或方法,那么它其实是拥有闭包特性的,因为在 JavaScript 中,每个函数都可以理解为对其创建时所处作用域的引用。从这个角度来说,即使普通函数本身并没有捕获外部变量,但它们仍…

JAVA集中学习第四周学习记录(四)

系列文章目录 第一章 JAVA集中学习第一周学习记录(一) 第二章 JAVA集中学习第一周项目实践 第三章 JAVA集中学习第一周学习记录(二) 第四章 JAVA集中学习第一周课后习题 第五章 JAVA集中学习第二周学习记录(一) 第六章 JAVA集中学习第二周项目实践 第七章 JAVA集中学习第二周学…

WPF篇(9)-CheckBox复选框+RadioButton单选框+RepeatButton重复按钮

CheckBox复选框 CheckBox继承于ToggleButton&#xff0c;而ToggleButton继承于ButtonBase基类。 案例 前端代码 <StackPanel Orientation"Horizontal" HorizontalAlignment"Center" VerticalAlignment"Center"><TextBlock Text"…

Redis的过期策略与内存淘汰机制详解

文章目录 Redis的过期策略1. 定时删除2. 惰性删除3. 定期删除 Redis的内存淘汰机制1. noeviction2. volatile-random3. volatile-ttl4. volatile-lru5. volatile-lfu6. allkeys-random7. allkeys-lru8. allkeys-lfu LRU与LFU算法总结 Redis作为一种高性能的键值对存储系统&…

C语言 之 理解指针(9)与指针相关的理解题

文章目录 代码1代码2代码3代码4代码5代码6代码7 本篇内容接上一篇&#xff0c;对指针进行一个更深入的理解 建议没看过 上一篇的可以看看上一篇&#xff0c;当然不看也可以。 建议先自行完成再看答案哟 代码1 #include <stdio.h> int main() {int a[5] { 1, 2, 3, 4, …

B站千亿级点赞系统服务架构设计

B站千亿级点赞系统服务架构设计 原文链接&#xff1a;https://www.bilibili.com/read/cv21576373/ 原文作者&#xff1a;哔哩哔哩技术团队-芦文超 点赞的功能太过于简单不再赘述&#xff0c;大家可以点击原文链接简单看下便可知晓。 本讲结合B站知名UP主陆总监的一期视频(h…

【vue3|第21期】Vue3中Vue Router的push和replace方法详解

日期&#xff1a;2024年8月9日 作者&#xff1a;Commas 签名&#xff1a;(ง •_•)ง 积跬步以致千里,积小流以成江海…… 注释&#xff1a;如果您觉得有所帮助&#xff0c;帮忙点个赞&#xff0c;也可以关注我&#xff0c;我们一起成长&#xff1b;如果有不对的地方&#xff…

Android系统Android.bp文件详解

文章目录 1. 基本语法结构2. 常见模块类型3. 模块属性常见属性包括&#xff1a; 4. 具体示例5. 高级功能5.1. 条件编译5.2. 变量定义与使用5.3. 模块继承 6. 总结 Android.bp 是 Android 构建系统&#xff08;Android Build System&#xff09;中的配置文件&#xff0c;用于描述…

C语言典型例题31

《C程序设计教程&#xff08;第四版&#xff09;——谭浩强》 习题2.8 请编写程序将China译为密码&#xff0c;密码的规律是&#xff1a;用原来字母后面的第4个字母代替原来的字母。 例如:C后面的4个字母是G&#xff0c;h后面第4个字母为l 代码&#xff1a; //《C程序设计教程…

TinyLLaVA: A Framework of Small-scale Large Multimodal Models

发表时间&#xff1a;22 Feb 2024 论文链接&#xff1a;https://arxiv.org/pdf/2402.14289 作者单位&#xff1a;SKLCCSE, Institute of Artificial Intelligence, Beihang University, Beijing, China Motivation&#xff1a;当前的大语言模型的参数量太大了&#xff0c;作…

flask学习-day1

介绍 django是大而全&#xff0c;flask是轻量级的框架 django提供非常多组件&#xff1a;orm/session/cookie/admin/form/modelform/路由/视图/模板/中间件/分页/auth/contentype/缓存/信号/多数据库连接 flask本身没有太多的功能&#xff1a;路由/试视图/模板/session/中间件…

【C++ 面试 - 基础题】每日 3 题(八)

✍个人博客&#xff1a;Pandaconda-CSDN博客 &#x1f4e3;专栏地址&#xff1a;http://t.csdnimg.cn/fYaBd &#x1f4da;专栏简介&#xff1a;在这个专栏中&#xff0c;我将会分享 C 面试中常见的面试题给大家~ ❤️如果有收获的话&#xff0c;欢迎点赞&#x1f44d;收藏&…

24/8/9算法笔记 决策树VS线性回归

from sklearn.tree import DecisionTreeRegressorfrom sklearn.linear_model import LinearRegressionfrom sklearn import datasetsfrom sklearn.model_selection import train_test_split import numpy as np X,y datasets.load_diabetes(return_X_yTrue)#糖尿病数据 X_tra…

03、MySQL-DQL(数据查询语言)

目录 1、编写顺序 2、基本查询 3、条件查询 4、聚合函数 5、分组查询 6、排序查询 7、分页查询 8、执行顺序 1、编写顺序 SELECT 字段列表 FROM 表名列表 WHERE 条件列表 GROUP BY 分组字段列表 HAVING 分组后条件列表 ORDER BY 排序字段列表 LIMIT 分页参数2、基本查…

Cesium初探-相机

在 Cesium 中&#xff0c;相机&#xff08;Camera&#xff09;是一个非常重要的概念&#xff0c;它代表了用户观察 3D 场景的视角。相机不仅决定了用户看到的内容&#xff0c;还定义了观察的角度、距离和方向。理解 Cesium 中的相机是如何工作的对于创建有效的 3D 地图和地球应…

关于Redis的面试题(一)

一、为什么要使用Redis 内存数据库&#xff0c;速度很快工作单线程worker&#xff0c;串行化&#xff0c;原子操作&#xff0c;IO线程是多线程的。避免上下文切换使用 IO模型&#xff0c;天生支撑高并发kv模型&#xff0c;v具有类型结构具有本地方法&#xff0c;计算数据移动二…

政府经济学(练习题)

政府经济学&#xff08;练习题&#xff09; 一、单项选择题 政府经济活动的主体是&#xff08; &#xff09;。 A.各级政府 B.各级人大 C.各级政协 D.各级党委政府经济的依据主要是&#xff08; &#xff09;。 A.私人财产所有权 B.社会公共权力 C.道德劝说 D.法律制度1776年亚…

通过指令深入了解Linux 3

&#x1f308;个人主页&#xff1a;Yui_ &#x1f308;C语言笔记专栏&#xff1a;C语言笔记 &#x1f308;数据结构专栏&#xff1a;数据结构 文章目录 1.Linux下的基本指令1.1 more指令&#xff08;有更好的平替&#xff09;1.2 less指令1.3 head指令1.4 tail指令1.5 date指令…

二、Matlab图像处理基础

文章目录 一、Matlab图像处理工具箱二、图像文件的读取2.1 文件信息的读取2.2 图像文件的读取2.3 图像文件的保存2.4 图像文件的显示2.5 像素信息的显示 本章知识点总结 一、Matlab图像处理工具箱 在帮助文档可以搜索到图像处理工具箱的介绍 二、图像文件的读取 2.1 文件信息…