Skip to content

Commit

Permalink
perf(tsc): support vue files with project reference delcaration
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
blake-newman committed Nov 23, 2023
1 parent a03aae4 commit f835ad7
Showing 1 changed file with 15 additions and 1 deletion.
16 changes: 15 additions & 1 deletion packages/tsc/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ export function createProgram(options: ts.CreateProgramOptions) {
modifiedTime: number,
scriptSnapshot: ts.IScriptSnapshot,
}>();
const languageHost: vue.TypeScriptLanguageHost = {
const languageHost: vue.TypeScriptLanguageHost & Partial<ts.LanguageServiceHost> = {
workspacePath: ctx.options.host!.getCurrentDirectory().replace(windowsPathReg, '/'),
rootPath: ctx.options.host!.getCurrentDirectory().replace(windowsPathReg, '/'),
getCompilationSettings: () => ctx.options.options,
Expand All @@ -77,6 +77,20 @@ export function createProgram(options: ts.CreateProgramOptions) {
},
getProjectReferences: () => ctx.options.projectReferences,
getCancellationToken: ctx.options.host!.getCancellationToken ? () => ctx.options.host!.getCancellationToken!() : undefined,
realpath(path) {
const realpath = ctx.options.host!.realpath! ?? ts.sys.realpath
const match = /^(?<path>.+\.vue)\.(?<extension>.+)$/.exec(path)
return match?.groups ? `${realpath(match.groups.path)}.${match.groups.extension}` : realpath(path)
},
getParsedCommandLine: (path) => {
const possibleExtensions = ['ts', 'tsx']
const commandLine = ts.getParsedCommandLineOfConfigFile(path, undefined, ts.sys as any)
if (!commandLine) return undefined
return {
...commandLine,
fileNames: commandLine.fileNames.flatMap(name => name.endsWith('.vue') ? possibleExtensions.map(ext => `${name}.${ext}`) : [name])
}
},
};
const languageContext = vue.createLanguageContext(
languageHost,
Expand Down

0 comments on commit f835ad7

Please sign in to comment.