mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-22 05:35:13 +00:00
feat(kit): addTypeTemplate
helper with auto-registration (#21331)
This commit is contained in:
parent
31a1b98f3f
commit
ee6869b1ba
@ -443,22 +443,40 @@ export default defineNuxtModule({
|
|||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
#### Augmenting Types
|
#### Adding Templates/Virtual Files
|
||||||
|
|
||||||
If your module should augment types handled by Nuxt, you can use the `prepare:types` hook to perform this operation.
|
If you need to add a virtual file that can be imported into the user's app, you can use the `addTemplate` utility.
|
||||||
|
|
||||||
```js
|
```ts
|
||||||
import { defineNuxtModule, addTemplate, createResolver } from '@nuxt/kit'
|
import { defineNuxtModule, addTemplate } from '@nuxt/kit'
|
||||||
|
|
||||||
export default defineNuxtModule({
|
export default defineNuxtModule({
|
||||||
setup (options, nuxt) {
|
setup (options, nuxt) {
|
||||||
const { resolve } = createResolver(import.meta.url)
|
// The file is added to Nuxt's internal virtual file system and can be imported from '#build/my-module-feature.mjs'
|
||||||
|
|
||||||
// Generating types to be injected
|
|
||||||
addTemplate({
|
addTemplate({
|
||||||
filename: 'my-module.d.ts',
|
filename: 'my-module-feature.mjs',
|
||||||
getContents: () => {
|
getContents: () => 'export const myModuleFeature = () => "hello world !"'
|
||||||
return `// Generated by my-module
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Adding Type Declarations
|
||||||
|
|
||||||
|
You might also want to add a type declaration to the user's project (for example, to augment an Nuxt interface
|
||||||
|
or provide a global type of your own). For this, Nuxt provides the `addTypeTemplate` utility that both
|
||||||
|
writes a template to disk and adds a reference to it in the generated `nuxt.d.ts` file that.
|
||||||
|
|
||||||
|
If your module should augment types handled by Nuxt, you can use `addTypeTemplate` to perform this operation:
|
||||||
|
|
||||||
|
```js
|
||||||
|
import { defineNuxtModule, addTemplate, addTypeTemplate } from '@nuxt/kit'
|
||||||
|
|
||||||
|
export default defineNuxtModule({
|
||||||
|
setup (options, nuxt) {
|
||||||
|
addTypeTemplate({
|
||||||
|
filename: 'types/my-module.d.ts',
|
||||||
|
getContents: () => `// Generated by my-module
|
||||||
interface MyModuleNitroRules {
|
interface MyModuleNitroRules {
|
||||||
myModule?: { foo: 'bar' }
|
myModule?: { foo: 'bar' }
|
||||||
}
|
}
|
||||||
@ -467,13 +485,29 @@ export default defineNuxtModule({
|
|||||||
interface NitroRouteConfig extends MyModuleNitroRules {}
|
interface NitroRouteConfig extends MyModuleNitroRules {}
|
||||||
}
|
}
|
||||||
export {}`
|
export {}`
|
||||||
},
|
|
||||||
})
|
})
|
||||||
|
}
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
// Injecting previously generated types
|
If you need more granular control, you can use the `prepare:types` hook to register a callback that will inject your types.
|
||||||
nuxt.hooks.hook('prepare:types', ({ references }) => {
|
|
||||||
references.push({ path: resolve(nuxt.options.buildDir, 'my-module.d.ts') })
|
```ts
|
||||||
})
|
const template = addTemplate({ /* template options */ })
|
||||||
|
nuxt.hook('prepare:types', ({ references }) => {
|
||||||
|
references.push({ path: template.dst })
|
||||||
|
})
|
||||||
|
```
|
||||||
|
|
||||||
|
##### Updating Templates
|
||||||
|
|
||||||
|
If you need to update your templates/virtual files, you can leverage the `updateTemplates` utility like this :
|
||||||
|
|
||||||
|
```ts
|
||||||
|
nuxt.hook('builder:watch', async (event, path) => {
|
||||||
|
if (path.includes('my-module-feature.config')) {
|
||||||
|
// This will reload the template that you registered
|
||||||
|
updateTemplates({ filter: t => t.filename === 'my-module-feature.mjs' })
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
```
|
```
|
||||||
|
@ -76,6 +76,7 @@ description: Nuxt Kit provides composable utilities to help interacting with Nux
|
|||||||
[source code](https://github.com/nuxt/nuxt/blob/main/packages/kit/src/template.ts)
|
[source code](https://github.com/nuxt/nuxt/blob/main/packages/kit/src/template.ts)
|
||||||
|
|
||||||
- `addTemplate(templateOptions)`
|
- `addTemplate(templateOptions)`
|
||||||
|
- `addTypeTemplate(templateOptions)`
|
||||||
- `updateTemplates({ filter?: ResolvedNuxtTemplate => boolean })`
|
- `updateTemplates({ filter?: ResolvedNuxtTemplate => boolean })`
|
||||||
|
|
||||||
### Nitro
|
### Nitro
|
||||||
|
@ -23,6 +23,27 @@ export function addTemplate (_template: NuxtTemplate<any> | string) {
|
|||||||
return template
|
return template
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Renders given types using lodash template during build into the project buildDir
|
||||||
|
* and register them as types.
|
||||||
|
*/
|
||||||
|
export function addTypeTemplate (_template: NuxtTemplate<any>) {
|
||||||
|
const nuxt = useNuxt()
|
||||||
|
|
||||||
|
const template = addTemplate(_template)
|
||||||
|
|
||||||
|
if (!template.filename.endsWith('.d.ts')) {
|
||||||
|
throw new Error(`Invalid type template. Filename must end with .d.ts : "${template.filename}"`)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add template to types reference
|
||||||
|
nuxt.hook('prepare:types', ({ references }) => {
|
||||||
|
references.push({ path: template.dst })
|
||||||
|
})
|
||||||
|
|
||||||
|
return template
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Normalize a nuxt template object
|
* Normalize a nuxt template object
|
||||||
*/
|
*/
|
||||||
|
8
test/fixtures/basic-types/nuxt.config.ts
vendored
8
test/fixtures/basic-types/nuxt.config.ts
vendored
@ -1,3 +1,5 @@
|
|||||||
|
import { addTypeTemplate } from 'nuxt/kit'
|
||||||
|
|
||||||
export default defineNuxtConfig({
|
export default defineNuxtConfig({
|
||||||
experimental: {
|
experimental: {
|
||||||
typedPages: true
|
typedPages: true
|
||||||
@ -33,6 +35,12 @@ export default defineNuxtConfig({
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
modules: [
|
modules: [
|
||||||
|
function () {
|
||||||
|
addTypeTemplate({
|
||||||
|
filename: 'test.d.ts',
|
||||||
|
getContents: () => 'declare type Fromage = "cheese"'
|
||||||
|
})
|
||||||
|
},
|
||||||
'./modules/test',
|
'./modules/test',
|
||||||
[
|
[
|
||||||
'~/modules/example',
|
'~/modules/example',
|
||||||
|
9
test/fixtures/basic-types/types.ts
vendored
9
test/fixtures/basic-types/types.ts
vendored
@ -401,3 +401,12 @@ describe('composables inference', () => {
|
|||||||
expectTypeOf<typeof bob>().toEqualTypeOf<boolean | Promise<boolean>>()
|
expectTypeOf<typeof bob>().toEqualTypeOf<boolean | Promise<boolean>>()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe('kit utilities', () => {
|
||||||
|
it('addTypeTemplate', () => {
|
||||||
|
// @ts-expect-error Fromage is 'cheese'
|
||||||
|
const _fake: Fromage = 'babybel'
|
||||||
|
|
||||||
|
const _fromage: Fromage = 'cheese'
|
||||||
|
})
|
||||||
|
})
|
||||||
|
Loading…
Reference in New Issue
Block a user