babel 原理三:babel 的工作原理

本文介绍了babel 7.x的更新内容,包括淘汰es201x、更新包命名和提升node.js版本要求。详细解析了babel的工作原理,涉及解析、转换和生成三个阶段,以及如何使用AST进行操作。此外,讨论了babel的plugins、presets、polyfill和runtime,特别是polyfill和babel-runtime的区别,推荐使用transform-runtime以避免全局污染。最后,探讨了如何按需引入core-js以减小代码体积。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

更新 babel7.x

preset 的变更:淘汰 es201x、删除 stage-x、强推 env

npm package 名称的变化:把所有 babel-* 重命名为 @babel/*

不再支持低版本 node:要求 nodejs>=6

only 和 ignore 匹配规则的变化

@babel/node 从 @babel/cli 中独立了

babel-upgrade

babel 的工作原理

  • babel 是一个转译器。
  • 把同种的高版本规则翻译成低版本规则,输出的是另一种更低级的语言代码。
  • 和编译器类似,babel 的转译过程分为三个阶段: parsing-transforming-generating(解析-转换-生成)
    在这里插入图片描述

具体过程

解析

将代码解析为 AST,每个 js 引擎都有自己的 AST 解析器,而 babel 是通过 babylon 实现的,解析过程中有两个阶段:词法分析 和 语法分析。

转换

将 AST 通过 babel-traverse 进行深度遍历,在此过程中对节点进行添加、更新及移除

生成

将转换后的 AST 通过 babel-generator 再转换成 js 代码,过程是深度遍历整个 AST,然后构建可以表示转换后代码的字符串。

此外,babel 只是转译新标准引入的语法,比如 es6 的箭头函数转译成 es5 的函数;而新标准引入的新的原生对象,部分原生对象新增的原型方法,新增的 API 等(如 Proxy\Set 等),这些 babel 不会转译,需要用户自行引入 polyfill 解决。

plugins

  • 应用于 babel 转译的 transforming 阶段,如果该阶段不使用插件,babel 会原样输出代码。
  • 主要关注 transfoming 阶段使用的插件,因为 transform 插件会自动使用对应的词法插件,所以 parsing 阶段的插件不需要再配置。

presets

预设的插件集,以 JS 标准为例,babel 提供了如下的一些 preset:

  • es2015
  • es2016
  • es2017
  • env: 代指最新的标准,包括了 latest 和 es20xx 各年份
  • stage-0 到 stage-4 的标准成形之前的各个阶段,都是实验版的 preset,建议不使用。

polyfill

  • 针对 es2015+ 环境的 shim
  • 实现:把 core-js 和 regenerator runtime 包装
  • 使用 babel-polyfill 会把 es2015+ 环境整体引入到代码环境中,代码可以直接使用新标准所引入的新原生对象,新 API 等,一般来说单独的应用和页面都可以这样使用

runtime

polyfill 和 runtime 的区别

polyfill 可以在应用或页面环境下,library 中不可使用,因为 library 是供外部使用的,但外部的环境并不在 library 的控制范围,而 polyfill 会污染原来的全局环境,这时候 babel-runtime 就可以派上用场了。

transform-runtime 和 babel-runtime

babel-plugin-transform-runtime 插件依赖 babel-runtime,babel-runtime 是真正提供 runtime 环境的包;也就是说 transform-runtime 插件是把 js 代码中使用到的新原生对象和静态方法转换成对 runtime 实现包的引用。

  • babel-runtime 就是一个提供了 regenerator core-js helpers 的运行时库
  • 建议不要直接使用 babel-runtime,因为 transform-runtime 依赖 babel-runtime,大部分情况下都可以用 transform-runtime 达成目标
  • 在 .babelrc 里配置时,还可以设置 helpers polyfill regenerator 这三个开关,以自行决定 runtime 是否要引入对应的功能

core-js 按需引用

  • core-js 是上述 polyfill runtime 的核心
  • polyfill runtime 都是整体引入的,不能做细粒度的调整,会造成代码体积不必要的增大(runtime 的影响较小),依靠 core-js 可以实现按需引入

core-js 组织结构

默认方式

require(“core-js”)
这种方式包括全部特性,标准的和非标准的

库的形式

var core = require(“core-js/library”)
包括全部特性,不会污染全局名字空间

shim

require(‘core-js/shim’) 或 var shim = require(‘core-js/library/shim’) 只包括标准特性

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值