const babel = require("@babel/core"); const fs = require("fs"); const path = require("path"); const t = babel.types; const dirs = fs .readdirSync(path.join(__dirname, "../src/components")) .filter((file) => file.startsWith("Dage")); /** * @type {{[name: string]: string[]}} */ const mapper = {}; const extensions = [".ts", ".tsx"]; const findFile = (file) => { if (fs.existsSync(file)) { if (fs.statSync(file).isDirectory()) { return findFile(path.join(file, "index")); } return file; } for (const ext of extensions) { const f = `${file}${ext}`; if (fs.existsSync(f)) { return f; } } return null; }; const walk = (context, entry) => { const base = path.basename(context); const addMapper = (name) => { mapper[base] = mapper[base] || []; mapper[base].push(name); }; /** * @type {import('@babel/core').PluginObj} */ const plugin = { visitor: { ExportNamedDeclaration(path) { const decl = path.node.declaration; if (t.isVariableDeclaration(decl)) { decl.declarations.forEach((i) => { if (t.isIdentifier(i.id)) { addMapper(i.id.name); } }); } else if ( (t.isFunctionDeclaration(decl) || t.isTSInterfaceDeclaration(decl) || t.isTSTypeAliasDeclaration(decl) || t.isTSEnumDeclaration(decl) || t.isClassDeclaration(decl)) && t.isIdentifier(decl.id) ) { addMapper(decl.id.name); } else if (path.node.specifiers?.length) { path.node.specifiers.forEach((i) => { addMapper(i.exported.name); }); } }, ExportAllDeclaration(p) { // 递归 if (p.node.source.value.startsWith("./")) { const relativeEntry = findFile( path.join(path.dirname(entry), p.node.source.value) ); walk(context, relativeEntry); } }, }, }; babel.transformFileSync(entry, { root: path.join(__dirname, "../"), configFile: false, babelrc: false, parserOpts: { plugins: [ "decorators-legacy", "classProperties", "dynamicImport", "typescript", "jsx", ], }, plugins: [plugin], }); }; dirs.forEach((dir) => { const context = path.join(__dirname, "../src/components", dir); const entry = findFile(path.join(context, "index")); if (entry == null) { return; } walk(context, entry); }); fs.writeFileSync( path.join(__dirname, "../dist/metadata.json"), JSON.stringify(mapper, null, 2) );