当下,每个写 JavaScript 的猿可能都在或多或少地使用 Babel。借助 Babel,我们可以使用最新的 ECMAScript 特性,而不用太关注浏览器支持。Babel 在背后进行了许多复杂的转换,我们要做的,就是写配置文件,告诉 Babel 我们想要什么。下面就来看看一些配置技巧吧。
在 .babelrc
中使用 JS
All Babel API options except the callbacks are allowed (because .babelrc
files are serialized as JSON5
).
Babel 使用 JSON5 解析 .babelrc
,也就是说可以在 .babelrc
中使用宽松的语法,可以添加注释什么的,不过,真的可以像 ESLint 的 .eslintrc.js
直接使用 JS 配置吗?截止目前的最新版本(Babel 6),并不会解析 .babelrc.js
之类的文件,不过可以变通一下。
首先,建一个 .babelrc.js
文件:
const ES = process.env.BABEL_ENV === 'es' module.exports = { presets: [ [ 'env', { modules: !ES } ], 'react', 'stage-2', ], };
接下来,再建一个 Babel 认识的 .babelrc
文件:
{ "presets": ["./.babelrc.js"] }
或者,嫌多一个文件麻烦的话,加在 package.json
里面也没问题:
{ "babel": { "presets": [ "./.babelrc.js" ] } }
通过 JS 编写配置文件,不仅可以给一些参数复杂的插件传递正则、函数等参数,还可以根据环境变量设置不同的参数,产出不同的代码。
减少冗余代码
babel-plugin-transform-runtime
以下面的源代码为例:
class Person { constructor(options) { this.options = Object.assign({}, Person.DEAULTS, options); } sayHi() { return `Hi, this is ${this.options.name}`; } } Person.DEAULTS = { name: 'anonymous', };
.babelrc
配置为:
{ "presets": [ "es2015" ], "plugins": ["transform-object-assign"] }
转换后的代码为:
'use strict'; var _extends = Object.assign || function (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; }; var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } var Person = function () { function Person(options) { _classCallCheck(this, Person); this.options = _extends({}, Person.DEAULTS, options); } _createClass(Person, [{ key: 'sayHi', value: function sayHi() { return 'Hi, this is ' + this.options.name; } }]); return Person; }(); Person.DEAULTS = { name: 'anonymous' };
就是说,如果源代码中有 10 个类似的模块,就会有 10 份重复的 _extends
、 _createClass
、 _classCallCheck
代码分布在各个文件中,太多冗余。通过 babel-plugin-transform-runtime
可以有效解决这一问题。
安装并配置 Runtime transform 插件:
{ "presets": [ "es2015" ], "plugins": [ "transform-object-assign", "transform-runtime" ] }
转换出来的代码会引用公共的模块,干净多了:
'use strict'; var _extends2 = require('babel-runtime/helpers/extends'); var _extends3 = _interopRequireDefault(_extends2); var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck'); var _classCallCheck3 = _interopRequireDefault(_classCallCheck2); var _createClass2 = require('babel-runtime/helpers/createClass'); var _createClass3 = _interopRequireDefault(_createClass2); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } var Person = function () { function Person(options) { (0, _classCallCheck3.default)(this, Person); this.options = (0, _extends3.default)({}, Person.DEAULTS, options); } (0, _createClass3.default)(Person, [{ key: 'sayHi', value: function sayHi() { return 'Hi, this is ' + this.options.name; } }]); return Person; }(); Person.DEAULTS = { name: 'anonymous' };
记得把 babel-runtime
也加到依赖中。如果需进一步定制,可 参考官方文档
。
生产环境中移除 React PropTypes 定义
React PropTypes 定义可以在开发时帮助我们校验传入的属性,但在构建生产环境代码时,完全可以移除,以减小文件体积,节省宽带。 babel-plugin-transform-react-remove-prop-types 就是干这事的,具体参见文档,不再赘述。
注:本文内容来自互联网,旨在为开发者提供分享、交流的平台。如有涉及文章版权等事宜,请你联系站长进行处理。