Skip to content

Commit

Permalink
feat: add vueCompilerOptions.experimentalComponentOptionsWrapper
Browse files Browse the repository at this point in the history
close #1517
  • Loading branch information
johnsoncodehk committed Sep 5, 2022
1 parent ebbc480 commit 0af9b91
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 66 deletions.
35 changes: 17 additions & 18 deletions packages/vue-language-core/schemas/vue-tsconfig.schema.json
Expand Up @@ -22,6 +22,23 @@
"default": false,
"markdownDescription": "Strict props, component type-checking in templates."
},
"experimentalComponentOptionsWrapper": {
"type": "array",
"default": [
"(await import('vue')).defineComponent(",
")"
],
"markdownDescription": "How to wrap option of `export default { ... }`? Default: `[\"(await import('vue')).default.extend(\", \")\"]` for target < 2.7, `[\"(await import('vue')).defineComponent(\", \")\"]` for target >= 2.7."
},
"experimentalComponentOptionsWrapperEnable": {
"enum": [
true,
false,
"onlyJs"
],
"default": "onlyJs",
"markdownDescription": "Enable `experimentalComponentOptionsWrapper`?"
},
"plugins": {
"type": "array",
"default": [],
Expand All @@ -40,24 +57,6 @@
],
"markdownDescription": "Run app in browser or uni-app"
},
"experimentalImplicitWrapComponentOptionsWithDefineComponent": {
"enum": [
true,
false,
"onlyJs"
],
"default": "onlyJs",
"markdownDescription": "Implicit wrap object literal component options export with `defineComponent()`."
},
"experimentalImplicitWrapComponentOptionsWithVue2Extend": {
"enum": [
true,
false,
"onlyJs"
],
"default": "onlyJs",
"markdownDescription": "Implicit wrap object literal component options export with `Vue.extend()`."
},
"experimentalDowngradePropsAndEmitsToSetupReturnOnScriptSetup": {
"enum": [
true,
Expand Down
48 changes: 7 additions & 41 deletions packages/vue-language-core/src/generators/script.ts
Expand Up @@ -7,8 +7,7 @@ import type { ScriptRanges } from '../parsers/scriptRanges';
import type { ScriptSetupRanges } from '../parsers/scriptSetupRanges';
import { collectCssVars, collectStyleCssClasses } from '../plugins/vue-tsx';
import { Sfc } from '../sourceFile';
import type { EmbeddedFileMappingData, TeleportMappingData } from '../types';
import { TextRange, VueCompilerOptions } from '../types';
import type { EmbeddedFileMappingData, TeleportMappingData, TextRange, _VueCompilerOptions } from '../types';
import { getSlotsPropertyName, getVueLibraryName } from '../utils/shared';
import { SearchTexts } from '../utils/string';
import { walkInterpolationFragment } from '../utils/transform';
Expand All @@ -28,7 +27,7 @@ export function generate(
cssScopedClasses: ReturnType<typeof collectStyleCssClasses>,
htmlGen: ReturnType<typeof templateGen['generate']> | undefined,
compilerOptions: ts.CompilerOptions,
vueCompilerOptions: VueCompilerOptions,
vueCompilerOptions: _VueCompilerOptions,
codeGen = new CodeGen<EmbeddedFileMappingData>(),
teleports: SourceMaps.Mapping<TeleportMappingData>[] = [],
) {
Expand Down Expand Up @@ -205,17 +204,13 @@ export function generate(
if (scriptRanges?.exportDefault) {
isExportRawObject = sfc.script.content.substring(scriptRanges.exportDefault.expression.start, scriptRanges.exportDefault.expression.end).startsWith('{');
}
const wrapMode = getImplicitWrapComponentOptionsMode(lang);
if (isExportRawObject && wrapMode && scriptRanges?.exportDefault) {
const warpperEnabled = vueCompilerOptions.experimentalComponentOptionsWrapperEnable === true
|| (vueCompilerOptions.experimentalComponentOptionsWrapperEnable === 'onlyJs' && (lang === 'js' || lang === 'jsx'));
if (isExportRawObject && warpperEnabled && scriptRanges?.exportDefault) {
addVirtualCode('script', 0, scriptRanges.exportDefault.expression.start);
if (wrapMode === 'defineComponent') {
codeGen.addText(`(await import('${vueLibName}')).defineComponent(`);
}
else {
codeGen.addText(`(await import('vue')).default.extend(`);
}
codeGen.addText(vueCompilerOptions.experimentalComponentOptionsWrapper[0]);
addVirtualCode('script', scriptRanges.exportDefault.expression.start, scriptRanges.exportDefault.expression.end);
codeGen.addText(`)`);
codeGen.addText(vueCompilerOptions.experimentalComponentOptionsWrapper[1]);
addVirtualCode('script', scriptRanges.exportDefault.expression.end, sfc.script.content.length);
}
else {
Expand Down Expand Up @@ -786,35 +781,6 @@ export function generate(

return usageVars;
}
function getImplicitWrapComponentOptionsMode(lang: string) {

let shimComponentOptionsMode: 'defineComponent' | 'Vue.extend' | false = false;

if (
vueCompilerOptions.experimentalImplicitWrapComponentOptionsWithVue2Extend === 'onlyJs'
? lang === 'js' || lang === 'jsx'
: !!vueCompilerOptions.experimentalImplicitWrapComponentOptionsWithVue2Extend
) {
shimComponentOptionsMode = 'Vue.extend';
}
if (
vueCompilerOptions.experimentalImplicitWrapComponentOptionsWithDefineComponent === 'onlyJs'
? lang === 'js' || lang === 'jsx'
: !!vueCompilerOptions.experimentalImplicitWrapComponentOptionsWithDefineComponent
) {
shimComponentOptionsMode = 'defineComponent';
}

// true override 'onlyJs'
if (vueCompilerOptions.experimentalImplicitWrapComponentOptionsWithVue2Extend === true) {
shimComponentOptionsMode = 'Vue.extend';
}
if (vueCompilerOptions.experimentalImplicitWrapComponentOptionsWithDefineComponent === true) {
shimComponentOptionsMode = 'defineComponent';
}

return shimComponentOptionsMode;
}
}

// TODO: not working for overloads > n (n = 8)
Expand Down
4 changes: 2 additions & 2 deletions packages/vue-language-core/src/types.ts
Expand Up @@ -15,9 +15,9 @@ export interface _VueCompilerOptions {
plugins: string[];

// experimental
experimentalComponentOptionsWrapper: [string, string];
experimentalComponentOptionsWrapperEnable: boolean | 'onlyJs';
experimentalRuntimeMode: 'runtime-dom' | 'runtime-uni-app';
experimentalImplicitWrapComponentOptionsWithDefineComponent: boolean | 'onlyJs';
experimentalImplicitWrapComponentOptionsWithVue2Extend: boolean | 'onlyJs';
experimentalDowngradePropsAndEmitsToSetupReturnOnScriptSetup: boolean | 'onlyJs';
experimentalTemplateCompilerOptions: any;
experimentalTemplateCompilerOptionsRequirePath: string | undefined;
Expand Down
11 changes: 8 additions & 3 deletions packages/vue-language-core/src/utils/ts.ts
Expand Up @@ -71,17 +71,22 @@ function createParsedCommandLineBase(
}

export function getVueCompilerOptions(vueOptions: VueCompilerOptions): _VueCompilerOptions {
const target = vueOptions.target ?? 3;
return {
...vueOptions,

target: vueOptions.target ?? 3,
target,
strictTemplates: vueOptions.strictTemplates ?? false,
plugins: vueOptions.plugins ?? [],

// experimental
experimentalComponentOptionsWrapper: vueOptions.experimentalComponentOptionsWrapper ?? (
target >= 2.7
? [`(await import('vue')).defineComponent(`, `)`]
: [`(await import('vue')).default.extend(`, `)`]
),
experimentalComponentOptionsWrapperEnable: vueOptions.experimentalComponentOptionsWrapperEnable ?? 'onlyJs',
experimentalRuntimeMode: vueOptions.experimentalRuntimeMode ?? 'runtime-dom',
experimentalImplicitWrapComponentOptionsWithDefineComponent: vueOptions.experimentalImplicitWrapComponentOptionsWithDefineComponent ?? 'onlyJs',
experimentalImplicitWrapComponentOptionsWithVue2Extend: vueOptions.experimentalImplicitWrapComponentOptionsWithVue2Extend ?? 'onlyJs',
experimentalDowngradePropsAndEmitsToSetupReturnOnScriptSetup: vueOptions.experimentalDowngradePropsAndEmitsToSetupReturnOnScriptSetup ?? 'onlyJs',
experimentalTemplateCompilerOptions: vueOptions.experimentalTemplateCompilerOptions ?? {},
experimentalTemplateCompilerOptionsRequirePath: vueOptions.experimentalTemplateCompilerOptionsRequirePath ?? undefined,
Expand Down
4 changes: 2 additions & 2 deletions packages/vue-language-service/src/documentFeatures/format.ts
Expand Up @@ -80,14 +80,14 @@ export function register(context: DocumentServiceRuntimeContext) {

if (!start) {
const firstMapping = sourceMap.base.mappings.sort((a, b) => a.sourceRange.start - b.sourceRange.start)[0];
if (document.offsetAt(range.start) < firstMapping.sourceRange.start) {
if (firstMapping && document.offsetAt(range.start) < firstMapping.sourceRange.start) {
start = sourceMap.mappedDocument.positionAt(firstMapping.mappedRange.start);
}
}

if (!end) {
const lastMapping = sourceMap.base.mappings.sort((a, b) => b.sourceRange.start - a.sourceRange.start)[0];
if (document.offsetAt(range.end) > lastMapping.sourceRange.end) {
if (lastMapping && document.offsetAt(range.end) > lastMapping.sourceRange.end) {
end = sourceMap.mappedDocument.positionAt(lastMapping.mappedRange.end);
}
}
Expand Down

0 comments on commit 0af9b91

Please sign in to comment.