Skip to content

Commit d4e41d2

Browse files
committed
fix: include .vue files when resolving tsconfig include patterns
fix #469
1 parent 4bd5189 commit d4e41d2

2 files changed

Lines changed: 84 additions & 2 deletions

File tree

packages/unplugin-dts/src/core/processor/vue.ts

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,46 @@
1+
import { dirname } from 'node:path'
2+
13
import {
2-
createParsedCommandLine,
34
createVueLanguagePlugin,
5+
createParsedCommandLine as createVueParsedCommandLine,
46
getDefaultCompilerOptions,
57
} from '@vue/language-core'
68

79
import { proxyCreateProgram } from '@volar/typescript'
810
import ts from '../ts-loader.cjs'
911
import { slash } from '../utils'
1012

11-
export { createParsedCommandLine } from './ts'
13+
export function createParsedCommandLine(
14+
_ts: typeof ts,
15+
host: ts.ParseConfigHost,
16+
configPath: string,
17+
) {
18+
// Use @vue/language-core to parse vueCompilerOptions, but its readDirectory
19+
// returns [] which breaks glob expansion. We combine it with native TS parsing
20+
// that adds .vue to supported extensions so include patterns work correctly.
21+
const vueResult = createVueParsedCommandLine(_ts, host, slash(configPath))
22+
23+
const config = _ts.readJsonConfigFile(configPath, host.readFile)
24+
const vueHost: ts.ParseConfigHost = {
25+
...host,
26+
readDirectory(rootDir, extensions, excludes, includes, depth) {
27+
const extendedExtensions = extensions ? [...extensions, '.vue'] : extensions
28+
return host.readDirectory(rootDir, extendedExtensions, excludes, includes, depth)
29+
},
30+
}
31+
const parsed = _ts.parseJsonSourceFileConfigFileContent(
32+
config,
33+
vueHost,
34+
dirname(configPath),
35+
{},
36+
configPath,
37+
)
38+
39+
return {
40+
...parsed,
41+
vueOptions: vueResult.vueOptions,
42+
}
43+
}
1244

1345
export const createProgram = proxyCreateProgram(ts, ts.createProgram, (ts, options) => {
1446
const { configFilePath } = options.options

packages/unplugin-dts/tests/runtime.spec.ts

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,56 @@ describe('runtime tests', () => {
4848
expect(normalizePath(alias!.replacement)).toBe(normalizePath(resolve(tempDir, 'src/$1')))
4949
})
5050

51+
it('should include .vue files when using glob patterns with processor vue', async () => {
52+
tempDir = mkdtempSync(resolve(tmpdir(), 'unplugin-dts-'))
53+
54+
writeFileSync(
55+
resolve(tempDir, 'tsconfig.json'),
56+
JSON.stringify({
57+
include: ['src/**/*'],
58+
exclude: ['node_modules', 'dist'],
59+
compilerOptions: {
60+
target: 'ESNext',
61+
module: 'ESNext',
62+
composite: true,
63+
moduleResolution: 'bundler',
64+
strict: true,
65+
},
66+
}),
67+
)
68+
69+
mkdirSync(resolve(tempDir, 'src', 'components'), { recursive: true })
70+
writeFileSync(
71+
resolve(tempDir, 'src', 'main.ts'),
72+
`import App from './App.vue'\nexport { App }\n`,
73+
)
74+
writeFileSync(
75+
resolve(tempDir, 'src', 'App.vue'),
76+
`<template><HelloWorld /></template>\n<script setup lang="ts">\nimport HelloWorld from './components/HelloWorld.vue'\n</script>\n`,
77+
)
78+
writeFileSync(
79+
resolve(tempDir, 'src', 'components', 'HelloWorld.vue'),
80+
`<template><div>Hello</div></template>\n<script setup lang="ts">\nconst msg = 'Hello World'\n</script>\n`,
81+
)
82+
83+
const runtime = await Runtime.toInstance({
84+
processor: 'vue',
85+
root: tempDir,
86+
tsconfigPath: 'tsconfig.json',
87+
entries: {
88+
main: resolve(tempDir, 'src/main.ts'),
89+
},
90+
})
91+
92+
const diagnostics = runtime.getDiagnostics()
93+
const ts6307 = diagnostics.filter((d: any) => {
94+
const msg = typeof d.messageText === 'string' ? d.messageText : d.messageText.messageText
95+
return msg.includes('not listed within the file list')
96+
})
97+
98+
expect(ts6307).toHaveLength(0)
99+
})
100+
51101
it('should use baseUrl when explicitly set', async () => {
52102
tempDir = mkdtempSync(resolve(tmpdir(), 'unplugin-dts-'))
53103

0 commit comments

Comments
 (0)