转译器
主要进行语法转换,解析现代代码,并使用旧的语法结构对其进行重写,进而使其也可以在旧的引擎中工作
代表工具:Babel
- babel做的事
- 转译语法
- 通过polyfill方式填充缺失的特性,core-js
- 源码转换
- babel编译流程(@babel/parser、@babel/traverse、@babel-generator)
- 解析源代码为ast抽象语法树,包括词法分析和语法分析过程
- 操作ast(操作其中的节点),使用深度优先遍历,转换为需要的低版本语法的ast,包括对ast的Node节点的一些优化操作
- 生成最终的代码(借助@babel-generator工具),同时也能创建 Source Map 映射
- babel组成(以babel7为例)
- @babel/preset-xxxx: 预设,插件包
以@babel/preset-env为例,包含的插件将支持所有最新的 es6+ 语法;点击查看@babel/preset-env包含的插件列表
// Babel预设‘由后向前’执行,确保向后兼容
// babel.config.js
module.exports = {
presets: [a, b, c], // 执行顺序c, b, a
// ...
};
-
@babel/polyfill
-
@babel/core: 进行babel转码的核心库
-
@babel/runtime:提供统一的模块化的辅助函数
-
@babel/plugin-transform-runtime: 去除冗余的helper, 减小打包体积
-
@babel/plugin-transform-xxx: 具体的插件,进行代码编译;插件优先级高于preset
如 @babel/plugin-transform-arrow-functions(转换箭头函数语法),@babel/plugin-transform-classes(转换es6-class语法)
特别地:webpack等构建工具,提供了在每次代码更改时自动运行转译器的方法,因此很容易将代码转译集成到开发过程中
Shim && Polyfill相关说明
目前主要用于解决实现了
web新技术、新标准的浏览器兼容问题
shim(垫片): 使用已有的api模拟出新的api,影响已有环境, 是一种优雅降级;增加了学习成本
polyfill(填充):
程序库先检查浏览器是否支持某个API,如果不支持则加载对应的 polyfill,不提供新的API,只是实现标准的api
shim 的概念 > polyfill 更大一些,可以将 polyfill 理解为专门兼容浏览器 API的 shim.
案例:core-js
以MDN Number.isInteger为例
// shim实现
function myIsInteger(value) {
if (Number.isInteger) return Number.isInteger(value);
// 自行操作
return typeof value === "number" && isFinite(value) && Math.floor(value) === value;
};
// polyfill
Number.isInteger = Number.isInteger || function(value) { return typeof value === "number" && isFinite(value) && Math.floor(value) === value; };
查看新特性支持情况的工具