refactor: simplify components registration

This commit is contained in:
MuhammadM1998 2024-05-04 13:04:15 +03:00
parent 952793f11a
commit 9c0b50c523

View File

@ -1,7 +1,4 @@
import { readFileSync, readdirSync } from 'node:fs' import { createResolver, defineNuxtModule } from '@nuxt/kit'
import { join } from 'node:path'
import { addComponent, createResolver, defineNuxtModule } from '@nuxt/kit'
import { parseSync } from '@oxc-parser/wasm'
// TODO: add test to make sure all registry is being parse correctly // TODO: add test to make sure all registry is being parse correctly
// Module options TypeScript interface definition // Module options TypeScript interface definition
@ -29,52 +26,16 @@ export default defineNuxtModule<ModuleOptions>({
async setup({ prefix, componentDir }, nuxt) { async setup({ prefix, componentDir }, nuxt) {
const COMPONENT_DIR_PATH = componentDir! const COMPONENT_DIR_PATH = componentDir!
const ROOT_DIR_PATH = nuxt.options.rootDir const ROOT_DIR_PATH = nuxt.options.rootDir
const { resolve, resolvePath } = createResolver(ROOT_DIR_PATH) const { resolve } = createResolver(ROOT_DIR_PATH)
// --- Register components --- // Register components
// Tell Nuxt to not scan `componentsDir` for auto imports as we will do it manually const componentsPath = resolve(COMPONENT_DIR_PATH)
nuxt.hook('components:dirs', (dirs) => { nuxt.hook('components:dirs', (dirs) => {
dirs.unshift({ dirs.unshift({
path: resolve(COMPONENT_DIR_PATH), path: componentsPath,
extensions: [], extensions: ['.vue'], // Scan `.vue` only and skip `.ts` files as we use them inside components file only
prefix,
}) })
}) })
// Manually scan `componentsDir` for components and register them for auto imports
try {
readdirSync(resolve(COMPONENT_DIR_PATH))
.forEach(async (dir) => {
try {
const filePath = await resolvePath(join(COMPONENT_DIR_PATH, dir, 'index'), { extensions: ['.ts', '.js'] })
const content = readFileSync(filePath, { encoding: 'utf8' })
const ast = parseSync(content, {
sourceType: 'module',
sourceFilename: filePath,
})
const exportedKeys: string[] = ast.program.body
.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) {
if (err instanceof Error)
console.warn(err.message)
}
}, },
}) })