Nuxt/packages/nuxt3/src/core/templates.ts

122 lines
3.2 KiB
TypeScript
Raw Normal View History

import { templateUtils } from '@nuxt/kit'
import type { Nuxt, NuxtApp } from '@nuxt/schema'
import { relative } from 'pathe'
import escapeRE from 'escape-string-regexp'
type TemplateContext = {
nuxt: Nuxt;
app: NuxtApp;
}
export const vueShim = {
filename: 'vue-shim.d.ts',
write: true,
getContents: () =>
[
'declare module \'*.vue\' {',
' import { DefineComponent } from \'@vue/runtime-core\'',
' const component: DefineComponent<{}, {}, any>',
' export default component',
'}'
].join('\n')
}
// TODO: Use an alias
export const appComponentTemplate = {
filename: 'app-component.mjs',
getContents (ctx: TemplateContext) {
return `export { default } from '${ctx.app.mainComponent}'`
}
}
// TODO: Use an alias
export const rootComponentTemplate = {
filename: 'root-component.mjs',
getContents (ctx: TemplateContext) {
return `export { default } from '${ctx.app.rootComponent}'`
}
}
export const cssTemplate = {
filename: 'css.mjs',
getContents (ctx: TemplateContext) {
return ctx.nuxt.options.css.map(i => `import '${i.src || i}';`).join('\n')
}
}
export const clientPluginTemplate = {
filename: 'plugins/client.mjs',
getContents (ctx: TemplateContext) {
const clientPlugins = ctx.app.plugins.filter(p => !p.mode || p.mode !== 'server')
return [
templateUtils.importSources(clientPlugins.map(p => p.src)),
'export default [',
clientPlugins.map(p => templateUtils.importName(p.src)).join(',\n '),
']'
].join('\n')
}
}
export const serverPluginTemplate = {
filename: 'plugins/server.mjs',
getContents (ctx: TemplateContext) {
const serverPlugins = ctx.app.plugins.filter(p => !p.mode || p.mode !== 'client')
return [
"import preload from '#app/plugins/preload.server'",
templateUtils.importSources(serverPlugins.map(p => p.src)),
'export default [',
' preload,',
serverPlugins.map(p => templateUtils.importName(p.src)).join(',\n '),
']'
].join('\n')
}
}
export const appViewTemplate = {
filename: 'views/app.template.html',
getContents () {
return `<!DOCTYPE html>
<html {{ HTML_ATTRS }}>
<head {{ HEAD_ATTRS }}>
{{ HEAD }}
</head>
<body {{ BODY_ATTRS }}>
{{ APP }}
</body>
</html>
`
}
}
export const pluginsDeclaration = {
filename: 'plugins.d.ts',
write: true,
getContents: (ctx: TemplateContext) => {
const EXTENSION_RE = new RegExp(`(?<=\\w)(${ctx.nuxt.options.extensions.map(e => escapeRE(e)).join('|')})$`, 'g')
const tsImports = ctx.app.plugins.map(p => relative(ctx.nuxt.options.buildDir, p.src).replace(EXTENSION_RE, ''))
return `// Generated by Nuxt3'
import type { Plugin } from '#app'
type Decorate<T extends Record<string, any>> = { [K in keyof T as K extends string ? \`$\${K}\` : never]: T[K] }
type InjectionType<A extends Plugin> = A extends Plugin<infer T> ? Decorate<T> : unknown
type NuxtAppInjections = \n ${tsImports.map(p => `InjectionType<typeof import('${p}').default>`).join(' &\n ')}
declare module '#app' {
interface NuxtApp extends NuxtAppInjections { }
}
declare module '@vue/runtime-core' {
interface ComponentCustomProperties extends NuxtAppInjections { }
}
export { }
`
}
}