babel原理_看不懂的babel

Babel是什么?Babel的原理是什么?Babel怎么用?先来一波三联 (看完觉得不错的话暗示嘿嘿嘿)

Babel是什么?第一步,先来波翻译~~ ,上图!

哈哈,知道没 ,Babel 是巴比伦文化里的通天塔

我TM**上来就是一巴掌 ,这还用你教?不过听起来还挺有文化的 !羡慕这些牛逼的人,不光代码写得好,还这么有文化,不像我们,起个变量名都得憋上半天,吃了没有文化的亏。

好了好了别打了 ,直接引用官方文档官网链接Babel 是一个 JavaScript 编译器 Babel 是一个工具链,主要用于将 ECMAScript 2015+ 版本的代码转换为向后兼容的 JavaScript 语法,以便能够运行在当前和旧版本的浏览器或其他环境中。

「小沐标总结起来用通俗的话来讲」

「1. Babel将es6的语法通过编译器转换为es5的语法」

「2. 同时Babel通过polyfills这个垫片来提供es6新增的api」从Babel 7.4.0开始,polyfills这个包已经被弃用,取而代之的是直接包含core-js/stable(用于填充ECMAScript特性)和regenerator-runtime/runtime(需要使用经过置换的生成器函数)

Babel的原理是什么?

Babel工作流程

分为如下三步Parser 解析源文件

Transfrom 转换

Generator 生成新文件

抄波图

Babel组成部分

Babel根据模块话思维拆分成多个模块组成,所有Babel模块都作为单独的npm软件包发布,其范围为@babel(自版本7起)

没时间解释了直接抄图

@babel/core将源码转化为抽象语法树 (AST)

@babel/cli可以使Babel使用命令行编译文件。

@babel/plugin* babel语法转化插件

只是语法转化,如箭头函数、let、class、模板字符串、解构等等,不包括API啊注意 ),相当于@babel/core提供插槽,而是用Babel插件转化成相对应的语法

@babel/preset-env 通用的转ES6的插件集合

转换ES6有N多的插件,配置起来超级蛮烦 ,没错,@babel/preset-env是给我们提供了一个通用的转ES6的插件集合引用官方的话(当然是直接翻译 )

@babel/preset-env是一个智能(障---开玩笑嘻嘻 )预设,可让您使用最新的JavaScript,而无需微观管理目标环境所需的语法转换core-js ES6新增API的补丁

core-js 是ES6新增API的补丁(用ES5实现)es6API补丁-官方链接,自@babel/polyfill 7.4.0 起已弃用,建议您core-js通过corejs选项直接添加和设置版本。但是不幸的像Proxy、Symbols由于ES5的局限性,无法对代理进行转译或填充

@babel/plugin-transform-runtime 复用帮助文件,为代码创建一个沙盒环境

core-js新增API 如Promise,会污染全局环境,对库开发者很不友好,试想下如果引入一个库,但是库中定义了全局变量Promise,而且这个Promise版本很旧,这对应用者来说就很糟糕了,还有Babel编译时使用很小的帮助器来完成class类申明,如_classCallCheck、_defineProperties等,默认情况下,它将被添加到需要它的每个文件中,这将造成代码大量的重复变得臃肿。上图

@babel/runtime 作为一个帮助文件的库 往往和@babel/plugin-transform-runtime 一起使用,可以复用帮助文件。

效果上图!

还有一个污染全局环境没解决滴呢

别急让我翻翻文档。。。 官方文档链接

找到啦 options中有个corejs字段参数英文水平差直接上中文

大致上就是说@babel/plugin-transform-runtime默认不提供api垫片功能,但是我们可以手动配置, 我们不使用上面提到的core-js补丁,因为他会引入全局变量,而是安装另一个插件@babel/runtime-corejs3,效果如下图所示:

会把Promise api取个别名_Promise

Babel怎么用

上面讲了一大通,代码硬是一个字母都打不出来

哈哈哈 ,接下来我们一步步实现吧

第一步安装核心模块@babel/core肯定要装(没它怎么编译源码转成抽象语法树呀)

@babel/preset-env肯定要装(新语法仅靠它了)

@babel/cli 肯定要装(命令行执行呀,不然怎么执行 )

core-js 不是库开发的话,用core-js问题也不大嘛

@babel/plugin-transform-runtime @babel/runtime 优化代码要要要

npm init -y

npm install --save-dev @babel/core @babel/cli @babel/preset-env @babel/plugin-transform-runtime

npm i @babel/runtime core-js

第二步 配置文件

.babelrc.js

module.exports = {

presets: [["@babel/env", {

useBuiltIns: "usage"

}]],

plugins: ["@babel/plugin-transform-runtime"]

}

