likes
comments
collection
share

babel 所有函数转成带 try catch包裹下

作者站长头像
站长
· 阅读数 17

使用babel 对所有函数都转成 带 try catch包裹下

其实再很久之前就看到过这篇如何给所有的async函数添加try/catch? 当时看完后表示很强!!!!

咱们今天就实现简易版本的携带 try、catch函数包裹的 babel脚本 。

第一步初始化环境 引入依赖代码如下

下面是一个标准的babel转成ats再到生成code代码 就不过多解释了。 咱们需要做的是把函数转成带try、catch包裹的

import * as parser from '@babel/parser';
import traverse from '@babel/traverse';
import generate from '@babel/generator';
import template from '@babel/template';
import * as types from '@babel/types';


const code = `
function test1() {
  const a = 1;
  const b = 2;
  return a + b;
}

function test2() {
  const a = 1;
  const b = 2;
}
`
const ast = parser.parse(code, {
  sourceType: 'unambiguous',
});

console.log(generate(ast).code);

第二步 利用traverseast 进行改造

traverse ast=>修改过的ast

使用template 创建模板code如下(假如尼对template比较熟悉应该能知道我要干啥了):

import template from '@babel/template';

const tryTemp = template(`
{
  try {
    NODE_TEMPLATE
  } catch (error) {
    console.log(NODE_NAME,error)
  }
}
`);

再然后

path.skip() 替换完成后一定要跳出循环,不然就会陷入死循环了。

import traverse from '@babel/traverse';

traverse(ast, {
  FunctionDeclaration(path) { // 函数声明  所有的ast函数声明都会进这里面
    path.node.body = tryTemp({ // 把函数的body 替换成咱们try、catch包裹的
      NODE_TEMPLATE: path.node.body.body,
      NODE_NAME: types.stringLiteral(`[function ${path.node.id.name}]:`),
    });
    path.skip(); // 略过
  },
});

完整代码

import * as parser from '@babel/parser';
import traverse from '@babel/traverse';
import generate from '@babel/generator';
import template from '@babel/template';
import * as types from '@babel/types';


const code = `
function test1() {
  const a = 1;
  const b = 2;
  return a + b;
}

function test2() {
  const a = 1;
  const b = 2;
}
`


const tryTemp = template(`
{
  try {
    NODE_TEMPLATE
  } catch (error) {
    console.log(NODE_NAME,error)
  }
}
`);

const ast = parser.parse(code, {
  sourceType: 'unambiguous',
});


traverse(ast, {
  FunctionDeclaration(path) {
    path.node.body = tryTemp({
      NODE_TEMPLATE: path.node.body.body,
      NODE_NAME: types.stringLiteral(`[function ${path.node.id.name}]:`),
    });
    path.skip();
  },
});

console.log(generate(ast).code);

运行后输出如下

$ yarn log:try
yarn run v1.22.19
$ node ./dist/try.js
function test1() {
  try {
    const a = 1;  
    const b = 2;  
    return a + b; 
  } catch (error) {
    console.log("[function test1]:", error);
  }
}
function test2() {
  try {
    const a = 1;
    const b = 2;
  } catch (error) {
    console.log("[function test2]:", error);
  }
}
Done in 1.65s.

总结

就是简单用try、catch包裹了下函数,没有考虑那么全面就基本实现了包裹,好像也没有实质性的用途。当练习挺好的。