本篇是根据最新babel 7版本写的,里面用到的一些babel相关包都是babel 7的
 
 
1,babel是如何工作的
babel是一个转译器,这里我严格区分了转译器和编译器,因为编译器最终生成的是机器指令,已经和最初的代码完全不一样了,而转译器只是将高级别的语言转化为低级别的语言,能更好的兼容,所以我把它称作转译器,仅仅做了转化。
 
babel的工作流程,简单来说,就是传入code字符串,经过一系列处理后,吐出code字符串,就像这样:   >Code => do something => Code
 
传统编译过程?(分词/词法分析,解析/语法分析AST,生成机器指令)
 
其实babel也类似,三个过程:解析,变换,再建
 
1,解析:
将代码字符串解析成AST(抽象语法树),在这一步里,babel会顺带进行语法的正确性校验
(关于这一步里,实际上就是编译器过程的第一二两步,生成AST的过程,具体的可参考之前的js编译原理那篇随笔)
 
2,变换:
遍历整个抽象语法树,对AST进行变换操作
 
3,再建:
再次递归遍历整个新的AST,根据变换后的AST再生成代码字符串
 
而我们在配置文件中写的 presets 和 plugins 就是在第二阶段 变换 过程中使用的
2,plugin是干嘛用的
plugin就是用在do something的时候,如果没有plugin,code还是原字符串返回,不作处理
plugin会运行在preset之前
plugin是从前往后,而preset是从后往前执行
3,presets是干嘛用的
preset是用来组合plugin的,无需我们手动安装很多plugin,而是提供了一组插件的集合(单点和套餐的区别)
比如我们用react的时候,我们就要添加@babel/preset-react,用ts的时候,就要添加@babel/preset-typescript
4,presets一些常见的配置项的功能及作用
env: 通过配置得知当前目标环境的特点,然后只做必要的转换,如果不写配置项,默认env为latest,也等价于es2015 + es2016 + es2017三个相加
5,其它一些相关的包
 
@babel/core
这个包里提供了很多代码转化的API,可以直接用里面的API对某一段代码进行转化,但是大部分情况我们不会手动调用,可是这个包确实必须要用的,因为其它的包会用到它。
@babel/preset-env
它是多个preset的集合,并且不断在更新,我们可以通过配置项来决定需要支持的平台(浏览器或者node平台,不同版本下),然后按需加载插件,如果不配置,默认情况下和babel-preset-latest等同,会加载从es2015开始的所有preset
@babel/register
每当使用 require 命令加载 .js, .jsx, .es, .es6 的后缀名文件时,会先用babel进行转码。
使用时必须先加载 require('@babel/register'),这个通常我们会在做服务端编译的时候,引入这个。
@babel/polyfill

从7.4版本开始,不推荐使用了,下面讲一下原因:
babel默认只转换js语法,不转换新的API,比如 Iterator, Generator, Set, Maps, Proxy, Reflect, Symbol, Promise 等全局对象,以及一些定义在全局对象上的方法,比如 Array.from, Object.assign ,如果想用这些方法,就必须使用 @babel/polyfill ,它内部集成了 core-js, regenerator
使用时必须在所有代码运行之前加 require('@babel/polyfill'),所以之前通常也是在服务端代码中加入这个。
 
 
缺点:
打出来的包非常大,因为它是一个整体,会一次性将所有的方法都加到原型链上,没用到的那些方法也会加上去,所以可以单独使用 core-js 的某个类库来解决
会污染全局变量,因为直接在原型上做修改
如何解决这些缺点?使用 @babel/plugin-transform-runtime 和 @babel/runtime
@babel/plugin-transform-runtime 和 @babel/runtime
简单来说,它能有效的减少重复代码,并且可以实现在需要进行转换的时候才转换,不会像 @babel/polyfill 那样一次性全部处理
使用时必须将 @babel/runtime 添加到 dependencies 中
那这样的话,谁还用 @babel/polyfill 呢,是否有场景是必须要用它,而 @babel/runtime 解决不了的呢?
有, 实例方法无法转码,如
 
'!!!'.repeat(3);
'hello'.includes('h');

  

 

但是那都是过去了!

@babel/runtime-corejs3 里提供了对实例方法的转码,所以不用使用babel-polyfill,使用的时候在@babel/plugin-transform-runtime里配置属性 corejs: 3

 
 
 
以上就是我在学习babel过程中觉得有价值的部分了,可能面试会遇到的这些问题,如果后续还看到有用的内容,会继续更新。
 
end

最新文章

  1. Oracle数据库文件路径变更
  2. PHP realpath() 函数
  3. 3-Highcharts 3D图之3D柱状图分组叠堆3D图
  4. 日志分析(五) PV&UV
  5. [Gauss]HDOJ3364 Lanterns
  6. 关于Windows的139和445端口
  7. FFmpeg部署及相关指令操作说明
  8. WinForm 进度条
  9. SVG路径
  10. python 复数类型
  11. MGR主从不一致问题排查与修复
  12. git学习——Git 基础要点【转】
  13. mysql基础拓扑图
  14. 3d md5 demo
  15. u3d 场景资源打包
  16. Binder AIDL中自定义类型传递的源码分析
  17. rails常用验证方法
  18. Oracle执行SQL报错ORA-00922
  19. MVC框架入门准备(二) - 语言包类与工厂模式
  20. SQL注入--显注和盲注中过滤逗号绕过

热门文章

  1. x86架构:分页机制和原理
  2. Sharding-JDBC实现水平拆分-单库分表
  3. Mybais面试题(一)
  4. 安卓APP开发的初步了解
  5. Python使用Tornado+Redis维护ADSL拨号服务器代理池
  6. Python中匿名函数与内置高阶函数详解
  7. 太鸡冻了!我用 Python 偷偷查到暗恋女生的名字
  8. Hibernate配置文件和映射文件详解
  9. DotNet Core
  10. Vue Vue-loader / VueLoaderPlugin / Webpack