mirror of
https://github.com/nuxt/nuxt.git
synced 2024-11-25 15:15:19 +00:00
feat(kit,nuxi): add writeTypes
utility (#22385)
This commit is contained in:
parent
0f839dd723
commit
38d2bb7b95
@ -60,15 +60,19 @@ function getRequireCacheItem (id: string) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getModulePaths (paths?: string[] | string) {
|
||||||
|
return ([] as Array<string | undefined>).concat(
|
||||||
|
global.__NUXT_PREPATHS__,
|
||||||
|
paths || [],
|
||||||
|
process.cwd(),
|
||||||
|
global.__NUXT_PATHS__
|
||||||
|
).filter(Boolean) as string[]
|
||||||
|
}
|
||||||
|
|
||||||
/** @deprecated Do not use CJS utils */
|
/** @deprecated Do not use CJS utils */
|
||||||
export function resolveModule (id: string, opts: ResolveModuleOptions = {}) {
|
export function resolveModule (id: string, opts: ResolveModuleOptions = {}) {
|
||||||
return normalize(_require.resolve(id, {
|
return normalize(_require.resolve(id, {
|
||||||
paths: ([] as Array<string | undefined>).concat(
|
paths: getModulePaths(opts.paths)
|
||||||
global.__NUXT_PREPATHS__,
|
|
||||||
opts.paths || [],
|
|
||||||
process.cwd(),
|
|
||||||
global.__NUXT_PATHS__
|
|
||||||
).filter(Boolean) as string[]
|
|
||||||
}))
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,8 +1,14 @@
|
|||||||
import { existsSync } from 'node:fs'
|
import { existsSync, promises as fsp } from 'node:fs'
|
||||||
import { basename, parse, resolve } from 'pathe'
|
import { basename, isAbsolute, join, parse, relative, resolve } from 'pathe'
|
||||||
import hash from 'hash-sum'
|
import hash from 'hash-sum'
|
||||||
import type { NuxtTemplate, ResolvedNuxtTemplate } from '@nuxt/schema'
|
import type { Nuxt, NuxtTemplate, ResolvedNuxtTemplate, TSReference } from '@nuxt/schema'
|
||||||
|
import { withTrailingSlash } from 'ufo'
|
||||||
|
import { defu } from 'defu'
|
||||||
|
import type { TSConfig } from 'pkg-types'
|
||||||
|
import { readPackageJSON } from 'pkg-types'
|
||||||
|
|
||||||
import { tryUseNuxt, useNuxt } from './context'
|
import { tryUseNuxt, useNuxt } from './context'
|
||||||
|
import { getModulePaths } from './internal/cjs'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Renders given template using lodash template during build into the project buildDir
|
* Renders given template using lodash template during build into the project buildDir
|
||||||
@ -101,3 +107,142 @@ export function normalizeTemplate (template: NuxtTemplate<any> | string): Resolv
|
|||||||
export async function updateTemplates (options?: { filter?: (template: ResolvedNuxtTemplate<any>) => boolean }) {
|
export async function updateTemplates (options?: { filter?: (template: ResolvedNuxtTemplate<any>) => boolean }) {
|
||||||
return await tryUseNuxt()?.hooks.callHook('builder:generateApp', options)
|
return await tryUseNuxt()?.hooks.callHook('builder:generateApp', options)
|
||||||
}
|
}
|
||||||
|
export async function writeTypes (nuxt: Nuxt) {
|
||||||
|
const modulePaths = getModulePaths(nuxt.options.modulesDir)
|
||||||
|
|
||||||
|
const rootDirWithSlash = withTrailingSlash(nuxt.options.rootDir)
|
||||||
|
|
||||||
|
const tsConfig: TSConfig = defu(nuxt.options.typescript?.tsConfig, {
|
||||||
|
compilerOptions: {
|
||||||
|
forceConsistentCasingInFileNames: true,
|
||||||
|
jsx: 'preserve',
|
||||||
|
target: 'ESNext',
|
||||||
|
module: 'ESNext',
|
||||||
|
moduleResolution: nuxt.options.experimental?.typescriptBundlerResolution ? 'Bundler' : 'Node',
|
||||||
|
skipLibCheck: true,
|
||||||
|
strict: nuxt.options.typescript?.strict ?? true,
|
||||||
|
allowJs: true,
|
||||||
|
// TODO: remove by default in 3.7
|
||||||
|
baseUrl: nuxt.options.srcDir,
|
||||||
|
noEmit: true,
|
||||||
|
resolveJsonModule: true,
|
||||||
|
allowSyntheticDefaultImports: true,
|
||||||
|
types: ['node'],
|
||||||
|
paths: {}
|
||||||
|
},
|
||||||
|
include: [
|
||||||
|
'./nuxt.d.ts',
|
||||||
|
join(relative(nuxt.options.buildDir, nuxt.options.rootDir), '**/*'),
|
||||||
|
...nuxt.options.srcDir !== nuxt.options.rootDir ? [join(relative(nuxt.options.buildDir, nuxt.options.srcDir), '**/*')] : [],
|
||||||
|
...nuxt.options._layers.map(layer => layer.config.srcDir ?? layer.cwd)
|
||||||
|
.filter(srcOrCwd => !srcOrCwd.startsWith(rootDirWithSlash) || srcOrCwd.includes('node_modules'))
|
||||||
|
.map(srcOrCwd => join(relative(nuxt.options.buildDir, srcOrCwd), '**/*')),
|
||||||
|
...nuxt.options.typescript.includeWorkspace && nuxt.options.workspaceDir !== nuxt.options.rootDir ? [join(relative(nuxt.options.buildDir, nuxt.options.workspaceDir), '**/*')] : []
|
||||||
|
],
|
||||||
|
exclude: [
|
||||||
|
...nuxt.options.modulesDir.map(m => relative(nuxt.options.buildDir, m)),
|
||||||
|
// nitro generate output: https://github.com/nuxt/nuxt/blob/main/packages/nuxt/src/core/nitro.ts#L186
|
||||||
|
relative(nuxt.options.buildDir, resolve(nuxt.options.rootDir, 'dist'))
|
||||||
|
]
|
||||||
|
} satisfies TSConfig)
|
||||||
|
|
||||||
|
const aliases: Record<string, string> = {
|
||||||
|
...nuxt.options.alias,
|
||||||
|
'#build': nuxt.options.buildDir
|
||||||
|
}
|
||||||
|
|
||||||
|
// Exclude bridge alias types to support Volar
|
||||||
|
const excludedAlias = [/^@vue\/.*$/]
|
||||||
|
|
||||||
|
const basePath = tsConfig.compilerOptions!.baseUrl ? resolve(nuxt.options.buildDir, tsConfig.compilerOptions!.baseUrl) : nuxt.options.buildDir
|
||||||
|
|
||||||
|
tsConfig.compilerOptions = tsConfig.compilerOptions || {}
|
||||||
|
tsConfig.include = tsConfig.include || []
|
||||||
|
|
||||||
|
for (const alias in aliases) {
|
||||||
|
if (excludedAlias.some(re => re.test(alias))) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
const absolutePath = resolve(basePath, aliases[alias])
|
||||||
|
const relativePath = relative(nuxt.options.buildDir, absolutePath)
|
||||||
|
|
||||||
|
const stats = await fsp.stat(absolutePath).catch(() => null /* file does not exist */)
|
||||||
|
if (stats?.isDirectory()) {
|
||||||
|
tsConfig.compilerOptions.paths[alias] = [absolutePath]
|
||||||
|
tsConfig.compilerOptions.paths[`${alias}/*`] = [`${absolutePath}/*`]
|
||||||
|
|
||||||
|
if (!absolutePath.startsWith(rootDirWithSlash)) {
|
||||||
|
tsConfig.include.push(relativePath)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
const path = stats?.isFile()
|
||||||
|
? absolutePath.replace(/(?<=\w)\.\w+$/g, '') /* remove extension */
|
||||||
|
: absolutePath
|
||||||
|
|
||||||
|
tsConfig.compilerOptions.paths[alias] = [path]
|
||||||
|
|
||||||
|
if (!absolutePath.startsWith(rootDirWithSlash)) {
|
||||||
|
tsConfig.include.push(path)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const references: TSReference[] = await Promise.all([
|
||||||
|
...nuxt.options.modules,
|
||||||
|
...nuxt.options._modules
|
||||||
|
]
|
||||||
|
.filter(f => typeof f === 'string')
|
||||||
|
.map(async id => ({ types: (await readPackageJSON(id, { url: modulePaths }).catch(() => null))?.name || id })))
|
||||||
|
|
||||||
|
if (nuxt.options.experimental?.reactivityTransform) {
|
||||||
|
references.push({ types: 'vue/macros-global' })
|
||||||
|
}
|
||||||
|
|
||||||
|
const declarations: string[] = []
|
||||||
|
|
||||||
|
tsConfig.include = [...new Set(tsConfig.include)]
|
||||||
|
tsConfig.exclude = [...new Set(tsConfig.exclude)]
|
||||||
|
|
||||||
|
await nuxt.callHook('prepare:types', { references, declarations, tsConfig })
|
||||||
|
|
||||||
|
const declaration = [
|
||||||
|
...references.map((ref) => {
|
||||||
|
if ('path' in ref && isAbsolute(ref.path)) {
|
||||||
|
ref.path = relative(nuxt.options.buildDir, ref.path)
|
||||||
|
}
|
||||||
|
return `/// <reference ${renderAttrs(ref)} />`
|
||||||
|
}),
|
||||||
|
...declarations,
|
||||||
|
'',
|
||||||
|
'export {}',
|
||||||
|
''
|
||||||
|
].join('\n')
|
||||||
|
|
||||||
|
async function writeFile () {
|
||||||
|
const GeneratedBy = '// Generated by nuxi'
|
||||||
|
|
||||||
|
const tsConfigPath = resolve(nuxt.options.buildDir, 'tsconfig.json')
|
||||||
|
await fsp.mkdir(nuxt.options.buildDir, { recursive: true })
|
||||||
|
await fsp.writeFile(tsConfigPath, GeneratedBy + '\n' + JSON.stringify(tsConfig, null, 2))
|
||||||
|
|
||||||
|
const declarationPath = resolve(nuxt.options.buildDir, 'nuxt.d.ts')
|
||||||
|
await fsp.writeFile(declarationPath, GeneratedBy + '\n' + declaration)
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is needed for Nuxt 2 which clears the build directory again before building
|
||||||
|
// https://github.com/nuxt/nuxt/blob/2.x/packages/builder/src/builder.js#L144
|
||||||
|
// @ts-expect-error TODO: Nuxt 2 hook
|
||||||
|
const unsub = nuxt.hook('builder:prepared', writeFile)
|
||||||
|
|
||||||
|
await writeFile()
|
||||||
|
|
||||||
|
unsub()
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderAttrs (obj: Record<string, string>) {
|
||||||
|
return Object.entries(obj).map(e => renderAttr(e[0], e[1])).join(' ')
|
||||||
|
}
|
||||||
|
|
||||||
|
function renderAttr (key: string, value: string) {
|
||||||
|
return value ? `${key}="${value}"` : ''
|
||||||
|
}
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
import { relative, resolve } from 'pathe'
|
import { relative, resolve } from 'pathe'
|
||||||
import { consola } from 'consola'
|
import { consola } from 'consola'
|
||||||
import { writeTypes } from '../utils/prepare'
|
|
||||||
|
// we are deliberately inlining this code as a backup in case user has `@nuxt/schema<3.7`
|
||||||
|
import { writeTypes as writeTypesLegacy } from '../../../kit/src/template'
|
||||||
import { loadKit } from '../utils/kit'
|
import { loadKit } from '../utils/kit'
|
||||||
import { clearBuildDir } from '../utils/fs'
|
import { clearBuildDir } from '../utils/fs'
|
||||||
import { overrideEnv } from '../utils/env'
|
import { overrideEnv } from '../utils/env'
|
||||||
@ -19,7 +21,7 @@ export default defineNuxtCommand({
|
|||||||
const rootDir = resolve(args._[0] || '.')
|
const rootDir = resolve(args._[0] || '.')
|
||||||
showVersions(rootDir)
|
showVersions(rootDir)
|
||||||
|
|
||||||
const { loadNuxt, buildNuxt, useNitro } = await loadKit(rootDir)
|
const { loadNuxt, buildNuxt, useNitro, writeTypes = writeTypesLegacy } = await loadKit(rootDir)
|
||||||
|
|
||||||
const nuxt = await loadNuxt({
|
const nuxt = await loadNuxt({
|
||||||
rootDir,
|
rootDir,
|
||||||
|
@ -7,8 +7,10 @@ import type { Nuxt } from '@nuxt/schema'
|
|||||||
import { consola } from 'consola'
|
import { consola } from 'consola'
|
||||||
import { withTrailingSlash } from 'ufo'
|
import { withTrailingSlash } from 'ufo'
|
||||||
import { setupDotenv } from 'c12'
|
import { setupDotenv } from 'c12'
|
||||||
|
|
||||||
|
// we are deliberately inlining this code as a backup in case user has `@nuxt/schema<3.7`
|
||||||
|
import { writeTypes as writeTypesLegacy } from '../../../kit/src/template'
|
||||||
import { showBanner, showVersions } from '../utils/banner'
|
import { showBanner, showVersions } from '../utils/banner'
|
||||||
import { writeTypes } from '../utils/prepare'
|
|
||||||
import { loadKit } from '../utils/kit'
|
import { loadKit } from '../utils/kit'
|
||||||
import { importModule } from '../utils/esm'
|
import { importModule } from '../utils/esm'
|
||||||
import { overrideEnv } from '../utils/env'
|
import { overrideEnv } from '../utils/env'
|
||||||
@ -30,7 +32,7 @@ export default defineNuxtCommand({
|
|||||||
|
|
||||||
await setupDotenv({ cwd: rootDir, fileName: args.dotenv })
|
await setupDotenv({ cwd: rootDir, fileName: args.dotenv })
|
||||||
|
|
||||||
const { loadNuxt, loadNuxtConfig, buildNuxt } = await loadKit(rootDir)
|
const { loadNuxt, loadNuxtConfig, buildNuxt, writeTypes = writeTypesLegacy } = await loadKit(rootDir)
|
||||||
|
|
||||||
const config = await loadNuxtConfig({
|
const config = await loadNuxtConfig({
|
||||||
cwd: rootDir,
|
cwd: rootDir,
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
import { relative, resolve } from 'pathe'
|
import { relative, resolve } from 'pathe'
|
||||||
import { consola } from 'consola'
|
import { consola } from 'consola'
|
||||||
|
|
||||||
|
// we are deliberately inlining this code as a backup in case user has `@nuxt/schema<3.7`
|
||||||
|
import { writeTypes as writeTypesLegacy } from '../../../kit/src/template'
|
||||||
import { clearBuildDir } from '../utils/fs'
|
import { clearBuildDir } from '../utils/fs'
|
||||||
import { loadKit } from '../utils/kit'
|
import { loadKit } from '../utils/kit'
|
||||||
import { writeTypes } from '../utils/prepare'
|
|
||||||
import { defineNuxtCommand } from './index'
|
import { defineNuxtCommand } from './index'
|
||||||
|
|
||||||
export default defineNuxtCommand({
|
export default defineNuxtCommand({
|
||||||
@ -15,7 +17,7 @@ export default defineNuxtCommand({
|
|||||||
process.env.NODE_ENV = process.env.NODE_ENV || 'production'
|
process.env.NODE_ENV = process.env.NODE_ENV || 'production'
|
||||||
const rootDir = resolve(args._[0] || '.')
|
const rootDir = resolve(args._[0] || '.')
|
||||||
|
|
||||||
const { loadNuxt, buildNuxt } = await loadKit(rootDir)
|
const { loadNuxt, buildNuxt, writeTypes = writeTypesLegacy } = await loadKit(rootDir)
|
||||||
const nuxt = await loadNuxt({
|
const nuxt = await loadNuxt({
|
||||||
rootDir,
|
rootDir,
|
||||||
overrides: {
|
overrides: {
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
import { execa } from 'execa'
|
import { execa } from 'execa'
|
||||||
import { resolve } from 'pathe'
|
import { resolve } from 'pathe'
|
||||||
import { tryResolveModule } from '../utils/esm'
|
|
||||||
|
|
||||||
|
// we are deliberately inlining this code as a backup in case user has `@nuxt/schema<3.7`
|
||||||
|
import { writeTypes as writeTypesLegacy } from '../../../kit/src/template'
|
||||||
|
import { tryResolveModule } from '../utils/esm'
|
||||||
import { loadKit } from '../utils/kit'
|
import { loadKit } from '../utils/kit'
|
||||||
import { writeTypes } from '../utils/prepare'
|
|
||||||
import { defineNuxtCommand } from './index'
|
import { defineNuxtCommand } from './index'
|
||||||
|
|
||||||
export default defineNuxtCommand({
|
export default defineNuxtCommand({
|
||||||
@ -16,7 +17,7 @@ export default defineNuxtCommand({
|
|||||||
process.env.NODE_ENV = process.env.NODE_ENV || 'production'
|
process.env.NODE_ENV = process.env.NODE_ENV || 'production'
|
||||||
const rootDir = resolve(args._[0] || '.')
|
const rootDir = resolve(args._[0] || '.')
|
||||||
|
|
||||||
const { loadNuxt, buildNuxt } = await loadKit(rootDir)
|
const { loadNuxt, buildNuxt, writeTypes = writeTypesLegacy } = await loadKit(rootDir)
|
||||||
const nuxt = await loadNuxt({
|
const nuxt = await loadNuxt({
|
||||||
rootDir,
|
rootDir,
|
||||||
overrides: {
|
overrides: {
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import { createRequire } from 'node:module'
|
import { createRequire } from 'node:module'
|
||||||
import { dirname, normalize } from 'pathe'
|
import { normalize } from 'pathe'
|
||||||
|
|
||||||
export function getModulePaths (paths?: string | string[]): string[] {
|
function getModulePaths (paths?: string | string[]): string[] {
|
||||||
return ([] as Array<string | undefined>)
|
return ([] as Array<string | undefined>)
|
||||||
.concat(
|
.concat(
|
||||||
global.__NUXT_PREPATHS__,
|
global.__NUXT_PREPATHS__,
|
||||||
@ -25,11 +25,3 @@ function requireModule (id: string, paths?: string | string[]) {
|
|||||||
export function tryRequireModule (id: string, paths?: string | string[]) {
|
export function tryRequireModule (id: string, paths?: string | string[]) {
|
||||||
try { return requireModule(id, paths) } catch { return null }
|
try { return requireModule(id, paths) } catch { return null }
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getNearestPackage (id: string, paths?: string | string[]) {
|
|
||||||
while (dirname(id) !== id) {
|
|
||||||
try { return requireModule(id + '/package.json', paths) } catch {}
|
|
||||||
id = dirname(id)
|
|
||||||
}
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
@ -1,141 +0,0 @@
|
|||||||
import { promises as fsp } from 'node:fs'
|
|
||||||
import { isAbsolute, join, relative, resolve } from 'pathe'
|
|
||||||
import type { Nuxt, TSReference } from '@nuxt/schema'
|
|
||||||
import { defu } from 'defu'
|
|
||||||
import type { TSConfig } from 'pkg-types'
|
|
||||||
import { withTrailingSlash } from 'ufo'
|
|
||||||
import { getModulePaths, getNearestPackage } from './cjs'
|
|
||||||
|
|
||||||
export const writeTypes = async (nuxt: Nuxt) => {
|
|
||||||
const modulePaths = getModulePaths(nuxt.options.modulesDir)
|
|
||||||
|
|
||||||
const rootDirWithSlash = withTrailingSlash(nuxt.options.rootDir)
|
|
||||||
|
|
||||||
const tsConfig: TSConfig = defu(nuxt.options.typescript?.tsConfig, {
|
|
||||||
compilerOptions: {
|
|
||||||
forceConsistentCasingInFileNames: true,
|
|
||||||
jsx: 'preserve',
|
|
||||||
target: 'ESNext',
|
|
||||||
module: 'ESNext',
|
|
||||||
moduleResolution: nuxt.options.experimental?.typescriptBundlerResolution ? 'Bundler' : 'Node',
|
|
||||||
skipLibCheck: true,
|
|
||||||
strict: nuxt.options.typescript?.strict ?? true,
|
|
||||||
allowJs: true,
|
|
||||||
// TODO: remove by default in 3.7
|
|
||||||
baseUrl: nuxt.options.srcDir,
|
|
||||||
noEmit: true,
|
|
||||||
resolveJsonModule: true,
|
|
||||||
allowSyntheticDefaultImports: true,
|
|
||||||
types: ['node'],
|
|
||||||
paths: {}
|
|
||||||
},
|
|
||||||
include: [
|
|
||||||
'./nuxt.d.ts',
|
|
||||||
join(relative(nuxt.options.buildDir, nuxt.options.rootDir), '**/*'),
|
|
||||||
...nuxt.options.srcDir !== nuxt.options.rootDir ? [join(relative(nuxt.options.buildDir, nuxt.options.srcDir), '**/*')] : [],
|
|
||||||
...nuxt.options._layers.map(layer => layer.config.srcDir ?? layer.cwd)
|
|
||||||
.filter(srcOrCwd => !srcOrCwd.startsWith(rootDirWithSlash) || srcOrCwd.includes('node_modules'))
|
|
||||||
.map(srcOrCwd => join(relative(nuxt.options.buildDir, srcOrCwd), '**/*')),
|
|
||||||
...nuxt.options.typescript.includeWorkspace && nuxt.options.workspaceDir !== nuxt.options.rootDir ? [join(relative(nuxt.options.buildDir, nuxt.options.workspaceDir), '**/*')] : []
|
|
||||||
],
|
|
||||||
exclude: [
|
|
||||||
// nitro generate output: https://github.com/nuxt/nuxt/blob/main/packages/nuxt/src/core/nitro.ts#L186
|
|
||||||
relative(nuxt.options.buildDir, resolve(nuxt.options.rootDir, 'dist'))
|
|
||||||
]
|
|
||||||
} satisfies TSConfig)
|
|
||||||
|
|
||||||
const aliases: Record<string, string> = {
|
|
||||||
...nuxt.options.alias,
|
|
||||||
'#build': nuxt.options.buildDir
|
|
||||||
}
|
|
||||||
|
|
||||||
// Exclude bridge alias types to support Volar
|
|
||||||
const excludedAlias = [/^@vue\/.*$/]
|
|
||||||
|
|
||||||
const basePath = tsConfig.compilerOptions!.baseUrl ? resolve(nuxt.options.buildDir, tsConfig.compilerOptions!.baseUrl) : nuxt.options.buildDir
|
|
||||||
|
|
||||||
tsConfig.compilerOptions = tsConfig.compilerOptions || {}
|
|
||||||
tsConfig.include = tsConfig.include || []
|
|
||||||
|
|
||||||
for (const alias in aliases) {
|
|
||||||
if (excludedAlias.some(re => re.test(alias))) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
const absolutePath = resolve(basePath, aliases[alias])
|
|
||||||
|
|
||||||
const stats = await fsp.stat(absolutePath).catch(() => null /* file does not exist */)
|
|
||||||
if (stats?.isDirectory()) {
|
|
||||||
tsConfig.compilerOptions.paths[alias] = [absolutePath]
|
|
||||||
tsConfig.compilerOptions.paths[`${alias}/*`] = [`${absolutePath}/*`]
|
|
||||||
|
|
||||||
if (!absolutePath.startsWith(rootDirWithSlash)) {
|
|
||||||
tsConfig.include.push(absolutePath)
|
|
||||||
tsConfig.include.push(`${absolutePath}/*`)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
const path = stats?.isFile()
|
|
||||||
? absolutePath.replace(/(?<=\w)\.\w+$/g, '') /* remove extension */
|
|
||||||
: absolutePath
|
|
||||||
|
|
||||||
tsConfig.compilerOptions.paths[alias] = [path]
|
|
||||||
|
|
||||||
if (!absolutePath.startsWith(rootDirWithSlash)) {
|
|
||||||
tsConfig.include.push(path)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const references: TSReference[] = [
|
|
||||||
...nuxt.options.modules,
|
|
||||||
...nuxt.options._modules
|
|
||||||
]
|
|
||||||
.filter(f => typeof f === 'string')
|
|
||||||
.map(id => ({ types: getNearestPackage(id, modulePaths)?.name || id }))
|
|
||||||
|
|
||||||
if (nuxt.options.experimental?.reactivityTransform) {
|
|
||||||
references.push({ types: 'vue/macros-global' })
|
|
||||||
}
|
|
||||||
|
|
||||||
const declarations: string[] = []
|
|
||||||
|
|
||||||
await nuxt.callHook('prepare:types', { references, declarations, tsConfig })
|
|
||||||
|
|
||||||
const declaration = [
|
|
||||||
...references.map((ref) => {
|
|
||||||
if ('path' in ref && isAbsolute(ref.path)) {
|
|
||||||
ref.path = relative(nuxt.options.buildDir, ref.path)
|
|
||||||
}
|
|
||||||
return `/// <reference ${renderAttrs(ref)} />`
|
|
||||||
}),
|
|
||||||
...declarations,
|
|
||||||
'',
|
|
||||||
'export {}',
|
|
||||||
''
|
|
||||||
].join('\n')
|
|
||||||
|
|
||||||
async function writeFile () {
|
|
||||||
const GeneratedBy = '// Generated by nuxi'
|
|
||||||
|
|
||||||
const tsConfigPath = resolve(nuxt.options.buildDir, 'tsconfig.json')
|
|
||||||
await fsp.mkdir(nuxt.options.buildDir, { recursive: true })
|
|
||||||
await fsp.writeFile(tsConfigPath, GeneratedBy + '\n' + JSON.stringify(tsConfig, null, 2))
|
|
||||||
|
|
||||||
const declarationPath = resolve(nuxt.options.buildDir, 'nuxt.d.ts')
|
|
||||||
await fsp.writeFile(declarationPath, GeneratedBy + '\n' + declaration)
|
|
||||||
}
|
|
||||||
|
|
||||||
// This is needed for Nuxt 2 which clears the build directory again before building
|
|
||||||
// https://github.com/nuxt/nuxt/blob/2.x/packages/builder/src/builder.js#L144
|
|
||||||
// @ts-expect-error TODO: Nuxt 2 hook
|
|
||||||
nuxt.hook('builder:prepared', writeFile)
|
|
||||||
|
|
||||||
await writeFile()
|
|
||||||
}
|
|
||||||
|
|
||||||
function renderAttrs (obj: Record<string, string>) {
|
|
||||||
return Object.entries(obj).map(e => renderAttr(e[0], e[1])).join(' ')
|
|
||||||
}
|
|
||||||
|
|
||||||
function renderAttr (key: string, value: string) {
|
|
||||||
return value ? `${key}="${value}"` : ''
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user