当前位置: 首页 > news >正文

前端工程化工具系列(十一)—— Babel(v7.24):JavaScript编译器

Babel 是一个Javascript 编译器。主要用于将 ECMAScript 2015+ 版本的代码转换为向后兼容(backwards compatible)的 JavaScript 语法,以便能够运行在当前和旧版本的浏览器或其它环境(如:Node.js)中。
Babel 可以在命令行中单独运行也可以和 webpack、rollup 等工具结合使用。

1 单独 || 结合 Webpack 使用

1.1 安装

1.1.1 针对 JavaScript

pnpm add -D @babel/core @babel/preset-env core-js
  • @babel/core
    主要用于将源代码 (JS\TS) 解析为 AST (抽象语法树)。
  • @babel/preset-env
    预设环境。源代码解析成 AST 后,还需要进行转换和生成,这是由插件来做的。@babel/preset-env(预设环境)是常用预设和插件的集合(babel-preset-es2015,babel-preset-es2016,babel-preset-es2017,babel-preset-latest,babel-preset-node5, babel-preset-es2015-node 等,@babel/preset-env 不支持 stage-x 插件)。
    最初每年 EcmaScript 标准更新,都需要使用者手动添加最新年份的预设才能进行新语法的转换,后来改成了 babel-preset-latest,意思为最新的预设(包含了以往所有年份),不用每年都需要手动添加一把。最终 latest 也被废弃,变成了目前的 preset-env。开发人员可以在代码中直接书写已经正式发布的特性。不过,当 ES 更新时,肯定还需要更新一下 @babel/preset-env。
  • core-js
    Babel 默认只转换新的 JavaScript 语法,如: 类、箭头函数、扩展运算(spread),而不转换新的 API ,如:Iterator、Generator、Set、Maps、Proxy、Reflect、Symbol、Promise 等全局对象,以及一些定义在全局对象上的方法(如:Object.assign)。不能被转译的 API 详细清单可以查看 definitions.js 文件。
    core-js 提供了 ES5、ES6+ 的 polyfills (填充物,用于实现浏览器并不支持的原生 API 的代码,它将一个新的 API 引入到一个旧的环境中,仅靠旧环境中已有的技术手段实现),包括 promises, symbols, collections, iterators, typed arrays 等等。之前的 @babel/polyfill 已被废弃。

这里不得不提一下 core-js 库和它的俄罗斯作者。该库一周的下载量比大家熟知的 Angular、 React、Vue加一起的下载量还要多的多。就这样的一个库谁能想到它的作者竟然需要在命令行里 looking for a good job,后来该作者又因为骑摩托车撞死一人,伤一人,被判入狱18个月, 现在已经出狱了,应该也找到工作了…

1.1.2 针对 TypeScript

在 JS 的基础上增加:

pnpm add -D @babel/preset-typescript

1.1.3 通过命令行单独使用

pnpm add -D @babel/cli 
@babel/cli

用于通过命令行编译文件。

1.2 配置

1.2.1 针对 JavaScript

需要结合 browserslist 一起使用,Browerslist 的配置见:《前端工程化工具系列(十)—— Browserslist:浏览器兼容性配置工具》
接下来在项目根目录下创建 babel.config.json,填入以下内容:

{"presets": [["@babel/preset-env",{"useBuiltIns": "usage","corejs": "3","modules": false}]]
}
  • targets
    设置编译代码的目标平台,可以是浏览器也可以是node环境。如不设置,会将所有ES6+的代码编译为ES5-。建议设置,这样可以按目标平台来决定是否进行转换,以避免增加不必要的补丁,减少打包后的代码体积。
    这里没有单独做设置,而是共享了 browserslist 的配置。
  • useBuiltIns
    是否内置兼容。如果设置,就可以不用在 HTML 中引入 polyfill 的 JS 文件来处理浏览器的兼容性问题了。
    可选值包括:“usage” | “entry” | false。
    • false:默认值,即不引入polyfills,不做浏览器兼容。
    • entry:根据配置的浏览器,引入这些浏览器不兼容的polyfill。这个是在文件中已经明确写了import “core-js” 或其中具体某个模块(如:import “core-js/es/array”)的情况下,babel 会根据 browserslist 自动添加指定浏览器不兼容的该模块下的所有 polyfill,无论当前代码是否需要。
    • usage:会根据配置的浏览器以及代码中用到的 API 自动添加polyfill,实现了按需引入。一般使用这个配置。

只有当 useBuiltIns 的值为 entry 或 usage 时,“corejs” 这个选项才会起作用。这里如无特殊情况尽量指定
core-js 的版本为 3(默认为 2), 因为它有很多2没有的新特性: “corejs”: 3。

  • modules
    可选值包括:“amd” | “umd” | “systemjs” | “commonjs” | “cjs” | “auto” | false, 默认是 “auto”.
    一般默认转出的是 CommonJS 模块,这里配置为 false ,是想保留 ESM 模块。

