美文网首页
babel 学习笔记

babel 学习笔记

作者: 回调的幸福时光 | 来源:发表于2019-12-11 20:10 被阅读0次

参考了很多文章,只是为了搞清楚babel 7 之后容易搞混的概念。

介绍

本文主要解决如下几个问题:

  1. babel 是什么?
  2. babel 的原理是什么?
  3. babel 7 常见的核心包有哪些?
  4. babel 7 的最佳配置实践

一、babel 是什么?

babel 是一个 JavaScript 编译器。

除了常用的 将新语法转换为向后兼容的语法外,还支持如下功能:

  • 支持语法扩展(例如 JSX)
  • 支持静态类型检查的流式语法

二、babel 的原理是什么?

babel 的 三个主要处理步骤分别是:解析(parse)转换(transform)生成(generate)

babel 处理步骤

2.1 解析

解析步骤接收代码并输出抽象语法树(AST)。

  • 词法分析
    词法分析阶段把字符串形式的代码转换为令牌(tokens)流。
  • 语法分析
    语法分析阶段使用令牌中的信息把令牌流转换成 AST 的形式。

2.2 转换

转换步骤接收 AST 并对其进行遍历,在此过程中对节点进行添加、更新及移除等操作。

2.3 生成

代码生成步骤把最终的 AST 转换成字符串形式的代码,同时还会创建源码映射。

三、babel 7 常见的核心包有哪些?

babel 7

3.1 @babel/preset-env

@babel/preset-env 是一个智能的 babel 预设,让你能使用最新的 JavaScript 语法,他会帮你转换成代码的目标运行环境支持的语法,提升你的开发效率并让打包后的代码体积更小。

运行机制:
@babel/preset-env 依赖了许多优秀的开源库,并利用它们维护和增强 Babel 语法转换、语法实现,来支持对于的目标环境的版本的语法、特征。

重要的配置项:

target 可以指定浏览器类型。
这里推荐使用单独的文件 browserslistrc 来指定目标浏览器,因为除了 babel 还有其他插件,例如 postcss 也会用到。

useBuiltIns 配置@babel/preset-env 如何处理 polyfill

  • entry
    这个属性将会把 import "@babel/polyfill 或者 require("@babel/polyfill") 替换成对应环境(基于配置的目标环境)的 polyfill。
  • usage
    按需加载需要的polyfill, 一个打包的 bundle 之后加载一次。
  • false
    不加载polyfill

3.2 @babel/polyfill

@babel/polyfill模块包括core-js 和一个自定义的 regenerator runtime 模块用于模拟完整的 ES2015+ 环境。

  • 新的内置组件:Promise、WeakMap
  • 静态方法:Array.from、Object,assign()
  • 实例方法:Array.prototype.includes
  • 生成器函数

弊端:会污染全局

Babel 7.4 之后废弃了 @babel/polyfill, 不再推荐使用。需要分别引入

import "core-js/stable";
import "regenerator-runtime/runtime";

3.3 @babel/plugin-transform-runtime

@babel/plugin-transform-runtime 是一个可重新使用Babel注入的帮助程序代码以节省代码大小的插件。

诸如“ foobar” .includes(“ foo”)之类的实例方法仅适用于core-js @ 3。
如果您需要填充它们,则可以直接导入“ core-js”或使用@babel/preset-env的useBuiltIns选项。

为什么需要 @babel/plugin-transform-runtime?

默认情况下,辅助函数将被添加到需要它的每个文件中。有时不需要重复,特别是当您的应用程序分布在多个文件中时。

  1. 所有辅助函数都将引用模块@babel/runtime,以避免在编译后的输出中出现重复。运行时将被编译到您的构建中。

  2. 该插件的另一个目的是为您的代码创建一个沙盒环境。如果直接导入core-js或@babel/polyfill及其提供的内置程序(例如Promise,Set和Map),则这些将污染全局范围。虽然这对于应用程序或命令行工具可能是可以的,但是如果您的代码是要发布供他人使用的库,或者您无法完全控制代码运行的环境,则将成为一个问题。

corejs option Install command
false npm install --save @babel/runtime
2 npm install --save @babel/runtime-corejs2
3 npm install --save @babel/runtime-corejs3

四、区分开发依赖和生产依赖

Babel 7.4 版本

需要作为开发依赖的:
@babel/preset-env@babel/plugin-transform-runtime@babel/polyfill

需要作为生产依赖的:
@babel/runtimeregenerator-runtimecore-js

总结

@babel/preset-env 是为了解决按需加载 polyfill
@babel/polyfill 是为了提供语法之外的垫片(内置组件、静态方法、实例方法等)
@babel/plugin-transform-runtime 是为了解决全局污染和辅助函数的重复引入

