@babel/cli入门

890 阅读3分钟

初始化一个项目

mkdir babeljs
cd babeljs
npm init -y

安装@babel/cli@babel/core

注意是开发依赖:

npm i -D @babel/cli @babel/core

按照官方的说法:如果不手动指定安装@babel/core,npx会安装babel6.x。

创建一个es6文件

cat <<EOF > 01.js
 const a = 0
 const b = '1'
 export { a }
 export default b
EOF

用npx跑一下

% npx babel 01.js      
const a = 0;
const b = '1';
export { a };
export default b;

很贴心,给每行都加了分号。

使用presets

安装一个大家都极为熟悉的npm包:@babel/preset-env

npm i -D @babel/preset-env

然后在npx指定加载这个preset:

% npx babel 01.js --presets=@babel/preset-env 
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports["default"] = exports.a = void 0;
var a = 0;
exports.a = a;
var b = '1';
var _default = b;
exports["default"] = _default;

就很熟悉的味道。

支持JSX

先改一下01.js的代码:

const a = 0
const b = '1'
const c = <h1>Hello</h1>
export { a, c }
export default b

注意新增了变量c,返回一个jsx节点。

如果我们还使用之前的编译命令,就会报错了,因为语法解析认为这是错误的js代码:

% npx babel 01.js --presets=@babel/preset-env                                   
SyntaxError: /Users/kema/git/exp2fun/babeljs/01.js: Support for the experimental syntax 'jsx' isn't currently enabled (3:11):

  1 | const a = 0
  2 | const b = '1'
> 3 | const c = <h1>Hello</h1>
    |           ^
  4 | export { a, c }
  5 | export default b
  6 |

Add @babel/preset-react (https://git.io/JfeDR) to the 'presets' section of your Babel config to enable transformation.

按照提示,安装@babel/preset-react并执行:

 npx babel 01.js --presets=@babel/preset-env,@babel/preset-react
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports["default"] = exports.c = exports.a = void 0;
var a = 0;
exports.a = a;
var b = '1';
# 所以页面顶部要先 import React from 'react'
var c = /*#__PURE__*/React.createElement("h1", null, "Hello");
exports.c = c;
var _default = b;
exports["default"] = _default;

可以看到,这里的变量c被转成了react组件。

顾名思义,@babel/preset-react是转react组件,你猜有没有@babel/preset-vue

jsx -> vue

有但不叫这个名字,而是@vue/babel-preset-jsx:

npm i -D @vue/babel-preset-jsx

期待一下吧:

% npx babel 01.js --presets=@babel/preset-env,@vue/babel-preset-jsx
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports["default"] = exports.c = exports.a = void 0;
var a = 0;
exports.a = a;
var b = '1';
var c = h("h1", ["Hello"]);
exports.c = c;
var _default = b;
exports["default"] = _default;

完美。

通过上面的几个小栗子能看到,在不同preset的加持下,jsx可以转成不同框架下的组件。

来看一下jsx在react下的完整形态:

import React from 'react'
const a = 0
const b = '1'
const c = <h1>Hello</h1>
export { a, c }
export default b
% npx babel 01.js --presets=@babel/preset-env,@babel/preset-react  
"use strict";

Object.defineProperty(exports, "__esModule", {
  value: true
});
exports["default"] = exports.c = exports.a = void 0;

var _react = _interopRequireDefault(require("react"));

function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; }

var a = 0;
exports.a = a;
var b = '1';

var c = /*#__PURE__*/_react["default"].createElement("h1", null, "Hello");

exports.c = c;
var _default = b;
exports["default"] = _default;

plugins

babel的插件原理和使用还是很好理解的,而且官方插件就很丰富。日常的话,当伸手党就可以。

这里拿一个官方插件@babel/plugin-proposal-decorators简单做个例子:

// 02.js
@annotation
class MyClass {}

function annotation(target) {
  target.annotated = true;
}

配置插件的时候,插件参数通过命令行就不好去配置了,所以这里我们用.babelrc来配置转换插件及参数:

{
  "plugins": [
    [
      "@babel/plugin-proposal-decorators",
      {
        "decoratorsBeforeExport": true
      }
    ]
  ]
}

编译

% npx babel 02.js

转出来的代码很多,基本上都是polyfill的操作。

当然也可以配合presets参数使用

npx babel 02.js --presets=@babel/preset-env

转成es5,node就可以直接用了。

more

更多配置项说明,请见官方文档