1.2.2 针对 TypeScript

{"presets": [["@babel/preset-env",{"useBuiltIns": "usage","corejs": "3","modules": false}],"@babel/preset-typescript"]
}

2 结合 Rollup

对于一般应用开发来说,直接使用上述的 polyfill 方案是比较方便的,但如果是开发组件库或者类库的话,这种方案未就不太合适,以上第一部分的 polyfill 是添加自定义全局对象或向对象的 prototype 上添加方法实现的,会污染全局作用域。使用 @babel/plugin-transform-runtime 这个插件就可以解决这个问题。

2.1 安装

在以上单独配置的基础上,添加:

pnpm add -D @babel/plugin-transform-runtime

2.1 配置

无论是 JavaScript 还是 TypeScript 都使用以下配置。
如果是 TypeScript 项目,由于转译不能在 babel 中做(会报错),而是通过 rollup 的插件来做。因此,需要移除 @babel/preset-typescript 这个库

{"presets": [["@babel/preset-env",{"modules": false}]],"plugins": [["@babel/plugin-transform-runtime",{"corejs": "3"}]]
}

这里没有单独设置 targets,而是共享了 browserslist 的配置。

针对 Babel 的配置已经完成了,接下来要结合 rollup 来构建打包。具体可参看《前端工程化工具系列(十三)—— Rollup:专注于库构建的JavaScript打包器》。

相关文章:

  • 多线程详解
  • Redis到底支不支持事务?
  • MySQL 存储函数及调用
  • C语言 | Leetcode C语言题解之第142题环形链表II
  • Position定位
  • 深度学习之文本分类模型-基于transformer
  • Spring Web MVC入门
  • AI服务器相关知识
  • 有趣的数学 为什么绝对值和模都用两个竖线表示?
  • Python with语句
  • 大数据运维学习笔记之flink standalone flink on yarn集群搭建 —— 筑梦之路
  • AI作画工具介绍
  • 容器是什么?
  • 【linux】(6)文本处理sed
  • 《软件定义安全》之一:SDN和NFV:下一代网络的变革
  • exif信息对照
  • github从入门到放弃(1)
  • GitUp, 你不可错过的秀外慧中的git工具
  • HTTP--网络协议分层,http历史(二)
  • JavaScript设计模式之工厂模式
  • Java比较器对数组,集合排序
  • Java的Interrupt与线程中断
  • 记一次用 NodeJs 实现模拟登录的思路
  • 线上 python http server profile 实践
  • 远离DoS攻击 Windows Server 2016发布DNS政策
  • (01)ORB-SLAM2源码无死角解析-(56) 闭环线程→计算Sim3:理论推导(1)求解s,t
  • (BAT向)Java岗常问高频面试汇总:MyBatis 微服务 Spring 分布式 MySQL等(1)
  • (java版)排序算法----【冒泡,选择,插入,希尔,快速排序,归并排序,基数排序】超详细~~
  • (Redis使用系列) Springboot 使用redis实现接口Api限流 十
  • (三)docker:Dockerfile构建容器运行jar包
  • (三十)Flask之wtforms库【剖析源码上篇】
  • (十六)串口UART
  • (学习日记)2024.03.25:UCOSIII第二十二节:系统启动流程详解
  • (转)Oracle 9i 数据库设计指引全集(1)
  • .cn根服务器被攻击之后
  • .FileZilla的使用和主动模式被动模式介绍
  • .NET 6 在已知拓扑路径的情况下使用 Dijkstra,A*算法搜索最短路径
  • .NET C#版本和.NET版本以及VS版本的对应关系
  • .NET 中选择合适的文件打开模式(CreateNew, Create, Open, OpenOrCreate, Truncate, Append)
  • .netcore 获取appsettings
  • .net开源工作流引擎ccflow表单数据返回值Pop分组模式和表格模式对比
  • @JSONField或@JsonProperty注解使用
  • [1] 平面(Plane)图形的生成算法
  • [C++][数据结构][跳表]详细讲解
  • [C++初阶]string类的详解
  • [Google Guava] 1.1-使用和避免null
  • [HOW TO]怎么在iPhone程序中实现可多选可搜索按字母排序的联系人选择器
  • [MRCTF2020]Ez_bypass1
  • [NOIP2013]华容道
  • [PY3]——logging
  • [python]yfinance国内不能使用
  • [Python人工智能] 四十.命名实体识别 (1)基于BiLSTM-CRF的威胁情报实体识别万字详解
  • [ruby on rails]rack-cors, rack-attack
  • [SpringCloud] Feign 与 Gateway 简介
  • [uniapp] uni-ui+vue3.2小程序评论列表组件 回复评论 点赞和删除