refactor: use plugin

This commit is contained in:
Julien Huang 2024-09-03 21:26:35 +02:00
parent 38e9e8caf7
commit be2a31a029
3 changed files with 48 additions and 6 deletions

View File

@ -75,13 +75,9 @@ export const loaderPlugin = createUnplugin((options: LoaderOptions) => {
if (lazy) {
imports.add(genImport('vue', [{ name: 'defineAsyncComponent', as: '__defineAsyncComponent' }]))
identifier += '_lazy'
imports.add(`const ${identifier} = __defineAsyncComponent(${genDynamicImport(component.filePath, { interopDefault: false })}.then(c => ${options.defaultCompNameToAutoImport ? `Object.assign(c.${component.export ?? 'default'} || c, {name: (c.${component.export ?? 'default'} || c)?.name ?? ${JSON.stringify(component.pascalName)}})` : `c.${component.export ?? 'default'} || c`})${isClientOnly ? '.then(c => createClientOnly(c))' : ''})`)
imports.add(`const ${identifier} = __defineAsyncComponent(${genDynamicImport(component.filePath, { interopDefault: false })}.then(c => c.${component.export ?? 'default'} || c)${isClientOnly ? '.then(c => createClientOnly(c))' : ''})`)
} else {
imports.add(genImport(component.filePath, [{ name: component._raw ? 'default' : component.export, as: identifier }]))
if (options.defaultCompNameToAutoImport) {
imports.add(`const ${identifier}_dev = Object.assign(${identifier}, { name: (c.${component.export ?? 'default'} || c)?.name ?? ${JSON.stringify(component.pascalName)} })`)
identifier += '_dev'
}
if (isClientOnly) {
imports.add(`const ${identifier}_wrapped = createClientOnly(${identifier})`)
identifier += '_wrapped'

View File

@ -1,6 +1,6 @@
import fs, { statSync } from 'node:fs'
import { join, normalize, relative, resolve } from 'pathe'
import { addPluginTemplate, addTemplate, addTypeTemplate, addVitePlugin, addWebpackPlugin, defineNuxtModule, logger, resolveAlias, updateTemplates } from '@nuxt/kit'
import { addBuildPlugin, addPluginTemplate, addTemplate, addTypeTemplate, addVitePlugin, addWebpackPlugin, defineNuxtModule, logger, resolveAlias, updateTemplates } from '@nuxt/kit'
import type { Component, ComponentsDir, ComponentsOptions } from 'nuxt/schema'
import { distDir } from '../dirs'
@ -11,6 +11,7 @@ import { loaderPlugin } from './loader'
import { TreeShakeTemplatePlugin } from './tree-shake'
import { componentsChunkPlugin, islandsTransform } from './islandsTransform'
import { createTransformPlugin } from './transform'
import { nameDevPlugin } from './nameDev'
const isPureObjectOrString = (val: any) => (!Array.isArray(val) && typeof val === 'object') || typeof val === 'string'
const isDirectory = (p: string) => { try { return statSync(p).isDirectory() } catch { return false } }
@ -42,6 +43,12 @@ export default defineNuxtModule<ComponentsOptions>({
: context.components
}
if (nuxt.options.dev || nuxt.options.test) {
addBuildPlugin(nameDevPlugin({
components: getComponents,
}))
}
const normalizeDirs = (dir: any, cwd: string, options?: { priority?: number }): ComponentsDir[] => {
if (Array.isArray(dir)) {
return dir.map(dir => normalizeDirs(dir, cwd, options)).flat().sort(compareDirByPathLength)

View File

@ -0,0 +1,39 @@
import { createUnplugin } from 'unplugin'
import type { Program } from 'acorn'
import MagicString from 'magic-string'
import type { Component } from 'nuxt/schema'
import { isVue } from '../core/utils'
interface NameDevPluginOptions {
components: () => Component[]
}
/**
* Set the default name of components to their PascalCase name
*/
export const nameDevPlugin = (options: NameDevPluginOptions) => createUnplugin(() => {
return {
name: 'nuxt:name-dev-plugin',
enforce: 'post',
transformInclude (id) {
return isVue(id) || !!id.match(/\.[tj]sx$/)
},
transform (code, id) {
const component = options.components().find(c => c.filePath === id)
if (!component) {
return
}
const ast = this.parse(code) as Program
const s = new MagicString(code)
const defaultExport = ast.body.find(node => node.type === 'ExportDefaultDeclaration')
if (defaultExport) {
s.overwrite(defaultExport.declaration.start, defaultExport.declaration.end, `Object.assign(${code.slice(defaultExport.declaration.start, defaultExport.declaration.end)}, { __name: ${JSON.stringify(component.pascalName)} } )`)
return {
code: s.toString(),
}
}
},
}
})