前端修仙路-Babel 7.x 详解

前端修仙路-Babel 7.x 详解

前言:Babel 是一个 JavaScript 编译器,主要用于将 ECMAScript 2015+ 版本的代码转换为向后兼容的 JavaScript 语法,以便能够运行在当前和旧版本的浏览器或其他环境中。本文主要介绍Babel常用的预设和插件相关概念,以及在webpack中如何使用。

babel图示


babel 的前置知识

网上流传的很多是 babel6 的教程,babel6babel7 的区别,可以根据命名来区分,babel7 的包一般以@babel/xxx开头,babel6则是babel-xxx开头,本文一切以现有最新版为准。babel6 之后,默认的转换被删除,如果不指定插件和预设,babel 只会返回原始代码。

概念

  • Presets 预设,babel预设的一组插件集合。

  • Plugins 插件,插件分为以下两种
    • Transform Plugins 转换插件,这种类型的插件一般负责将ES6 / ES2015转换为ES5,转换为ES3,jsx,以及实验性功能等。
    • Syntax Plugins 语法插件,一般转换插件里已经含有语法解析,不需要再额外引入。

  • Helpers 帮助程序,含有一些帮助编译的方法,这些主要提供给插件内部使用

  • stage-x 实验性的预设,预设中含有的各种提案阶段
    • 提案经过TC39(ECMAScript 标准背后的技术委员会)4个阶段:
      • babel-preset-stage-0 设想(Strawman):只是一个想法,可能有 Babel插件。
      • babel-preset-stage-1 建议(Proposal):这是值得跟进的。
      • babel-preset-stage-2 草案(Draft):初始规范。
      • babel-preset-stage-3 候选(Candidate):完成规范并在浏览器上初步实现。

注意stage-4不存在,因为4已经采纳成为标准,将在下一个年度版本发布。

  • polyfill 这个词得分开看,poly为单词前缀,通常表示多的,多数的,意味着有多种技术,fill 填补(漏洞),合起来就是用技术去填补漏洞,通常指的是对低版本浏览器某些不兼容的api的一种修复方式。

babel的使用方式

  1. babel-cli   命令行中使用 babel 编译文件的简单方法
  2. babel-register   只需要在文件头部添加require("@babel/register");即可编译该文件,原理是通过require的钩子进行即时编译模块
  3. babel-core   以编程的方式来使用 Babel,var babel = require("@babel/core");
  4. babel-loader   在webpack作为loader加载使用

babel的配置方式

  1. loader中配置,webpack中的loader传递选项可以进行配置
  2. package.json中配置,提供有babel键值对进行配置
  3. 配置文件配置,一般约定有.babelrc、.babelrc.json、babel.config.json、babel.config.js、.babelrc.js这些配置文件。
  4. cli命令行传递选项或者使用api进行配置

babel的编译流程

input string -> @babel/parser parser -> AST -> transformer[s] -> AST -> @babel/generator -> output string


babel如何使用

接下来介绍babel在webpack中如何使用

安装

    npm install babel-loader@8 @babel/core @babel/preset-env @babel/plugin-transform-runtime -D
    npm install @babel/runtime-corejs3
  • babel-loader@8   babel-loader8.0 版本, 以 loader 的方式去编译js模块
  • @babel/core   babel 的编译核心,babel-loader 需要该核心模块支持
  • @babel/preset-env   babel 的预设,可以理解为一套组合 babel 插件集合,集成了一套转换规则
  • @babel/plugin-transform-runtime   可重用Babel注入的帮助程序代码以节省代码大小。如果使用preset-env,可以不安装该模块。
  • @babel/runtime-corejs3   babel 的模块运行时,含有助手方法以及 polyfill

使用

webpack中配置loader

    module.exports = {
        module: {
            rules: [
            {
                // 以 .js 结尾的文件, 使用 babel-loader
                test: /\.js$/,
                // 编译时, 不去node_modules 目录下找
                exclude: /node_modules/,
                use: {
                    loader: 'babel-loader',
                }
            }
            // ...省略无关代码
            ]
        }
    }

babel.config.js文件中的配置

// 第一种方式
module.exports = {
    "presets":[
		["env",{
			"targets":{     // 编译目标,根据平台来编译所需
				"edge":"17",
				"firefox":"60",
				"chrome":"67",
				"safari":"11.1",
				"ie":"8"
			},
			"useBuiltIns":"usage",	// 不需要手动引入 @babel/polyfill,按需引入
			"corejs":3 // 指定使用的corejs版本
		}],
                // "es2015", // 需要安装@babel/preset-es2015
                // "stage-2" // 需要安装@babel/preset-stage-2,慎重使用提案阶段内容,因为可能会发生改变。
	    ],
    "plugins": []
  }

//第二种方式
module.exports = {
  "presets": [
    [
      "env"
    ]
  ],
  "plugins": [
    ["@babel/plugin-transform-runtime", {
      "corejs": 3
    }]
  ]
}

