Appearance
这里,我们自己来实现一个 Bebel 插件,来转换 Await 使其捕获异常。
Bebel
Await
主要是利用 @babel/core 库的 transform 方法,还有 @babel/types 库的 identifier, blockStatement, catchClause, tryStatement
transform
identifier
blockStatement
catchClause
tryStatement
@babel/core
@babel/types
xxx
{ xxxx }
catch (xxx) { xxx }
try { xxx } catch (xxx) { xxx }
async function func() { await asyncFn() }
async function func() { try { await asyncFn() } catch (e) { console.log(e) } }
import { identifier, blockStatement, catchClause, tryStatement } from '@babel/types' import { transform } from '@babel/core' import { parse } from '@babel/parser' import { default as chalk } from 'chalk' import { log } from '@common/index' import { FunctionDeclaration } from '@babel/types' import { PluginItem, BabelFileResult, NodePath } from '@babel/core' const transformAsyncAwaitPlugin = (): PluginItem => { return { visitor: { FunctionDeclaration(path: NodePath<FunctionDeclaration>) { // Node: async function func() { await asyncFn(); } const { node } = path // Edentifier: e const catchParam = identifier('e') // BlockStatement: console.log(e); const catchBlock = blockStatement([parse('console.log(e);').program.body[0]]) // CatchClause: catch (e) { console.log(e); } const catchHandler = catchClause(catchParam, catchBlock) const tryCatchBlock = tryStatement(node.body, catchHandler) path.replaceWith(tryCatchBlock) }, }, } } /** * try/catch an exception for async/await * * @param code async function func() { await asyncFn(); } * @returns async function func() { try { await asyncFn(); } catch(e) { console.log(e); } } */ const transformAsyncAwait = ( code = `async function func() { await asyncFn();}`, ): string | null | undefined => { log(chalk.green.bold('old =>')) log(code) const data: BabelFileResult | null = transform(code, { plugins: [transformAsyncAwaitPlugin()], }) /** * 转换后 * async function func() { * try { * await asyncFn(); * } catch (e) { * console.log(e); * } * } */ log(chalk.red.bold('New =>')) log(data?.code) return data?.code } export default transformAsyncAwait export { transformAsyncAwaitPlugin }