From be2a31a029ce2bf017bdbb2323e84dc62326750a Mon Sep 17 00:00:00 2001 From: Julien Huang Date: Tue, 3 Sep 2024 21:26:35 +0200 Subject: [PATCH] refactor: use plugin --- packages/nuxt/src/components/loader.ts | 6 +--- packages/nuxt/src/components/module.ts | 9 +++++- packages/nuxt/src/components/nameDev.ts | 39 +++++++++++++++++++++++++ 3 files changed, 48 insertions(+), 6 deletions(-) create mode 100644 packages/nuxt/src/components/nameDev.ts diff --git a/packages/nuxt/src/components/loader.ts b/packages/nuxt/src/components/loader.ts index 8ad21f53cf..ae38e918db 100644 --- a/packages/nuxt/src/components/loader.ts +++ b/packages/nuxt/src/components/loader.ts @@ -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' diff --git a/packages/nuxt/src/components/module.ts b/packages/nuxt/src/components/module.ts index 7d9bdab2e1..015379b3ad 100644 --- a/packages/nuxt/src/components/module.ts +++ b/packages/nuxt/src/components/module.ts @@ -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({ : 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) diff --git a/packages/nuxt/src/components/nameDev.ts b/packages/nuxt/src/components/nameDev.ts new file mode 100644 index 0000000000..44879fa3e1 --- /dev/null +++ b/packages/nuxt/src/components/nameDev.ts @@ -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(), + } + } + }, + } +})