五、实践

5.1 babel 的疑惑解答

说明一:@babel/preset-env 默认配置,并不能完整的转换 es6、以及 es7、es8 等新提案,它只能够转换新语法,但是对于Array.includes() 、Promise 等并不支持

说明二:@babel/polyfill 提供了语法之外的垫片(内置组件、静态方法、实例方法等),@babel/polyfill 依赖于 core-jsregenerator-runtime 实现的垫片

说明三: babel 7.4 之后废弃了 @babel/polyfill

说明四:core-js 是 JavaScript 的模块化标准库,提供了大部分 ES2015+ 的 polyfill 。现在推荐使用 core-js@3

说明五:regenerator-runtime facebook 出品的一个提供编译 generatorasync/await 的独立运行时。

总结:babel 7.4 之后@babel/preset-env 需要和 core-jsregenerator-runtime 搭配使用,才能提供完整的 ES2015+ 环境

5.2 普通应用的 babel 配置

安装babel 相关的依赖

yarn add @babel/core @babel/preset-env babel-loader --dev
yarn add core-js@3
yarn add regenerator-runtime

webpack.config.js

module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: {
          loader: "babel-loader"
        }
      }
    ]
  }

.babelrc 文件

{
  "presets": [
    [
      "@babel/preset-env", 
      {
        "useBuiltIns": "usage",
        "corejs": 3
      }
    ]
   ]
 }

说明一:babel-loader 是 webpack 的插件, 会默认读取 .babelrc中的配置
说明二:core-js@3regenerator-runtime 需要作为 dependencies, 因为这两个依赖中的部分或全部代码会被引入进代码,作为 polyfill,属于生产依赖。
说明三:useBuiltIns 的参数选择,推荐选择 usage,此选项将按需导入 polyfill。而 entry 会把全部的 polyfill 都引入到打包后的文件中。
说明四:useBuiltIns 会把 polyfill 引入到全局,所以会污染全局。
说明五: useBuiltIns: usage 配置时,需要在主文件中主动引入 core-js

import "core-js/stable";
import "regenerator-runtime/runtime";

5.3 第三方库的 babel 配置(待更新)

@babel/transform-runtime 会从 core-js-pure 这个包里去加载对应的polyfill代码,core-js-pure里面的代码不会污染全局变量,适合第三方库的开发。

-- 2020/01/07 更新 --

参考

babel 中文文档-使用说明
Babel 手册
刘小夕:不容错过的 Babel7 知识
知乎:babel 只编译语法
知乎:致我们学前端的小时光—corejs与env、runtime的不解之缘
知乎:Babel学习系列4-polyfill和runtime差别(必看)
怎么给新手科普Babel:polyfill/preset-env/plugin-transform-runtime
关于Babel你只需要知道三个插件
一口(很长的)气了解 babel
荒山:深入浅出 Babel 上篇:架构和原理 + 实战
倪晓磊:【工程化】@babel/preset-env 与@babel/plugin-transform-runtime 使用及场景区别

相关文章

  • babel学习笔记

    babel 转译 安装以下依赖: @babel/core调用 Babel 的 API 进行转码 babel-loa...

  • Babel 学习笔记

    基本使用 新建项目目录,初始化 npm 在项目根目录下安装 Babel 每年每个 preset (es2015) ...

  • 学习笔记 《Babel》

    作为一门按照标准制定,浏览器厂商各自实现的程序语言,从新语法的提出到标准化,需要经历漫长的历程,Babel 的价值...

  • Babel 学习笔记

    在 Github 上 Fork 了别人的代码,在 package.json 中看到了很多与 Babel 有关的包,...

  • babel学习笔记

    阮一峰babel入门教程 babel官网 一、配置 .babel 文件 { "presets":["es2015...

  • babel学习笔记

    本文源代码: babel入门 创建一个package: 安装babel: 安装babel-polyfill: 需要...

  • babel 学习笔记

    参考了很多文章,只是为了搞清楚babel 7 之后容易搞混的概念。 介绍 本文主要解决如下几个问题: babel ...

  • Babel transform-runtime

    Babel @babel/plugin-transform-runtime 本节我们来学习 @babel/plu...

  • Babel transform-runtime

    Babel @babel/plugin-transform-runtime 本节我们来学习 @babel/plu...

  • React源码阅读

    React 源码阅读笔记 babel转JSX babel 更新器 React.CreateElement 传入三个...

网友评论

      本文标题:babel 学习笔记

      本文链接:https://www.haomeiwen.com/subject/tmuggctx.html