All files / utils isFileContainExport.ts

96% Statements 24/25
66.67% Branches 4/6
85.71% Functions 6/7
96% Lines 24/25

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 684x 4x 4x 4x 4x 4x         4x 20x 20x 40x           20x 20x 20x 20x   16x               13x             5x 3x           1x 1x           1x         5x     13x   7x        
import { parseSync } from "@babel/core";
import { resolve } from "path";
import traverse from "@babel/traverse";
import * as t from "@babel/types";
import * as path from "path";
import { readFileSync } from "fs";
 
// https://github.com/layne0625/auto-export-plugin/blob/master/index.js
// path must be absolute
// not throw anything to make sure it work correctly with promise.all
export const isFileContainExport = ({
  fileName,
  destinationPath,
  babelConfigPath = resolve(process.cwd(), "./.babelrc")
}: {
  destinationPath: string;
  fileName: string;
  babelConfigPath?: string;
}): Promise<string | null> => {
  return new Promise(resolve => {
    try {
      const filePath = path.resolve(destinationPath, fileName);
      const fileContent = readFileSync(filePath).toString();
 
      const ast = parseSync(fileContent, {
        sourceType: "module",
        filename: fileName,
        configFile: babelConfigPath
      });
 
      // this thing run synchoronously
      // @ts-ignore
      traverse(ast, {
        ExportAllDeclaration() {
          resolve(fileName);
        },
        // 主要处理export const a = 1这种写法
        ExportNamedDeclaration(path) {
          // 考虑到一个文件中可能变量声明语法较多但不一定是export,所以对于`export const a = 1`这种写法,没有采用像其他3种方式一样单独对类型做处理,而是在ExportNamedDeclaration中进一步做判断并处理
          if (t.isVariableDeclaration(path.node.declaration)) {
            resolve(fileName);
          }
        },
 
        // 处理 export function getOne(){}写法
        FunctionDeclaration(path) {
          Eif (t.isExportNamedDeclaration(path.parent)) {
            resolve(fileName);
          }
        },
 
        // 处理const A = 1; export { A }这种写法
        ExportSpecifier() {
          resolve(fileName);
        },
 
        // 处理export default写法, 如果是export default会用文件名作为变量名
        ExportDefaultDeclaration() {
          resolve(fileName);
        }
      });
      resolve(null);
    } catch (error) {
      resolve(null);
    }
  });
};