两种配置的区别是:

  1. 方案一使用的是presets配置方式,采用修改全局对象的方式去polyfill。适合平时的业务项目使用。如果使用第一种方式可以不安装@babel/plugin-transform-runtime插件。
  2. 方案二使用的是@babel/plugin-transform-runtime插件的方式,采用不污染全局对象模式去polyfill。适合开发第三方类库使用。

小知识:凡是前缀以@babel/preset-的开头的预设都可以用缩写形式进行配置,上面看到的预设是缩写形式。@babel/preset-env预设大幅度简化了配置,不需要再配置es2015,es2017预设什么的,也不再需要配置一大堆插件,自动采用最新的语法,并且按需引入。
plugins的执行顺序是顺序执行,而presets的执行顺序是倒序执行,如同webpack里的loader一样。`

@babel/preset-env中重要选项

{
  "presets": [
    [
      "env",
      {
        "targets": "> 5%",
        "useBuiltIns": "usage",
        "corejs": 3
      }
    ]
  ]
}
  1. targets
    babel根据目标平台来编译

    {
        "targets": "> 0.25%, not dead"
    }
    // or
    {
        "targets": {
            "chrome": "58",
            "ie": "11"
        }
    }
    

    环境可以指定:chrome, opera, edge, firefox, safari, ie, ios, android, node, electron.

    推荐将该平台配置,写在 .browserslistrc 或者 package.json中,这样所有包都可以共享。

  2. useBuiltIns
    这个选项用来告诉@babel/preset-env如何处理polyfills,具有以下几个参数:

    • usage 按需引用,根据编译目标以及实际使用情况按需导入polyfills。
    • false 不引入,由用户自己决定引入部分。
    • entry 在核心入口文件中使用 import '@babel/polyfill' 语句引入,并不推荐,引入的包可能含有自己并不需要的东西。

  3. corejs
    仅当与 useBuiltIns: usageuseBuiltIns: entry 一起使用时才有效,可以指定corejs版本 2 | 3,建议使用3,2对于最新新增的polyfill不支持。

其他选项见官网

创建自己的预设

可以为自己公司或团队创建预设:

// index.js
module.exports = {
  presets: [
    require("@babel/preset-es2015"),
    require("@babel/preset-react")
  ],
  plugins: [
    require("@babel/plugin-transform-flow-strip-types")
  ]
};
// package.json
{
  "name": "@babel/preset-my-awesome-preset",
  "version": "1.0.0",
  "author": "James Kyle <me@thejameskyle.com>",
  "dependencies": {
    "@babel/preset-es2015": "^7.0.0",
    "@babel/preset-react": "^7.0.0",
    "@babel/plugin-transform-flow-strip-types": "^7.0.0"
  }
}

然后将这个包发布到npm上,就能安装使用自己的预设了

npm install @babel/preset-my-awesome-preset -D

关于@ babel / polyfill

@babel/polyfill 是对 core-js 的封装,引入该模块时,实际是引用了 core-js,以及regenerator-runtime。自Babel 7.4.0开始,官方已不推荐使用此软件包。

import "@babel/polyfill";

上下两种是等价写法

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

对于绝大部分情况,使用 @babel/preset-env + useBuiltIns: ‘usage’ 选项是最好的选择。

其他环境中使用

vue
vue 环境没有提供外部使用的preset,其@vue/babel-preset-app也是基于vue-cli的。如果是用vue-cli,只需在babel的配置文件中配置即可。

react

module.exports = {
  "presets": ["@babel/preset-react"]
}

typescript

module.exports = {
  "presets": ["@babel/preset-typescript"]
}

然后配置tsconfig.json,具体配置项见ts官网


附录

下面列出一些插件与预设仅供参考:

预设

省略包前缀@babel/preset-如下:

  • env   集合了最新的javascript的预设,以及polyfill,

  • es2015   es2015插件集合

  • react   react插件预设

  • stage-x   es所在阶段的提案语法

  • typescript   ts的预设

转换插件

省略包前缀@babel/plugin-transform 如下:

ES3

  • member-expression-literals
  • property-literals
  • reserved-words

ES5

  • property-mutators

ES2015

  • arrow-functions
  • block-scoped-functions
  • block-scoping
  • classes
  • computed-properties
  • destructuring
  • duplicate-keys
  • for-of
  • function-name
  • instanceof
  • literals
  • new-target
  • object-super
  • parameters
  • shorthand-properties
  • spread
  • sticky-regex
  • template-literals
  • typeof-symbol
  • unicode-escapes
  • unicode-regex

ES2016

  • exponentiation-operator

ES2017

  • async-to-generator

ES2018

  • async-generator-functions
  • dotall-regex
  • named-capturing-groups-regex
  • object-rest-spread
  • optional-catch-binding
  • unicode-property-regex

Experimental

  • class-properties
  • decorators
  • do-expressions
  • export-default-from
  • export-namespace-from
  • function-bind
  • function-sent
  • logical-assignment-operators
  • nullish-coalescing-operator
  • numeric-separator
  • optional-chaining
  • partial-application
  • pipeline-operator
  • private-methods
  • throw-expressions
  • private-property-in-object

各个插件的具体用法见官网

关于babel的分享到此结束 😃

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值