mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-22 13:45:18 +00:00
feat(kit): addComponent
utility (#1579)
This commit is contained in:
parent
266578b76e
commit
efe1fea1d1
@ -2,6 +2,7 @@ import { existsSync, promises as fsp } from 'fs'
|
||||
import { basename, extname, parse, resolve } from 'pathe'
|
||||
import lodashTemplate from 'lodash.template'
|
||||
import hash from 'hash-sum'
|
||||
import { pascalCase, camelCase, kebabCase } from 'scule'
|
||||
import type { WebpackPluginInstance, Configuration as WebpackConfig } from 'webpack'
|
||||
import type { Plugin as VitePlugin, UserConfig as ViteConfig } from 'vite'
|
||||
import { camelCase } from 'scule'
|
||||
@ -10,7 +11,7 @@ import { NuxtCompatibilityConstraints, NuxtCompatibilityIssues } from '../types/
|
||||
import { Nuxt } from '../types/nuxt'
|
||||
import { useNuxt } from '../nuxt'
|
||||
import type { NuxtTemplate, NuxtPlugin, NuxtPluginTemplate } from '../types/nuxt'
|
||||
import type { ComponentsDir } from '../types/components'
|
||||
import type { ComponentsDir, Component } from '../types/components'
|
||||
|
||||
/**
|
||||
* Renders given template using lodash template during build into the project buildDir
|
||||
@ -302,6 +303,52 @@ export function addComponentsDir (dir: ComponentsDir) {
|
||||
nuxt.hook('components:dirs', (dirs) => { dirs.push(dir) })
|
||||
}
|
||||
|
||||
export type AddComponentOptions = { name: string, filePath: string } & Partial<Exclude<Component,
|
||||
'shortPath' | 'async' | 'level' | 'import' | 'asyncImport'
|
||||
>>
|
||||
|
||||
/**
|
||||
* Register a directory to be scanned for components and imported only when used.
|
||||
*
|
||||
* Requires Nuxt 2.13+
|
||||
*/
|
||||
export function addComponent (opts: AddComponentOptions) {
|
||||
const nuxt = useNuxt()
|
||||
ensureNuxtCompatibility({ nuxt: '>=2.13' }, nuxt)
|
||||
nuxt.options.components = nuxt.options.components || []
|
||||
|
||||
// Apply defaults
|
||||
const component: Component = {
|
||||
export: opts.export || 'default',
|
||||
chunkName: 'components/' + kebabCase(opts.name),
|
||||
global: opts.global ?? false,
|
||||
kebabName: kebabCase(opts.name || ''),
|
||||
pascalName: pascalCase(opts.name || ''),
|
||||
prefetch: false,
|
||||
preload: false,
|
||||
|
||||
// Nuxt 2 support
|
||||
shortPath: opts.filePath,
|
||||
async: false,
|
||||
level: 0,
|
||||
asyncImport: `() => import('${opts.filePath}').then(r => r['${opts.export || 'default'}'])`,
|
||||
import: `require('${opts.filePath}')['${opts.export || 'default'}']`,
|
||||
|
||||
...opts
|
||||
}
|
||||
|
||||
nuxt.hook('components:extend', (components: Component[]) => {
|
||||
const existingComponent = components.find(c => c.pascalName === component.pascalName || c.kebabName === component.kebabName)
|
||||
if (existingComponent) {
|
||||
const name = existingComponent.pascalName || existingComponent.kebabName
|
||||
console.warn(`Overriding ${name} component.`)
|
||||
Object.assign(existingComponent, component)
|
||||
} else {
|
||||
components.push(component)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
const serialize = (data: any) => JSON.stringify(data, null, 2).replace(/"{(.+)}"/g, '$1')
|
||||
|
||||
const importName = (src: string) => `${camelCase(basename(src, extname(src))).replace(/[^a-zA-Z?\d\s:]/g, '')}_${hash(src)}`
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* eslint-disable no-use-before-define */
|
||||
import { getCurrentInstance, reactive, defineAsyncComponent } from 'vue'
|
||||
import { getCurrentInstance, reactive } from 'vue'
|
||||
import type { App, VNode } from 'vue'
|
||||
import { createHooks, Hookable } from 'hookable'
|
||||
import { legacyPlugin, LegacyContext } from './legacy'
|
||||
@ -99,12 +99,6 @@ export function createNuxtApp (options: CreateOptions) {
|
||||
nuxtApp.ssrContext.nuxt = nuxtApp
|
||||
}
|
||||
|
||||
// (temporary) Expose NuxtWelcome component in dev
|
||||
if (process.dev) {
|
||||
// @ts-ignore
|
||||
nuxtApp.vueApp.component('NuxtWelcome', defineAsyncComponent(() => import('./components/nuxt-welcome.vue')))
|
||||
}
|
||||
|
||||
if (process.server) {
|
||||
// Expose to server renderer to create window.__NUXT__
|
||||
nuxtApp.ssrContext = nuxtApp.ssrContext || {}
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { resolve } from 'pathe'
|
||||
import { createHooks } from 'hookable'
|
||||
import { loadNuxtConfig, LoadNuxtOptions, Nuxt, NuxtOptions, NuxtConfig, nuxtCtx, installModule, ModuleContainer, NuxtHooks } from '@nuxt/kit'
|
||||
import { loadNuxtConfig, LoadNuxtOptions, Nuxt, NuxtOptions, NuxtConfig, nuxtCtx, installModule, ModuleContainer, NuxtHooks, addComponent } from '@nuxt/kit'
|
||||
import pagesModule from '../pages/module'
|
||||
import metaModule from '../meta/module'
|
||||
import componentsModule from '../components/module'
|
||||
@ -52,6 +52,12 @@ async function initNuxt (nuxt: Nuxt) {
|
||||
...nuxt.options._modules
|
||||
]
|
||||
|
||||
// Add <NuxtWelcome>
|
||||
addComponent({
|
||||
name: 'NuxtWelcome',
|
||||
filePath: resolve(nuxt.options.appDir, 'components/nuxt-welcome.vue')
|
||||
})
|
||||
|
||||
for (const m of modulesToInstall) {
|
||||
await installModule(nuxt, m)
|
||||
}
|
||||
@ -66,7 +72,7 @@ async function initNuxt (nuxt: Nuxt) {
|
||||
export async function loadNuxt (opts: LoadNuxtOptions): Promise<Nuxt> {
|
||||
const options = await loadNuxtConfig(opts)
|
||||
|
||||
// Temp
|
||||
// Temporary until finding better placement for each
|
||||
options.appDir = options.alias['#app'] = resolve(distDir, 'app')
|
||||
options._majorVersion = 3
|
||||
options.buildModules.push(pagesModule, metaModule, componentsModule, autoImportsModule)
|
||||
|
Loading…
Reference in New Issue
Block a user