Skip to content

Commit b8ae905

Browse files
committed
feat: vueCompilerOptions.lib
close #2722
1 parent 068dfd7 commit b8ae905

File tree

8 files changed

+30
-33
lines changed

8 files changed

+30
-33
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
## Unreleased
44

5+
- feat: support for specify vue library name by `vueCompilerOptions.lib` option ([#2730](https://github.com/johnsoncodehk/volar/issues/2730))
56
- fix: avoid `<component :is>` type checking with string literal assignment ([#2725](https://github.com/johnsoncodehk/volar/issues/2725))
67
- fix: `<slot>` reporting false positive error when `strictTemplates` enabled ([#2726](https://github.com/johnsoncodehk/volar/issues/2726)) ([#2723](https://github.com/johnsoncodehk/volar/issues/2723))
78
- fix: error using custom directive: `Expected 2 arguments, but got 1.` ([#2730](https://github.com/johnsoncodehk/volar/issues/2730))

packages/vue-language-core/schemas/vue-tsconfig.schema.json

+4
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@
1919
"default": [ ".vue" ],
2020
"markdownDescription": "Valid file extensions that should be considered as regular Vue SFC, please note that you should not use this option separately for additional file extensions IDE support, see https://github.com/johnsoncodehk/volar/tree/master/packages/vscode-vue/README.md#custom-file-extensions."
2121
},
22+
"lib": {
23+
"default": "",
24+
"markdownDescription": "Specify module name for import regular types. (If empty, will use `@vue/runtime-dom` for target < 2.7, `vue` for target >= 2.7)"
25+
},
2226
"jsxSlots": {
2327
"type": "boolean",
2428
"default": false,

packages/vue-language-core/src/generators/script.ts

+19-20
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import type { ScriptSetupRanges } from '../parsers/scriptSetupRanges';
1111
import { collectCssVars, collectStyleCssClasses } from '../plugins/vue-tsx';
1212
import { Sfc } from '../types';
1313
import type { VueCompilerOptions } from '../types';
14-
import { getSlotsPropertyName, getVueLibraryName } from '../utils/shared';
14+
import { getSlotsPropertyName } from '../utils/shared';
1515
import { walkInterpolationFragment } from '../utils/transform';
1616
import * as sharedTypes from '../utils/directorySharedTypes';
1717
import * as muggle from 'muggle-string';
@@ -72,7 +72,6 @@ export function generate(
7272
//#endregion
7373

7474
const bypassDefineComponent = lang === 'js' || lang === 'jsx';
75-
const vueLibName = getVueLibraryName(vueCompilerOptions.target);
7675
const usedHelperTypes = {
7776
DefinePropsToOptions: false,
7877
mergePropDefaults: false,
@@ -116,11 +115,11 @@ export function generate(
116115
let usedPrettify = false;
117116
if (usedHelperTypes.DefinePropsToOptions) {
118117
if (compilerOptions.exactOptionalPropertyTypes) {
119-
codes.push(`type __VLS_TypePropsToRuntimeProps<T> = { [K in keyof T]-?: {} extends Pick<T, K> ? { type: import('${vueLibName}').PropType<T[K]> } : { type: import('${vueLibName}').PropType<T[K]>, required: true } };\n`);
118+
codes.push(`type __VLS_TypePropsToRuntimeProps<T> = { [K in keyof T]-?: {} extends Pick<T, K> ? { type: import('${vueCompilerOptions.lib}').PropType<T[K]> } : { type: import('${vueCompilerOptions.lib}').PropType<T[K]>, required: true } };\n`);
120119
}
121120
else {
122121
codes.push(`type __VLS_NonUndefinedable<T> = T extends undefined ? never : T;\n`);
123-
codes.push(`type __VLS_TypePropsToRuntimeProps<T> = { [K in keyof T]-?: {} extends Pick<T, K> ? { type: import('${vueLibName}').PropType<__VLS_NonUndefinedable<T[K]>> } : { type: import('${vueLibName}').PropType<T[K]>, required: true } };\n`);
122+
codes.push(`type __VLS_TypePropsToRuntimeProps<T> = { [K in keyof T]-?: {} extends Pick<T, K> ? { type: import('${vueCompilerOptions.lib}').PropType<__VLS_NonUndefinedable<T[K]>> } : { type: import('${vueCompilerOptions.lib}').PropType<T[K]>, required: true } };\n`);
124123
}
125124
}
126125
if (usedHelperTypes.mergePropDefaults) {
@@ -317,9 +316,9 @@ export function generate(
317316
codes.push('(\n');
318317
codes.push(
319318
`__VLS_props: typeof __VLS_setup['props']`,
320-
`& import('${vueLibName}').VNodeProps`,
321-
`& import('${vueLibName}').AllowedComponentProps`,
322-
`& import('${vueLibName}').ComponentCustomProps,\n`,
319+
`& import('${vueCompilerOptions.lib}').VNodeProps`,
320+
`& import('${vueCompilerOptions.lib}').AllowedComponentProps`,
321+
`& import('${vueCompilerOptions.lib}').ComponentCustomProps,\n`,
323322
);
324323
codes.push(`__VLS_ctx?: Pick<typeof __VLS_setup, 'attrs' | 'emit' | 'slots'>,\n`);
325324
codes.push('__VLS_setup = (() => {\n');
@@ -437,7 +436,7 @@ export function generate(
437436
codes.push('emit: typeof __VLS_emit');
438437
codes.push('};\n');
439438
codes.push('})(),\n');
440-
codes.push(`) => ({} as import('${vueLibName}').VNode & { __ctx?: typeof __VLS_setup }))`);
439+
codes.push(`) => ({} as import('${vueCompilerOptions.lib}').VNode & { __ctx?: typeof __VLS_setup }))`);
441440
}
442441
else if (!sfc.script) {
443442
// no script block, generate script setup code at root
@@ -484,20 +483,20 @@ export function generate(
484483
const definePropProposalB = sfc.scriptSetup.content.trimStart().startsWith('// @experimentalDefinePropProposal=johnsonEdition') || vueCompilerOptions.experimentalDefinePropProposal === 'johnsonEdition';
485484

486485
if (vueCompilerOptions.target >= 3.3) {
487-
codes.push(`const { defineProps, defineEmits, defineExpose, defineOptions, defineSlots, defineModel, withDefaults } = await import('${vueLibName}');\n`);
486+
codes.push(`const { defineProps, defineEmits, defineExpose, defineOptions, defineSlots, defineModel, withDefaults } = await import('${vueCompilerOptions.lib}');\n`);
488487
}
489488
if (definePropProposalA) {
490489
codes.push(`
491-
declare function defineProp<T>(name: string, options: { required: true } & Record<string, unknown>): import('${vueLibName}').ComputedRef<T>;
492-
declare function defineProp<T>(name: string, options: { default: any } & Record<string, unknown>): import('${vueLibName}').ComputedRef<T>;
493-
declare function defineProp<T>(name?: string, options?: any): import('${vueLibName}').ComputedRef<T | undefined>;
490+
declare function defineProp<T>(name: string, options: { required: true } & Record<string, unknown>): import('${vueCompilerOptions.lib}').ComputedRef<T>;
491+
declare function defineProp<T>(name: string, options: { default: any } & Record<string, unknown>): import('${vueCompilerOptions.lib}').ComputedRef<T>;
492+
declare function defineProp<T>(name?: string, options?: any): import('${vueCompilerOptions.lib}').ComputedRef<T | undefined>;
494493
`.trim() + '\n');
495494
}
496495
if (definePropProposalB) {
497496
codes.push(`
498-
declare function defineProp<T>(value: T | (() => T), required?: boolean, rest?: any): import('${vueLibName}').ComputedRef<T>;
499-
declare function defineProp<T>(value: T | (() => T) | undefined, required: true, rest?: any): import('${vueLibName}').ComputedRef<T>;
500-
declare function defineProp<T>(value?: T | (() => T), required?: boolean, rest?: any): import('${vueLibName}').ComputedRef<T | undefined>;
497+
declare function defineProp<T>(value: T | (() => T), required?: boolean, rest?: any): import('${vueCompilerOptions.lib}').ComputedRef<T>;
498+
declare function defineProp<T>(value: T | (() => T) | undefined, required: true, rest?: any): import('${vueCompilerOptions.lib}').ComputedRef<T>;
499+
declare function defineProp<T>(value?: T | (() => T), required?: boolean, rest?: any): import('${vueCompilerOptions.lib}').ComputedRef<T | undefined>;
501500
`.trim() + '\n');
502501
}
503502

@@ -519,7 +518,7 @@ declare function defineProp<T>(value?: T | (() => T), required?: boolean, rest?:
519518
codes.push(`{\n`);
520519
}
521520
else {
522-
codes.push(`const __VLS_publicComponent = (await import('${vueLibName}')).defineComponent({\n`);
521+
codes.push(`const __VLS_publicComponent = (await import('${vueCompilerOptions.lib}')).defineComponent({\n`);
523522
}
524523

525524
if (scriptSetupRanges.defineProp.length) {
@@ -552,10 +551,10 @@ declare function defineProp<T>(value?: T | (() => T), required?: boolean, rest?:
552551
}
553552

554553
if (defineProp.required) {
555-
codes.push(`{ required: true, type: import('${vueLibName}').PropType<${type}> },\n`);
554+
codes.push(`{ required: true, type: import('${vueCompilerOptions.lib}').PropType<${type}> },\n`);
556555
}
557556
else {
558-
codes.push(`import('${vueLibName}').PropType<${type}>,\n`);
557+
codes.push(`import('${vueCompilerOptions.lib}').PropType<${type}>,\n`);
559558
}
560559
}
561560
codes.push(`},\n`);
@@ -714,7 +713,7 @@ declare function defineProp<T>(value?: T | (() => T), required?: boolean, rest?:
714713

715714
if (sfc.scriptSetup && scriptSetupRanges) {
716715

717-
codes.push(`const __VLS_internalComponent = (await import('${vueLibName}')).defineComponent({\n`);
716+
codes.push(`const __VLS_internalComponent = (await import('${vueCompilerOptions.lib}')).defineComponent({\n`);
718717
codes.push(`setup() {\n`);
719718
codes.push(`return {\n`);
720719
// fill ctx from props
@@ -776,7 +775,7 @@ declare function defineProp<T>(value?: T | (() => T), required?: boolean, rest?:
776775
codes.push(`let __VLS_internalComponent!: typeof import('./${path.basename(fileName)}')['default'];\n`);
777776
}
778777
else {
779-
codes.push(`const __VLS_internalComponent = (await import('${vueLibName}')).defineComponent({});\n`);
778+
codes.push(`const __VLS_internalComponent = (await import('${vueCompilerOptions.lib}')).defineComponent({});\n`);
780779
}
781780
}
782781
function generateExportOptions() {

packages/vue-language-core/src/languageModule.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ export function createLanguageModules(
1919
compilerOptions,
2020
vueCompilerOptions,
2121
);
22-
const sharedTypesSnapshot = ts.ScriptSnapshot.fromString(sharedTypes.getTypesCode(vueCompilerOptions.target, vueCompilerOptions));
22+
const sharedTypesSnapshot = ts.ScriptSnapshot.fromString(sharedTypes.getTypesCode(vueCompilerOptions));
2323
const languageModule: embedded.LanguageModule = {
2424
createFile(fileName, snapshot, languageId) {
2525
if (

packages/vue-language-core/src/types.ts

+1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ export type RawVueCompilerOptions = Partial<Omit<VueCompilerOptions, 'target' |
1818

1919
export interface VueCompilerOptions {
2020
target: number;
21+
lib: string;
2122
extensions: string[];
2223
jsxSlots: boolean;
2324
strictTemplates: boolean;

packages/vue-language-core/src/utils/directorySharedTypes.ts

+3-8
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { VueCompilerOptions } from '../types';
22
import { getSlotsPropertyName } from './shared';
3-
import { getVueLibraryName } from './shared';
43
import type * as ts from 'typescript/lib/tsserverlibrary';
54

65
export const baseName = '__VLS_types.d.ts';
@@ -12,18 +11,14 @@ export function getImportName(compilerOptions: ts.CompilerOptions) {
1211
return './__VLS_types.js';
1312
};
1413

15-
export function getTypesCode(
16-
vueVersion: number,
17-
vueCompilerOptions: VueCompilerOptions,
18-
) {
19-
const libName = getVueLibraryName(vueVersion);
14+
export function getTypesCode(vueCompilerOptions: VueCompilerOptions) {
2015
return `
2116
// @ts-nocheck
2217
import type {
2318
ObjectDirective,
2419
FunctionDirective,
2520
VNode,
26-
} from '${libName}';
21+
} from '${vueCompilerOptions.lib}';
2722
2823
export type IntrinsicElements = PickNotAny<import('vue/jsx-runtime').JSX.IntrinsicElements, PickNotAny<JSX.IntrinsicElements, Record<string, any>>>;
2924
export type Element = PickNotAny<import('vue/jsx-runtime').JSX.Element, JSX.Element>;
@@ -47,7 +42,7 @@ export type GlobalComponents =
4742
& PickNotAny<import('@vue/runtime-core').GlobalComponents, {}>
4843
// @ts-ignore
4944
& PickNotAny<import('@vue/runtime-dom').GlobalComponents, {}>
50-
& Pick<typeof import('${libName}'),
45+
& Pick<typeof import('${vueCompilerOptions.lib}'),
5146
// @ts-ignore
5247
'Transition'
5348
| 'TransitionGroup'
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,3 @@
11
export function getSlotsPropertyName(vueVersion: number) {
22
return vueVersion < 3 ? '$scopedSlots' : '$slots';
33
}
4-
5-
export function getVueLibraryName(vueVersion: number) {
6-
return vueVersion < 2.7 ? '@vue/runtime-dom' : 'vue';
7-
}

packages/vue-language-core/src/utils/ts.ts

+1
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,7 @@ export function resolveVueCompilerOptions(vueOptions: Partial<VueCompilerOptions
176176
...vueOptions,
177177
target,
178178
extensions: vueOptions.extensions ?? ['.vue'],
179+
lib: vueOptions.lib || (target < 2.7 ? '@vue/runtime-dom' : 'vue'),
179180
jsxSlots: vueOptions.jsxSlots ?? false,
180181
strictTemplates: vueOptions.strictTemplates ?? false,
181182
skipTemplateCodegen: vueOptions.skipTemplateCodegen ?? false,

0 commit comments

Comments
 (0)