Skip to content

Commit 07bc594

Browse files
authored
feat: generate global types file into node_modules/.vue-global-types (#4752)
1 parent d18cade commit 07bc594

File tree

6 files changed

+52
-16
lines changed

6 files changed

+52
-16
lines changed

packages/component-meta/lib/base.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -135,18 +135,27 @@ export function baseCreate(
135135
const { languageServiceHost } = createLanguageServiceHost(ts, ts.sys, language, s => s, projectHost);
136136
const tsLs = ts.createLanguageService(languageServiceHost);
137137

138+
const directoryExists = languageServiceHost.directoryExists?.bind(languageServiceHost);
138139
const fileExists = languageServiceHost.fileExists.bind(languageServiceHost);
139140
const getScriptSnapshot = languageServiceHost.getScriptSnapshot.bind(languageServiceHost);
140-
const globalTypesName = `__global_types_${commandLine.vueOptions.target}_${commandLine.vueOptions.strictTemplates}.d.ts`;
141+
const globalTypesName = `${commandLine.vueOptions.lib}_${commandLine.vueOptions.target}_${commandLine.vueOptions.strictTemplates}.d.ts`;
141142
const snapshots = new Map<string, ts.IScriptSnapshot>();
143+
if (directoryExists) {
144+
languageServiceHost.directoryExists = path => {
145+
if (path.endsWith('.vue-global-types')) {
146+
return true;
147+
}
148+
return directoryExists(path);
149+
};
150+
}
142151
languageServiceHost.fileExists = path => {
143152
if (path.endsWith(globalTypesName)) {
144153
return true;
145154
}
146155
return fileExists(path);
147156
};
148157
languageServiceHost.getScriptSnapshot = path => {
149-
if (path.endsWith(globalTypesName)) {
158+
if (path.endsWith(`.vue-global-types/${globalTypesName}`) || path.endsWith(`.vue-global-types\\${globalTypesName}`)) {
150159
if (!snapshots.has(path)) {
151160
const contents = vue.generateGlobalTypes(commandLine.vueOptions.lib, commandLine.vueOptions.target, commandLine.vueOptions.strictTemplates);
152161
snapshots.set(path, {

packages/language-core/lib/codegen/script/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ export interface ScriptCodegenOptions {
5151
export function* generateScript(options: ScriptCodegenOptions): Generator<Code, ScriptCodegenContext> {
5252
const ctx = createScriptCodegenContext(options);
5353

54-
yield `/// <reference types="${options.vueCompilerOptions.lib}/dist/__global_types_${options.vueCompilerOptions.target}_${options.vueCompilerOptions.strictTemplates}.d.ts" />${newLine}`;
54+
yield `/// <reference types=".vue-global-types/${options.vueCompilerOptions.lib}_${options.vueCompilerOptions.target}_${options.vueCompilerOptions.strictTemplates}.d.ts" />${newLine}`;
5555

5656
if (options.sfc.script?.src) {
5757
yield* generateSrc(options.sfc.script, options.sfc.script.src);

packages/language-server/lib/initialize.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -52,18 +52,27 @@ export function initialize(
5252
project.vue = { compilerOptions: vueCompilerOptions };
5353

5454
if (project.typescript) {
55-
const globalTypesName = `__global_types_${vueCompilerOptions.target}_${vueCompilerOptions.strictTemplates}.d.ts`;
55+
const globalTypesName = `${vueCompilerOptions.lib}_${vueCompilerOptions.target}_${vueCompilerOptions.strictTemplates}.d.ts`;
56+
const directoryExists = project.typescript.languageServiceHost.directoryExists?.bind(project.typescript.languageServiceHost);
5657
const fileExists = project.typescript.languageServiceHost.fileExists.bind(project.typescript.languageServiceHost);
5758
const getScriptSnapshot = project.typescript.languageServiceHost.getScriptSnapshot.bind(project.typescript.languageServiceHost);
5859
const snapshots = new Map<string, ts.IScriptSnapshot>();
60+
if (directoryExists) {
61+
project.typescript.languageServiceHost.directoryExists = path => {
62+
if (path.endsWith('.vue-global-types')) {
63+
return true;
64+
}
65+
return directoryExists!(path);
66+
};
67+
}
5968
project.typescript.languageServiceHost.fileExists = path => {
6069
if (path.endsWith(globalTypesName)) {
6170
return true;
6271
}
6372
return fileExists(path);
6473
};
6574
project.typescript.languageServiceHost.getScriptSnapshot = path => {
66-
if (path.endsWith(globalTypesName)) {
75+
if (path.endsWith(`.vue-global-types/${globalTypesName}`) || path.endsWith(`.vue-global-types\\${globalTypesName}`)) {
6776
if (!snapshots.has(path)) {
6877
const contents = generateGlobalTypes(vueCompilerOptions.lib, vueCompilerOptions.target, vueCompilerOptions.strictTemplates);
6978
snapshots.set(path, {

packages/tsc/index.ts

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { runTsc } from '@volar/typescript/lib/quickstart/runTsc';
2+
import * as path from 'path';
23
import * as vue from '@vue/language-core';
34

45
const windowsPathReg = /\\/g;
@@ -22,12 +23,17 @@ export function run(tscPath = require.resolve('typescript/lib/tsc')) {
2223
&& runExtensions.every(ext => allExtensions.includes(ext))
2324
) {
2425
try {
25-
const rootDir = typeof configFilePath === 'string'
26+
let dir = typeof configFilePath === 'string'
2627
? configFilePath
2728
: options.host?.getCurrentDirectory() ?? ts.sys.getCurrentDirectory();
28-
const libDir = require.resolve(`${vueOptions.lib}/package.json`, { paths: [rootDir] })
29-
.slice(0, -'package.json'.length);
30-
const globalTypesPath = `${libDir}dist/__global_types_${vueOptions.target}_${vueOptions.strictTemplates}.d.ts`;
29+
while (!ts.sys.directoryExists(path.resolve(dir, 'node_modules'))) {
30+
const parentDir = path.resolve(dir, '..');
31+
if (dir === parentDir) {
32+
throw 0;
33+
}
34+
dir = parentDir;
35+
}
36+
const globalTypesPath = path.resolve(dir, `node_modules/.vue-global-types/${vueOptions.lib}_${vueOptions.target}_${vueOptions.strictTemplates}.d.ts`);
3137
const globalTypesContents = vue.generateGlobalTypes(vueOptions.lib, vueOptions.target, vueOptions.strictTemplates);
3238
ts.sys.writeFile(globalTypesPath, globalTypesContents);
3339
} catch { }

packages/tsc/tests/dts.spec.ts

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,17 @@ describe('vue-tsc-dts', () => {
3232
: vue.resolveVueCompilerOptions({ extensions: ['.vue', '.cext'] });
3333

3434
try {
35-
const rootDir = typeof configFilePath === 'string'
35+
let dir = typeof configFilePath === 'string'
3636
? configFilePath
3737
: options.host?.getCurrentDirectory() ?? ts.sys.getCurrentDirectory();
38-
const libDir = require.resolve(`${vueOptions.lib}/package.json`, { paths: [rootDir] })
39-
.slice(0, -'package.json'.length);
40-
const globalTypesPath = `${libDir}dist/__global_types_${vueOptions.target}_${vueOptions.strictTemplates}.d.ts`;
38+
while (!ts.sys.directoryExists(path.resolve(dir, 'node_modules'))) {
39+
const parentDir = path.resolve(dir, '..');
40+
if (dir === parentDir) {
41+
throw 0;
42+
}
43+
dir = parentDir;
44+
}
45+
const globalTypesPath = path.resolve(dir, `node_modules/.vue-global-types/${vueOptions.lib}_${vueOptions.target}_${vueOptions.strictTemplates}.d.ts`);
4146
const globalTypesContents = vue.generateGlobalTypes(vueOptions.lib, vueOptions.target, vueOptions.strictTemplates);
4247
ts.sys.writeFile(globalTypesPath, globalTypesContents);
4348
} catch { }

packages/typescript-plugin/index.ts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { createLanguageServicePlugin } from '@volar/typescript/lib/quickstart/createLanguageServicePlugin';
2+
import * as path from 'path';
23
import * as vue from '@vue/language-core';
34
import { proxyLanguageServiceForVue } from './lib/common';
45
import { startNamedPipeServer } from './lib/server';
@@ -61,9 +62,15 @@ const plugin: ts.server.PluginModuleFactory = mods => {
6162
const options = vueCompilerOptions.get(proj);
6263
if (updateLevel >= 1 && options) {
6364
try {
64-
const libDir = require.resolve(`${options.lib}/package.json`, { paths: [proj.getCurrentDirectory()] })
65-
.slice(0, -'package.json'.length);
66-
const globalTypesPath = `${libDir}dist/__global_types_${options.target}_${options.strictTemplates}.d.ts`;
65+
let dir = proj.getCurrentDirectory();
66+
while (!proj.directoryExists(path.resolve(dir, 'node_modules'))) {
67+
const parentDir = path.resolve(dir, '..');
68+
if (dir === parentDir) {
69+
throw 0;
70+
}
71+
dir = parentDir;
72+
}
73+
const globalTypesPath = path.resolve(dir, `node_modules/.vue-global-types/${options.lib}_${options.target}_${options.strictTemplates}.d.ts`);
6774
const globalTypesContents = vue.generateGlobalTypes(options.lib, options.target, options.strictTemplates);
6875
proj.writeFile(globalTypesPath, globalTypesContents);
6976
} catch { }

0 commit comments

Comments
 (0)