1. 解析 JSX 文件的插件

jsx-praser.js

  1. module.exports = function () {
  2. return {
  3. manipulateOptions: function manipulateOptions(opts, parserOpts) {
  4. parserOpts.plugins.push("jsx");
  5. }
  6. };
  7. };

2. 转换 JSX => React.createElement

它的实现原理是这样的。Babel 读取代码并解析,生成 AST,再将 AST 传入插件层进行转换,在转换时就可以将 JSX 的结构转换为 React.createElement 的函数。如下代码所示:

jsx-plugin.js

  1. module.exports = function (babel) {
  2. var t = babel.types;
  3. return {
  4. name: "custom-jsx-plugin",
  5. visitor: {
  6. JSXElement(path) {
  7. var openingElement = path.node.openingElement;
  8. var tagName = openingElement.name.name;
  9. var args = [];
  10. args.push(t.stringLiteral(tagName));
  11. var attribs = t.nullLiteral();
  12. args.push(attribs);
  13. var reactIdentifier = t.identifier("React"); //object
  14. var createElementIdentifier = t.identifier("createElement");
  15. var callee = t.memberExpression(reactIdentifier, createElementIdentifier)
  16. var callExpression = t.callExpression(callee, args);
  17. callExpression.arguments = callExpression.arguments.concat(path.node.children);
  18. path.replaceWith(callExpression, path.node);
  19. },
  20. },
  21. };
  22. };

3. .babelrc

  1. {
  2. "plugins": ["jsx-plugin", "./jsx-parser"]
  3. }

4. 编译

  1. function Test() {
  2. return <div><a>Hello~~~</a></div>
  3. }
  1. babel hello.jsx

References