From 228b0b970ef41f27138d89d0a248f41aa00ef987 Mon Sep 17 00:00:00 2001 From: zernonia Date: Fri, 12 Jan 2024 10:11:33 +0800 Subject: [PATCH] feat: use oxc-parser to get ExportNamedDeclaration node --- packages/module/src/module.ts | 46 +++++++++++++++++++++-------------- 1 file changed, 28 insertions(+), 18 deletions(-) diff --git a/packages/module/src/module.ts b/packages/module/src/module.ts index 0900f31c..e854aab0 100644 --- a/packages/module/src/module.ts +++ b/packages/module/src/module.ts @@ -1,7 +1,7 @@ import { readFileSync, readdirSync } from 'node:fs' import { join } from 'node:path' import { addComponent, createResolver, defineNuxtModule } from '@nuxt/kit' -import { parse } from 'recast' +import oxc from 'oxc-parser' // Module options TypeScript interface definition export interface ModuleOptions { @@ -40,24 +40,34 @@ export default defineNuxtModule({ try { readdirSync(resolve(COMPONENT_DIR_PATH)) .forEach(async (dir) => { - const filePath = await resolvePath(join(COMPONENT_DIR_PATH, dir, 'index'), { extensions: ['.ts', '.js'] }) - const content = readFileSync(filePath, { encoding: 'utf8' }) - const ast = parse(content) - - const exportedKeys: string[] = ast.program.body - // @ts-expect-error parse return any - .filter(node => node.type === 'ExportNamedDeclaration') - // @ts-expect-error parse return any - .flatMap(node => node.specifiers.map(specifier => specifier.exported.name)) - .filter((key: string) => /^[A-Z]/.test(key)) - - exportedKeys.forEach((key) => { - addComponent({ - name: `${prefix}${key}`, // name of the component to be used in vue templates - export: key, // (optional) if the component is a named (rather than default) export - filePath: resolve(filePath), + try { + const filePath = await resolvePath(join(COMPONENT_DIR_PATH, dir, 'index'), { extensions: ['.ts', '.js'] }) + const content = readFileSync(filePath, { encoding: 'utf8' }) + const ast = oxc.parseSync(content, { + sourceType: 'module', + sourceFilename: filePath, }) - }) + const program = JSON.parse(ast.program) + + const exportedKeys: string[] = program.body + // @ts-expect-error parse return any + .filter(node => node.type === 'ExportNamedDeclaration') + // @ts-expect-error parse return any + .flatMap(node => node.specifiers.map(specifier => specifier.exported.name)) + .filter((key: string) => /^[A-Z]/.test(key)) + + exportedKeys.forEach((key) => { + addComponent({ + name: `${prefix}${key}`, // name of the component to be used in vue templates + export: key, // (optional) if the component is a named (rather than default) export + filePath: resolve(filePath), + }) + }) + } + catch (err) { + if (err instanceof Error) + console.warn('Module error: ', err.message) + } }) } catch (err) {