mirror of
https://github.com/nuxt/nuxt.git
synced 2025-02-16 21:58:19 +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 { basename, extname, parse, resolve } from 'pathe'
|
||||||
import lodashTemplate from 'lodash.template'
|
import lodashTemplate from 'lodash.template'
|
||||||
import hash from 'hash-sum'
|
import hash from 'hash-sum'
|
||||||
|
import { pascalCase, camelCase, kebabCase } from 'scule'
|
||||||
import type { WebpackPluginInstance, Configuration as WebpackConfig } from 'webpack'
|
import type { WebpackPluginInstance, Configuration as WebpackConfig } from 'webpack'
|
||||||
import type { Plugin as VitePlugin, UserConfig as ViteConfig } from 'vite'
|
import type { Plugin as VitePlugin, UserConfig as ViteConfig } from 'vite'
|
||||||
import { camelCase } from 'scule'
|
import { camelCase } from 'scule'
|
||||||
@ -10,7 +11,7 @@ import { NuxtCompatibilityConstraints, NuxtCompatibilityIssues } from '../types/
|
|||||||
import { Nuxt } from '../types/nuxt'
|
import { Nuxt } from '../types/nuxt'
|
||||||
import { useNuxt } from '../nuxt'
|
import { useNuxt } from '../nuxt'
|
||||||
import type { NuxtTemplate, NuxtPlugin, NuxtPluginTemplate } from '../types/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
|
* 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) })
|
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 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)}`
|
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 */
|
/* eslint-disable no-use-before-define */
|
||||||
import { getCurrentInstance, reactive, defineAsyncComponent } from 'vue'
|
import { getCurrentInstance, reactive } from 'vue'
|
||||||
import type { App, VNode } from 'vue'
|
import type { App, VNode } from 'vue'
|
||||||
import { createHooks, Hookable } from 'hookable'
|
import { createHooks, Hookable } from 'hookable'
|
||||||
import { legacyPlugin, LegacyContext } from './legacy'
|
import { legacyPlugin, LegacyContext } from './legacy'
|
||||||
@ -99,12 +99,6 @@ export function createNuxtApp (options: CreateOptions) {
|
|||||||
nuxtApp.ssrContext.nuxt = nuxtApp
|
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) {
|
if (process.server) {
|
||||||
// Expose to server renderer to create window.__NUXT__
|
// Expose to server renderer to create window.__NUXT__
|
||||||
nuxtApp.ssrContext = nuxtApp.ssrContext || {}
|
nuxtApp.ssrContext = nuxtApp.ssrContext || {}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { resolve } from 'pathe'
|
import { resolve } from 'pathe'
|
||||||
import { createHooks } from 'hookable'
|
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 pagesModule from '../pages/module'
|
||||||
import metaModule from '../meta/module'
|
import metaModule from '../meta/module'
|
||||||
import componentsModule from '../components/module'
|
import componentsModule from '../components/module'
|
||||||
@ -52,6 +52,12 @@ async function initNuxt (nuxt: Nuxt) {
|
|||||||
...nuxt.options._modules
|
...nuxt.options._modules
|
||||||
]
|
]
|
||||||
|
|
||||||
|
// Add <NuxtWelcome>
|
||||||
|
addComponent({
|
||||||
|
name: 'NuxtWelcome',
|
||||||
|
filePath: resolve(nuxt.options.appDir, 'components/nuxt-welcome.vue')
|
||||||
|
})
|
||||||
|
|
||||||
for (const m of modulesToInstall) {
|
for (const m of modulesToInstall) {
|
||||||
await installModule(nuxt, m)
|
await installModule(nuxt, m)
|
||||||
}
|
}
|
||||||
@ -66,7 +72,7 @@ async function initNuxt (nuxt: Nuxt) {
|
|||||||
export async function loadNuxt (opts: LoadNuxtOptions): Promise<Nuxt> {
|
export async function loadNuxt (opts: LoadNuxtOptions): Promise<Nuxt> {
|
||||||
const options = await loadNuxtConfig(opts)
|
const options = await loadNuxtConfig(opts)
|
||||||
|
|
||||||
// Temp
|
// Temporary until finding better placement for each
|
||||||
options.appDir = options.alias['#app'] = resolve(distDir, 'app')
|
options.appDir = options.alias['#app'] = resolve(distDir, 'app')
|
||||||
options._majorVersion = 3
|
options._majorVersion = 3
|
||||||
options.buildModules.push(pagesModule, metaModule, componentsModule, autoImportsModule)
|
options.buildModules.push(pagesModule, metaModule, componentsModule, autoImportsModule)
|
||||||
|
Loading…
Reference in New Issue
Block a user