Skip to content

Commit 4027ee7

Browse files
committed
perf(tsc): support vue files with project reference delcaration
Support vue files with project reference output, so that typescript resolves the project reference vue file as the output `vue.d.ts` file rather than the source. This drastically improves performance in large projects that have vue files imported from project references. As much as 50% performance improvements as ts no longer recompiles vue files from source. Setup the real path to pass back the real path of vue files, as they are virtual files the inbuilt realpath always returns the non symlinked version (node_modules), which affects DX with vue-tsc as errors originating from upstream project reference packages are returned with the node modules path rather than the source. This change is also required to power the usage of `d.ts` files.
1 parent a03aae4 commit 4027ee7

File tree

1 file changed

+16
-1
lines changed

1 file changed

+16
-1
lines changed

packages/tsc/src/index.ts

+16-1
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,7 @@ export function createProgram(options: ts.CreateProgramOptions) {
6464
modifiedTime: number,
6565
scriptSnapshot: ts.IScriptSnapshot,
6666
}>();
67-
const languageHost: vue.TypeScriptLanguageHost = {
67+
const languageHost: vue.TypeScriptLanguageHost & Partial<ts.LanguageServiceHost> = {
6868
workspacePath: ctx.options.host!.getCurrentDirectory().replace(windowsPathReg, '/'),
6969
rootPath: ctx.options.host!.getCurrentDirectory().replace(windowsPathReg, '/'),
7070
getCompilationSettings: () => ctx.options.options,
@@ -77,6 +77,21 @@ export function createProgram(options: ts.CreateProgramOptions) {
7777
},
7878
getProjectReferences: () => ctx.options.projectReferences,
7979
getCancellationToken: ctx.options.host!.getCancellationToken ? () => ctx.options.host!.getCancellationToken!() : undefined,
80+
realpath(path) {
81+
const realpath = ctx.options.host!.realpath! ?? ts.sys.realpath
82+
const match = /^(?<path>.+\.vue)\.(?<extension>.+)$/.exec(path)
83+
return match?.groups ? `${realpath(match.groups.path)}.${match.groups.extension}` : realpath(path)
84+
},
85+
getParsedCommandLine: (path) => {
86+
const possibleExtensions = ['ts', 'tsx']
87+
const { fileNames, ...commandLineCustom } = vue.createParsedCommandLine(ts, ts.sys, path)
88+
// need to outDir to be defined
89+
const commandLine = ts.getParsedCommandLineOfConfigFile(path, undefined, ts.sys as any) ?? commandLineCustom
90+
return {
91+
...commandLine,
92+
fileNames: fileNames.flatMap(name => name.endsWith('.vue') ? possibleExtensions.map(ext => `${name}.${ext}`) : [name])
93+
}
94+
},
8095
};
8196
const languageContext = vue.createLanguageContext(
8297
languageHost,

0 commit comments

Comments
 (0)