Skip to content

babel 插件

上节课补充:@babel/polyfill 已过时,目前被core-jsgenerator-runtime所取代

除了预设可以转换代码之外,插件也可以转换代码,它们的顺序是:

  • 插件在 Presets 前运行。
  • 插件顺序从前往后排列。
  • Preset 顺序是颠倒的(从后往前)。

通常情况下,@babel/preset-env只转换那些已经形成正式标准的语法,对于某些处于早期阶段、还没有确定的语法不做转换。

如果要转换这些语法,就要单独使用插件

下面随便列举一些插件

@babel/plugin-proposal-class-properties

该插件可以让你在类中书写初始化字段

js
class A {
  a = 1;
  constructor() {
    this.b = 3;
  }
}

@babel/plugin-proposal-function-bind

该插件可以让你轻松的为某个方法绑定 this

js
function Print() {
  console.log(this.loginId);
}

const obj = {
  loginId: "abc",
};

obj::Print(); //相当于:Print.call(obj);

遗憾的是,目前 vscode 无法识别该语法,会在代码中报错,虽然并不会有什么实际性的危害,但是影响观感

@babel/plugin-proposal-optional-chaining

该插件支持安全访问的链式调用。

js
const obj = {
  foo: {
    bar: {
      baz: 42,
    },
  },
};

//这样访问及其不安全,因为可能是后端返回的数据,容易产生系统报错
if (obj.foo.bar.baz) {
  //xxx
}

const baz = obj?.foo?.bar?.baz; // 42

const safe = obj?.qux?.baz; // undefined

babel-plugin-transform-remove-console

该插件会移除源码中的控制台输出语句,一般我们会配置在生产环境的依赖中

js
console.log("foo");
console.error("bar");

@babel/plugin-transform-runtime

用于提供一些公共的 API,这些 API 会帮助代码转换

例如

index.js

js
class A {
  method() {}
}

a.js

js
class B {
  method() {}
}

编译后的结果:

js
"use strict";

require("core-js/modules/es.symbol.js");
require("core-js/modules/es.symbol.description.js");
require("core-js/modules/es.symbol.iterator.js");
require("core-js/modules/es.array.iterator.js");
require("core-js/modules/es.object.to-string.js");
require("core-js/modules/es.string.iterator.js");
require("core-js/modules/web.dom-collections.iterator.js");
require("core-js/modules/es.symbol.to-primitive.js");
require("core-js/modules/es.date.to-primitive.js");
require("core-js/modules/es.number.constructor.js");

//这段代码在编译出的index和a文件都存在,目的就是想办法提取出去
/*
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); }
function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } }
function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; }
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
*/

var B = /*#__PURE__*/ (function () {
  function B() {
    _classCallCheck(this, B);
  }
  return _createClass(B, [
    {
      key: "method",
      value: function method() {},
    },
  ]);
})();

配置上插件后编译:

js
"use strict";

//就变成了依赖一个@babel/runtime的库,将该依赖下载即可
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
var _classCallCheck2 = _interopRequireDefault(
  require("@babel/runtime/helpers/classCallCheck")
);
var _createClass2 = _interopRequireDefault(
  require("@babel/runtime/helpers/createClass")
);

var B = /*#__PURE__*/ (function () {
  function B() {
    (0, _classCallCheck2.default)(this, B);
  }
  return (0, _createClass2.default)(B, [
    {
      key: "method",
      value: function method() {},
    },
  ]);
})();

.babelrc配置文件

json
//babel同postcss一样,只是将文件进行了编译,具体转换的事交给插件去做。
{
  //预设
  "presets": [
    //可填写插件的参数,['插件名',{'插件配置项':''}]
    [
      "@babel/preset-env",
      {
        "useBuiltIns": "usage",
        "corejs": 3
      }
    ]
  ],
  //插件
  "plugins": [
    [
      "@babel/plugin-proposal-class-properties",
      {
        // "loose": true
      }
    ],
    "@babel/plugin-proposal-function-bind",
    "@babel/plugin-proposal-optional-chaining",
    "babel-plugin-transform-remove-console", //可以简写为transform-remove-console
    "@babel/plugin-transform-runtime" //可以简写为@babel/transform-runtime
  ]
}

MIT License