auto-inject-async-catch-loader

    1.0.8 • Public • Published

    auto-inject-async-catch-loader 🚀

    auto-inject-async-catch-loader 是一个 webpack-loader,基于 babel 提供的 tool 来通过遍历抽象语法树 AST 来实现对 AwaitExpression AST 节点添加 TryStatement AST 节点,从而完成对 async function自动注入 try catch 的机制。

    基础配置可以看 async-catch 讲解或者源码定义。在它的基础上,我做了以下两点优化:

    1.优化了向上查找 parent 的过程,优化后的 traverse 如下所示:

    traverse(ast, {
        AwaitExpression(path) {
          // 已经包含 try 语句则直接退出
          if (
            path.findParent(path => t.isTryStatement(path.node))
          ) {
            return;
          }
          // 查找最外层的 async 语句
          const blockParent = path.findParent(path => t.isBlockStatement(path.node) && isAsyncFuncNode(path.parentPath.node))
          const tryCatchAst = t.tryStatement(
            blockParent.node,
            t.catchClause(
              t.identifier(options.identifier),
              t.blockStatement(catchNode)
            ),
            finallyNode && t.blockStatement(finallyNode)
          )
          blockParent.replaceWithMultiple([tryCatchAst])
        }
      });

    2.支持使用 TypeScript + Vue 开发的情况,此时的 async function 的 type 为 ClassMethod,所以在 isAsyncFunction 判断函数中加了对 ClassMethod 的判断:

    const isAsyncFuncNode = node =>
      t.isFunctionDeclaration(node, {
        async: true
      }) ||
      t.isArrowFunctionExpression(node, {
        async: true
      }) ||
      t.isFunctionExpression(node, {
        async: true
      }) ||
      t.isObjectMethod(node, {
        async: true
      }) ||
      t.isClassMethod(node, {
        async: true
      });

    下面,我们讲讲在实际 Vue 项目中要怎么使用~

    在 Vue-CLI (3.x及以上) 中使用

    1. 使用 JavaScript 开发

    使用 JavaScirpt 开发的同学只需要通过 chainwebpack 选项在 js rule 中添加一个 loader 就行。在 vue.config.js 的 chainWepack 中加入如下配置:

    chainWepack: (config) => {
      const jsRule = config.module.rule("js");
      jsRule
        .use("auto-inject-async-catch-loader")
        .loader("auto-inject-async-catch-loader")
        .end()
    }

    2. 使用 TypeScript 开发

    使用 TypeScript 开发的同学需要重写整个 ts rule 的 loader 配置。在 vue.config.js 的 chainWepack 中加入如下配置:

    chainWebpack: (config) => {
      const tsRule = config.module.rule("ts");
      tsRule.uses.clear();
      tsRule
        .use("cache-loader")
          .loader("cache-loader")
          .end()
        .use("babel-loader")
          .loader("babel-loader")
          .end()
        .use("auto-inject-async-catch-loader")
          .loader("auto-inject-async-catch-loader")
          .tap(() => {
            return {
              catchCode: 'console.error(e)'
            }
          })
          .end()
        .use("ts-loader")
          .loader("ts-loader")
          .tap(() => {
            return {
                      transpileOnly: true,
                      appendTsSuffixTo: [
                        '\\.vue$'
                      ],
                      happyPackMode: false
                    }
          })
          .end()
    }

    Install

    npm i auto-inject-async-catch-loader

    DownloadsWeekly Downloads

    2

    Version

    1.0.8

    License

    MIT

    Unpacked Size

    12.6 kB

    Total Files

    16

    Last publish

    Collaborators

    • wjchumble