package.json

"scripts": {

"babel": "babel src --out-dir dist",

"test": "echo \"Error: no test specified\" && exit 1"

},

几个个问题presets是什么? @babel/env又是什么?

presets表示一个预设,表示插件集合,小伙伴们一定很奇怪@babel/env是什么,@babel/env是@babel/preset-env的简称,babel规定如果 preset 名称的前缀为 babel-preset-,你可以使用它的短名称。喔原来是这样子呀 ,

但是里面这么多数组嵌套,看的我眼睛都花了 详细介绍官方链接

官方文档上写着其实是 preset 都可以接受参数,参数由插件名和参数对象组成一个数组 也就是说如果要给preset设置参数就要写成数组的形式,第一个参数表示插件集合,第二个参数表示options对象,话不多说上图

options.useBuiltIns 这个选项是配合core-js 来为ES6新增API提供垫片的,当useBuiltIns:"entry",会把所有的ES6新增API导入,并且要在index.js手动引入core-js 运行结果上图

当useBuiltIns: 'usage'时,会按需导入,并且不需要全局import,结果上图

3 只看到@babel/plugin-transform-runtime 没看到@babel/runtime,@babel/runtime和@babel/plugin-transform-runtime是绑定在一起的,不需要配置

关于配置文件 官方链接(可跳过jump ‍♀️)

Babel有两种并行的配置文件格式,可以一起使用,也可以独立使用。

如果是Monorepos的项目的话,就要考虑使用babel.config.*的配置文件类型

如果对于普通项目来说,推荐使用.babelrc.*的配置文件类型

what Monorepos?i dont care

简单来说Monorepos的项目就是项目中包含多个package包,每个package包中都有一个package.json文件项目范围的配置--也可以叫全局配置(Babel 7.x中的新增功能)

babel.config.json 文件,具有不同的扩展名(可以为.json, .js,.cjs和.mjs后缀)

查看了官方文档和参考了资料 ,我睡着了。。。

首先Babel具有“根”目录的概念,该目录默认为当前工作目录。对于项目范围的配置,Babel将在此根目录中自动搜索一个babel.config.json文件或使用受支持的扩展名的等效文件,也就是说当命令行执行babel命令的时候会自动查找babel.config.*的配置文件,如果没有配置babelrcRoots字段,它默认不会加载合并子包中的.babelrc.*文件,也就是收对于子包的编译用的是全局的配置文件,对项目中的node_modules依赖包也进行编译,除非配置exclude剔除,值得注意的一点是他必须在项目的根目录

相对文件配置.babelrc.json 文件,具有不同的扩展名(可以为.json, .js,.cjs和.mjs后缀)

作用域的范围与待编译的文件位置有关,对于Monorepos的项目来说,在子包中的.babelrc.json只能作用与当前子包,它允许你为每个子包单独设置配置文件,公共的配置可提取到全局的配置文件中(babel.config.*)package.json中的babel参数配置

Monorepos的项目配置文件规则

Monorepos目录结构,上图

这时候就需要全局配置的能力了,首先在根目录下的babel.config.js作为全局配置的通用配置,而在子包中的.babelrc.js作为子包的单独配置,babel可以在全局编译,也可以在子包中单独编译babel在全局编译

当命令行执行babel命令的时候会自动查找babel.config.*的配置文件,这时如果要合并使用子包中的单独配置文件,则需要配置babelrcRoots: ["package1"],但是实际过程中会遇到问题,就是会把子包中的node_module也进行编译,这是可以使用 ignore:[/node_modules/]忽视对其的编译

在子包中单独编译 由于子包中的.babelrc.js只能作用于当前子包,无法使用全局配置文件,所以执行命令行时需要添加--root-mode upward

"babel": "babel --root-mode upward src --out-dir dist",

第三步测试

随便写点吧 index.js

class Person{

constructor(name,age){

this.name=name

this.age=age

}

getName(){

return this.name

}

}

let zjj=new Person("zjj",10)

console.log(zjj)

console.log(new Promise((resolve,reject)=>resolve(10)))

输出就不贴了,可以贴但没必要

如果要避免污染全局变量

第一步安装@babel/runtime-corejs3

npm install --save @babel/runtime-corejs3

第二步修改.babelrc.js

module.exports = {

presets: ["@babel/env"],

plugins: [

[ "@babel/plugin-transform-runtime",{

corejs:3

}]

]

}

删除 useBuiltIns: "usage",也就是不使用core-js,而是使用@babel/runtime-corejs3

第三步,重中之重!

平复心情,使身心保持最佳状态,输入npm run babel

参考资料

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值