使用ES6

本文共--字 阅读约--分钟 | 浏览: -- Last Updated: 2021-02-26

通常问需要将采用ES6编写的代码转换成目前已经支持良好的ES5代码,包含如下两件事:

  • 将新的 ES6语法使用 ES5实现,例如class语法使用prototype实现。
  • 为新的 API注入 polyfill,例如使用新的 fetchAPI时在注入对应的 polyfill后才能让低端浏览器正常运行。

Babel可以方便地完成以上两件事情,在Babel执行编译的过程中,会从项目根目录下的.babelrc文件中读取配置,内容大致如下:

{
  "plugin": [
    [
      "transform-runtime",
      {
        "polyfill": false
      }
    ]
  ],
  "presets": [
    [
      "es2015",
      {
        "modules": false
      }
    ],
    "stage-2",
    "react"
  ]
}

Plugins

plugins属性告诉Babel要使用哪些插件,这些插件可以控制如何转换代码。

上例使用到的babel-plugin-transform-runtime (包名会在前面加上babel-plugin-)的作用是减少冗余的代码,因为Babel在将 ES6代码转换成ES5代码时,通常需要一些由ES5 编写的辅助函数来完成新语法的实现,例如在转换class extends 语法时会在转换后的ES5 代码里注入extend 辅助函数用于实现继承。

function _extend(target) {
  for (var i = 1; i < arguments.length; i++) {
    var source = arguments[i];
    for (var key in source) {
      if (Object.prototype.hasOwnProperty.call(source, key)) {
        target[key] = source[key];
      }
    }
  }
  return target;
}

这会导致每个使用class extends 语法的文件都被注入重复的_extend辅助函数代码,babel-plugin-transform-runtime 的作用在于将原本注入JavaScript 文件里的辅助函数替换成一条导入语句,这样能减小Babel 编译出来的代码的文件大小。

var extend= require ('babel-runtime/helpers/_extend');

由于babel-plugin-transform-runtime 注入了require ('babel-runtime/helpers/_extend')语句到编译后的代码里,需要安装babel-runtime 依赖到我们的项目后,代码才能正常运行。也就是说babel-plugin-transform-runtimebabel-runtime 需要配套使用。

Presets

presets 属性告诉Babel 要转换的源码使用了哪些新的语法特性,一个Presets对一组新语法的特性提供了支持,多个Presets 可以叠加。

Presets 其实是一组 Plugins的集合,每个Plugin完成一个新语法的转换工作,Presets是按照 ECMAScript草案来组织的,通常分为三类;

  1. 已写入 ECMAScript标准的,例如 ES2015ES2016ES2017EnvEnv包含当前所有ECMAScript标准的最新特性);

  2. 被社区提出还未写入标准,比如stage0(美好激进的想法,一些插件支持,但是不确定是否会成为标准)、stage1(值得被纳入标准的特性)、stage2(已经被起草,将被纳入标准)、stage3(已经定稿,各大浏览器厂商和Node.js社区已开始着手实现);

  3. 用于支持一些特定应用场景下的语法的特性,例如babel-presets-react用于支持 React开发里的JSX语法;

接入Babel

# 依赖的babel模块
npm i -D babel-core babel-loader

# 根据需求选择不同的Plugins 或 Presets
npm i -D babel-presets-env
// webpack.config.js

module.exports = {
  module: {
    rules: [
      {
        test: /\.js$/,
        use: ['babel-loader'],
      },
    ],
  },
  // 输出source-map以方便调试ES6源码
  devtool: 'source-map'
}