babel 基础库分析和使用

babel 基础库分析和使用,第1张

转译过程一般分为三个阶段

parse: 包含词法分析、语法分析和语义分析三个阶段,最终生成抽象语法树(AST)transform:会调用各种插件对 AST 进行增删改。generate:把 AST 转换成最终的目标代码并生成 sourcemap。

@babel/core

babel 的核心库,parse 和 transform 两个核心方法都是在这个库中

@babel/cli

终端运行工具,这样我们可以直接使用终端命令对指定的文件进行转译
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "babel ./src/index.js --out-file ./src/compliled.js --watch"
  },

进行代码语法转换

es6+语法向下兼容新建一个 .babelrc 文件

比如要转换一个箭头函数

// complied.js
const fn = () => {
  console.log("babel");
};

// .babelrc
{
  "plugins": [
    "@babel/plugin-transform-arrow-functions"
  ]
}

babel-plugin-transform-xx:转换插件,主要用来加强转换能力;babel-plugin-syntax-xx:语法插件,主要是扩展编译能力,比如不在 async 函数作用域里面使用 await,如果不引入 @babel/plugin-syntax-top-level-await,是没办法编译成 AST 树的。并且会报 Unexpected reserved word ‘await’ 这种类似的错误babel-plugin-proposal-xx:用来编译和转换在提案中的属性,比如 class-properties、decorators。

@babel/preset-env

通过compat-table(维护每个特效在不同环境的支持情况),browserslist(具体的浏览器列表)实现精细控制不需要在进行es5+ 的语法转换时一个个引入plugins,通过一个预设一次性引入
// .babelrc
{
  "presets": [
    [
        "@babel/env", // 也可以写@babel/preset-env两者是等价的
        {
            "targets": { //针对浏览器版本进行转换
                "browsers": "Chrome 99"
            }
        }
    ]
  ]
}

进行高级特性的转换

像 Promise 、class、Array.prototype.includes 这些特性babel 是无法转换的,此时我们就需要用到 polyfill

@babel/polyfill

相当于引入下面两个库 require(“core-js”); 版本为2require(“regenerator-runtime/runtime”); 缺点: 体积大,不能实现按需加载污染全局环境:因为像 includes、filter 这样的方法是通过向全局对象和内置对象的 prototype 上添加方法来实现的。
// index.js
import '@babel/polyfill';
const fn = () => {
  console.log("babel");
};
const p = new Promise((resolve, reject) => {
  resolve("babel");
});
const list = [1, 2, 3, 4].map((item) => item * 2);

按需加载 @babel/preset-env 提供了一个 useBuiltIns 参数,设置值为 usage 时,就只会包含代码需要的 polyfillcorejs 的版本设置为 3,因为在 corejs@2 中已经不会再添加新的特性了,同时我们需要手动去安装 corejs@3 缺点 全局环境污染还是存在代码的重复引入,像 _classCallCheck,_defineProperties这样的函数只要用到了 class 就会被引入进来,就会产生重复引入的问题。
// .babelrc
{
  "presets": [
    [
      "@babel/env",
      {   
        "useBuiltIns": "usage",
        "corejs": 3
      }
    ]
  ]
}

@babel/plugin-transform-runtime 和 @babel/runtime

解决按需加载的缺点,前者是在开发的时候使用,但是最终运行时的代码依赖后者,所以我们需要在生产环境中安装 @babel/runtime。 解决命名污染:没有直接修改 prototype,而是使用 _includes 去替代 includes 方法,这样就有效的避免全局环境的污染。解决重复引入:所有的 polyfill 实现都被保存在 @babel/runtime-corejs3 这个包里面,我们需要的时候通过 require 导入进来就可以直接使用了
// .babelrc
{
  "presets": [[
    "@babel/env"
  ]],
  "plugins": [
    [
      "@babel/plugin-transform-runtime",
      {
        "corejs": 3
      }
    ]
  ]
}

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/web/946193.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-18
下一篇 2022-05-18

发表评论

登录后才能评论

评论列表(0条)

保存