@vue/compiler-sfc 3.2.41 → 3.2.42
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/compiler-sfc.cjs.js +218 -134
- package/dist/compiler-sfc.d.ts +4 -8
- package/dist/compiler-sfc.esm-browser.js +423 -300
- package/package.json +6 -6
package/dist/compiler-sfc.cjs.js
CHANGED
|
@@ -119,7 +119,8 @@ function genVarName(id, raw, isProd) {
|
|
|
119
119
|
return hashSum(id + raw);
|
|
120
120
|
}
|
|
121
121
|
else {
|
|
122
|
-
|
|
122
|
+
// escape ASCII Punctuation & Symbols
|
|
123
|
+
return `${id}-${raw.replace(/[ !"#$%&'()*+,./:;<=>?@[\\\]^`{|}~]/g, s => `\\${s}`)}`;
|
|
123
124
|
}
|
|
124
125
|
}
|
|
125
126
|
function normalizeExpression(exp) {
|
|
@@ -3537,7 +3538,6 @@ function compileScript(sfc, options) {
|
|
|
3537
3538
|
const bindingMetadata = {};
|
|
3538
3539
|
const helperImports = new Set();
|
|
3539
3540
|
const userImports = Object.create(null);
|
|
3540
|
-
const userImportAlias = Object.create(null);
|
|
3541
3541
|
const scriptBindings = Object.create(null);
|
|
3542
3542
|
const setupBindings = Object.create(null);
|
|
3543
3543
|
let defaultExport;
|
|
@@ -3588,10 +3588,24 @@ function compileScript(sfc, options) {
|
|
|
3588
3588
|
function error(msg, node, end = node.end + startOffset) {
|
|
3589
3589
|
throw new Error(`[@vue/compiler-sfc] ${msg}\n\n${sfc.filename}\n${shared.generateCodeFrame(source, node.start + startOffset, end)}`);
|
|
3590
3590
|
}
|
|
3591
|
-
function
|
|
3592
|
-
|
|
3593
|
-
|
|
3591
|
+
function hoistNode(node) {
|
|
3592
|
+
const start = node.start + startOffset;
|
|
3593
|
+
let end = node.end + startOffset;
|
|
3594
|
+
// locate comment
|
|
3595
|
+
if (node.trailingComments && node.trailingComments.length > 0) {
|
|
3596
|
+
const lastCommentNode = node.trailingComments[node.trailingComments.length - 1];
|
|
3597
|
+
end = lastCommentNode.end + startOffset;
|
|
3598
|
+
}
|
|
3599
|
+
// locate the end of whitespace between this statement and the next
|
|
3600
|
+
while (end <= source.length) {
|
|
3601
|
+
if (!/\s/.test(source.charAt(end))) {
|
|
3602
|
+
break;
|
|
3603
|
+
}
|
|
3604
|
+
end++;
|
|
3594
3605
|
}
|
|
3606
|
+
s.move(start, end, 0);
|
|
3607
|
+
}
|
|
3608
|
+
function registerUserImport(source, local, imported, isType, isFromSetup, needTemplateUsageCheck) {
|
|
3595
3609
|
// template usage check is only needed in non-inline mode, so we can skip
|
|
3596
3610
|
// the work if inlineTemplate is true.
|
|
3597
3611
|
let isUsedInTemplate = needTemplateUsageCheck;
|
|
@@ -3605,6 +3619,7 @@ function compileScript(sfc, options) {
|
|
|
3605
3619
|
userImports[local] = {
|
|
3606
3620
|
isType,
|
|
3607
3621
|
imported: imported || 'default',
|
|
3622
|
+
local,
|
|
3608
3623
|
source,
|
|
3609
3624
|
isFromSetup,
|
|
3610
3625
|
isUsedInTemplate
|
|
@@ -3638,12 +3653,10 @@ function compileScript(sfc, options) {
|
|
|
3638
3653
|
// props destructure - handle compilation sugar
|
|
3639
3654
|
for (const prop of declId.properties) {
|
|
3640
3655
|
if (prop.type === 'ObjectProperty') {
|
|
3641
|
-
|
|
3656
|
+
const propKey = resolveObjectKey(prop.key, prop.computed);
|
|
3657
|
+
if (!propKey) {
|
|
3642
3658
|
error(`${DEFINE_PROPS}() destructure cannot use computed key.`, prop.key);
|
|
3643
3659
|
}
|
|
3644
|
-
const propKey = prop.key.type === 'StringLiteral'
|
|
3645
|
-
? prop.key.value
|
|
3646
|
-
: prop.key.name;
|
|
3647
3660
|
if (prop.value.type === 'AssignmentPattern') {
|
|
3648
3661
|
// default value { foo = 123 }
|
|
3649
3662
|
const { left, right } = prop.value;
|
|
@@ -3724,10 +3737,67 @@ function compileScript(sfc, options) {
|
|
|
3724
3737
|
}
|
|
3725
3738
|
}
|
|
3726
3739
|
if (declId) {
|
|
3727
|
-
emitIdentifier =
|
|
3740
|
+
emitIdentifier =
|
|
3741
|
+
declId.type === 'Identifier'
|
|
3742
|
+
? declId.name
|
|
3743
|
+
: scriptSetup.content.slice(declId.start, declId.end);
|
|
3728
3744
|
}
|
|
3729
3745
|
return true;
|
|
3730
3746
|
}
|
|
3747
|
+
function getAstBody() {
|
|
3748
|
+
return scriptAst
|
|
3749
|
+
? [...scriptSetupAst.body, ...scriptAst.body]
|
|
3750
|
+
: scriptSetupAst.body;
|
|
3751
|
+
}
|
|
3752
|
+
function resolveExtendsType(node, qualifier, cache = []) {
|
|
3753
|
+
if (node.type === 'TSInterfaceDeclaration' && node.extends) {
|
|
3754
|
+
node.extends.forEach(extend => {
|
|
3755
|
+
if (extend.type === 'TSExpressionWithTypeArguments' &&
|
|
3756
|
+
extend.expression.type === 'Identifier') {
|
|
3757
|
+
const body = getAstBody();
|
|
3758
|
+
for (const node of body) {
|
|
3759
|
+
const qualified = isQualifiedType(node, qualifier, extend.expression.name);
|
|
3760
|
+
if (qualified) {
|
|
3761
|
+
cache.push(qualified);
|
|
3762
|
+
resolveExtendsType(node, qualifier, cache);
|
|
3763
|
+
return cache;
|
|
3764
|
+
}
|
|
3765
|
+
}
|
|
3766
|
+
}
|
|
3767
|
+
});
|
|
3768
|
+
}
|
|
3769
|
+
return cache;
|
|
3770
|
+
}
|
|
3771
|
+
function isQualifiedType(node, qualifier, refName) {
|
|
3772
|
+
if (node.type === 'TSInterfaceDeclaration' && node.id.name === refName) {
|
|
3773
|
+
return node.body;
|
|
3774
|
+
}
|
|
3775
|
+
else if (node.type === 'TSTypeAliasDeclaration' &&
|
|
3776
|
+
node.id.name === refName &&
|
|
3777
|
+
qualifier(node.typeAnnotation)) {
|
|
3778
|
+
return node.typeAnnotation;
|
|
3779
|
+
}
|
|
3780
|
+
else if (node.type === 'ExportNamedDeclaration' && node.declaration) {
|
|
3781
|
+
return isQualifiedType(node.declaration, qualifier, refName);
|
|
3782
|
+
}
|
|
3783
|
+
}
|
|
3784
|
+
// filter all extends types to keep the override declaration
|
|
3785
|
+
function filterExtendsType(extendsTypes, bodies) {
|
|
3786
|
+
extendsTypes.forEach(extend => {
|
|
3787
|
+
const body = extend.body;
|
|
3788
|
+
body.forEach(newBody => {
|
|
3789
|
+
if (newBody.type === 'TSPropertySignature' &&
|
|
3790
|
+
newBody.key.type === 'Identifier') {
|
|
3791
|
+
const name = newBody.key.name;
|
|
3792
|
+
const hasOverride = bodies.some(seenBody => seenBody.type === 'TSPropertySignature' &&
|
|
3793
|
+
seenBody.key.type === 'Identifier' &&
|
|
3794
|
+
seenBody.key.name === name);
|
|
3795
|
+
if (!hasOverride)
|
|
3796
|
+
bodies.push(newBody);
|
|
3797
|
+
}
|
|
3798
|
+
});
|
|
3799
|
+
});
|
|
3800
|
+
}
|
|
3731
3801
|
function resolveQualifiedType(node, qualifier) {
|
|
3732
3802
|
if (qualifier(node)) {
|
|
3733
3803
|
return node;
|
|
@@ -3735,26 +3805,16 @@ function compileScript(sfc, options) {
|
|
|
3735
3805
|
if (node.type === 'TSTypeReference' &&
|
|
3736
3806
|
node.typeName.type === 'Identifier') {
|
|
3737
3807
|
const refName = node.typeName.name;
|
|
3738
|
-
const
|
|
3739
|
-
if (node.type === 'TSInterfaceDeclaration' &&
|
|
3740
|
-
node.id.name === refName) {
|
|
3741
|
-
return node.body;
|
|
3742
|
-
}
|
|
3743
|
-
else if (node.type === 'TSTypeAliasDeclaration' &&
|
|
3744
|
-
node.id.name === refName &&
|
|
3745
|
-
qualifier(node.typeAnnotation)) {
|
|
3746
|
-
return node.typeAnnotation;
|
|
3747
|
-
}
|
|
3748
|
-
else if (node.type === 'ExportNamedDeclaration' && node.declaration) {
|
|
3749
|
-
return isQualifiedType(node.declaration);
|
|
3750
|
-
}
|
|
3751
|
-
};
|
|
3752
|
-
const body = scriptAst
|
|
3753
|
-
? [...scriptSetupAst.body, ...scriptAst.body]
|
|
3754
|
-
: scriptSetupAst.body;
|
|
3808
|
+
const body = getAstBody();
|
|
3755
3809
|
for (const node of body) {
|
|
3756
|
-
|
|
3810
|
+
let qualified = isQualifiedType(node, qualifier, refName);
|
|
3757
3811
|
if (qualified) {
|
|
3812
|
+
const extendsTypes = resolveExtendsType(node, qualifier);
|
|
3813
|
+
if (extendsTypes.length) {
|
|
3814
|
+
const bodies = [...qualified.body];
|
|
3815
|
+
filterExtendsType(extendsTypes, bodies);
|
|
3816
|
+
qualified.body = bodies;
|
|
3817
|
+
}
|
|
3758
3818
|
return qualified;
|
|
3759
3819
|
}
|
|
3760
3820
|
}
|
|
@@ -3818,7 +3878,8 @@ function compileScript(sfc, options) {
|
|
|
3818
3878
|
function hasStaticWithDefaults() {
|
|
3819
3879
|
return (propsRuntimeDefaults &&
|
|
3820
3880
|
propsRuntimeDefaults.type === 'ObjectExpression' &&
|
|
3821
|
-
propsRuntimeDefaults.properties.every(node => (node.type === 'ObjectProperty' &&
|
|
3881
|
+
propsRuntimeDefaults.properties.every(node => (node.type === 'ObjectProperty' &&
|
|
3882
|
+
(!node.computed || node.key.type.endsWith('Literal'))) ||
|
|
3822
3883
|
node.type === 'ObjectMethod'));
|
|
3823
3884
|
}
|
|
3824
3885
|
function genRuntimeProps(props) {
|
|
@@ -3837,14 +3898,18 @@ function compileScript(sfc, options) {
|
|
|
3837
3898
|
defaultString = `default: ${destructured}`;
|
|
3838
3899
|
}
|
|
3839
3900
|
else if (hasStaticDefaults) {
|
|
3840
|
-
const prop = propsRuntimeDefaults.properties.find(
|
|
3901
|
+
const prop = propsRuntimeDefaults.properties.find(node => {
|
|
3902
|
+
if (node.type === 'SpreadElement')
|
|
3903
|
+
return false;
|
|
3904
|
+
return resolveObjectKey(node.key, node.computed) === key;
|
|
3905
|
+
});
|
|
3841
3906
|
if (prop) {
|
|
3842
3907
|
if (prop.type === 'ObjectProperty') {
|
|
3843
3908
|
// prop has corresponding static default value
|
|
3844
3909
|
defaultString = `default: ${scriptSetupSource.slice(prop.value.start, prop.value.end)}`;
|
|
3845
3910
|
}
|
|
3846
3911
|
else {
|
|
3847
|
-
defaultString = `default() ${scriptSetupSource.slice(prop.body.start, prop.body.end)}`;
|
|
3912
|
+
defaultString = `${prop.async ? 'async ' : ''}${prop.kind !== 'method' ? `${prop.kind} ` : ''}default() ${scriptSetupSource.slice(prop.body.start, prop.body.end)}`;
|
|
3848
3913
|
}
|
|
3849
3914
|
}
|
|
3850
3915
|
}
|
|
@@ -3887,7 +3952,12 @@ function compileScript(sfc, options) {
|
|
|
3887
3952
|
m.type === 'TSMethodSignature') &&
|
|
3888
3953
|
m.typeAnnotation &&
|
|
3889
3954
|
m.key.type === 'Identifier') {
|
|
3890
|
-
if (propsRuntimeDefaults.properties.some(
|
|
3955
|
+
if (propsRuntimeDefaults.properties.some(p => {
|
|
3956
|
+
if (p.type === 'SpreadElement')
|
|
3957
|
+
return false;
|
|
3958
|
+
return (resolveObjectKey(p.key, p.computed) ===
|
|
3959
|
+
m.key.name);
|
|
3960
|
+
})) {
|
|
3891
3961
|
res +=
|
|
3892
3962
|
m.key.name +
|
|
3893
3963
|
(m.type === 'TSMethodSignature' ? '()' : '') +
|
|
@@ -3906,13 +3976,22 @@ function compileScript(sfc, options) {
|
|
|
3906
3976
|
return scriptSetupSource.slice(node.start, node.end);
|
|
3907
3977
|
}
|
|
3908
3978
|
}
|
|
3909
|
-
//
|
|
3910
|
-
|
|
3911
|
-
|
|
3912
|
-
scriptAst = parse(script.content, {
|
|
3979
|
+
// 0. parse both <script> and <script setup> blocks
|
|
3980
|
+
const scriptAst = script &&
|
|
3981
|
+
parse(script.content, {
|
|
3913
3982
|
plugins,
|
|
3914
3983
|
sourceType: 'module'
|
|
3915
3984
|
}, scriptStartOffset);
|
|
3985
|
+
const scriptSetupAst = parse(scriptSetup.content, {
|
|
3986
|
+
plugins: [
|
|
3987
|
+
...plugins,
|
|
3988
|
+
// allow top level await but only inside <script setup>
|
|
3989
|
+
'topLevelAwait'
|
|
3990
|
+
],
|
|
3991
|
+
sourceType: 'module'
|
|
3992
|
+
}, startOffset);
|
|
3993
|
+
// 1.1 walk import delcarations of <script>
|
|
3994
|
+
if (scriptAst) {
|
|
3916
3995
|
for (const node of scriptAst.body) {
|
|
3917
3996
|
if (node.type === 'ImportDeclaration') {
|
|
3918
3997
|
// record imports for dedupe
|
|
@@ -3925,7 +4004,75 @@ function compileScript(sfc, options) {
|
|
|
3925
4004
|
specifier.importKind === 'type'), false, !options.inlineTemplate);
|
|
3926
4005
|
}
|
|
3927
4006
|
}
|
|
3928
|
-
|
|
4007
|
+
}
|
|
4008
|
+
}
|
|
4009
|
+
// 1.2 walk import declarations of <script setup>
|
|
4010
|
+
for (const node of scriptSetupAst.body) {
|
|
4011
|
+
if (node.type === 'ImportDeclaration') {
|
|
4012
|
+
// import declarations are moved to top
|
|
4013
|
+
hoistNode(node);
|
|
4014
|
+
// dedupe imports
|
|
4015
|
+
let removed = 0;
|
|
4016
|
+
const removeSpecifier = (i) => {
|
|
4017
|
+
const removeLeft = i > removed;
|
|
4018
|
+
removed++;
|
|
4019
|
+
const current = node.specifiers[i];
|
|
4020
|
+
const next = node.specifiers[i + 1];
|
|
4021
|
+
s.remove(removeLeft
|
|
4022
|
+
? node.specifiers[i - 1].end + startOffset
|
|
4023
|
+
: current.start + startOffset, next && !removeLeft
|
|
4024
|
+
? next.start + startOffset
|
|
4025
|
+
: current.end + startOffset);
|
|
4026
|
+
};
|
|
4027
|
+
for (let i = 0; i < node.specifiers.length; i++) {
|
|
4028
|
+
const specifier = node.specifiers[i];
|
|
4029
|
+
const local = specifier.local.name;
|
|
4030
|
+
let imported = specifier.type === 'ImportSpecifier' &&
|
|
4031
|
+
specifier.imported.type === 'Identifier' &&
|
|
4032
|
+
specifier.imported.name;
|
|
4033
|
+
if (specifier.type === 'ImportNamespaceSpecifier') {
|
|
4034
|
+
imported = '*';
|
|
4035
|
+
}
|
|
4036
|
+
const source = node.source.value;
|
|
4037
|
+
const existing = userImports[local];
|
|
4038
|
+
if (source === 'vue' &&
|
|
4039
|
+
(imported === DEFINE_PROPS ||
|
|
4040
|
+
imported === DEFINE_EMITS ||
|
|
4041
|
+
imported === DEFINE_EXPOSE)) {
|
|
4042
|
+
warnOnce(`\`${imported}\` is a compiler macro and no longer needs to be imported.`);
|
|
4043
|
+
removeSpecifier(i);
|
|
4044
|
+
}
|
|
4045
|
+
else if (existing) {
|
|
4046
|
+
if (existing.source === source && existing.imported === imported) {
|
|
4047
|
+
// already imported in <script setup>, dedupe
|
|
4048
|
+
removeSpecifier(i);
|
|
4049
|
+
}
|
|
4050
|
+
else {
|
|
4051
|
+
error(`different imports aliased to same local name.`, specifier);
|
|
4052
|
+
}
|
|
4053
|
+
}
|
|
4054
|
+
else {
|
|
4055
|
+
registerUserImport(source, local, imported, node.importKind === 'type' ||
|
|
4056
|
+
(specifier.type === 'ImportSpecifier' &&
|
|
4057
|
+
specifier.importKind === 'type'), true, !options.inlineTemplate);
|
|
4058
|
+
}
|
|
4059
|
+
}
|
|
4060
|
+
if (node.specifiers.length && removed === node.specifiers.length) {
|
|
4061
|
+
s.remove(node.start + startOffset, node.end + startOffset);
|
|
4062
|
+
}
|
|
4063
|
+
}
|
|
4064
|
+
}
|
|
4065
|
+
// 1.3 resolve possible user import alias of `ref` and `reactive`
|
|
4066
|
+
const vueImportAliases = {};
|
|
4067
|
+
for (const key in userImports) {
|
|
4068
|
+
const { source, imported, local } = userImports[key];
|
|
4069
|
+
if (source === 'vue')
|
|
4070
|
+
vueImportAliases[imported] = local;
|
|
4071
|
+
}
|
|
4072
|
+
// 2.1 process normal <script> body
|
|
4073
|
+
if (script && scriptAst) {
|
|
4074
|
+
for (const node of scriptAst.body) {
|
|
4075
|
+
if (node.type === 'ExportDefaultDeclaration') {
|
|
3929
4076
|
// export default
|
|
3930
4077
|
defaultExport = node;
|
|
3931
4078
|
// check if user has manually specified `name` or 'render` option in
|
|
@@ -3985,7 +4132,7 @@ function compileScript(sfc, options) {
|
|
|
3985
4132
|
}
|
|
3986
4133
|
}
|
|
3987
4134
|
if (node.declaration) {
|
|
3988
|
-
walkDeclaration(node.declaration, scriptBindings,
|
|
4135
|
+
walkDeclaration(node.declaration, scriptBindings, vueImportAliases);
|
|
3989
4136
|
}
|
|
3990
4137
|
}
|
|
3991
4138
|
else if ((node.type === 'VariableDeclaration' ||
|
|
@@ -3993,7 +4140,7 @@ function compileScript(sfc, options) {
|
|
|
3993
4140
|
node.type === 'ClassDeclaration' ||
|
|
3994
4141
|
node.type === 'TSEnumDeclaration') &&
|
|
3995
4142
|
!node.declare) {
|
|
3996
|
-
walkDeclaration(node, scriptBindings,
|
|
4143
|
+
walkDeclaration(node, scriptBindings, vueImportAliases);
|
|
3997
4144
|
}
|
|
3998
4145
|
}
|
|
3999
4146
|
// apply reactivity transform
|
|
@@ -4015,31 +4162,10 @@ function compileScript(sfc, options) {
|
|
|
4015
4162
|
s.move(scriptStartOffset, scriptEndOffset, 0);
|
|
4016
4163
|
}
|
|
4017
4164
|
}
|
|
4018
|
-
// 2.
|
|
4019
|
-
const scriptSetupAst = parse(scriptSetup.content, {
|
|
4020
|
-
plugins: [
|
|
4021
|
-
...plugins,
|
|
4022
|
-
// allow top level await but only inside <script setup>
|
|
4023
|
-
'topLevelAwait'
|
|
4024
|
-
],
|
|
4025
|
-
sourceType: 'module'
|
|
4026
|
-
}, startOffset);
|
|
4165
|
+
// 2.2 process <script setup> body
|
|
4027
4166
|
for (const node of scriptSetupAst.body) {
|
|
4028
|
-
const start = node.start + startOffset;
|
|
4029
|
-
let end = node.end + startOffset;
|
|
4030
|
-
// locate comment
|
|
4031
|
-
if (node.trailingComments && node.trailingComments.length > 0) {
|
|
4032
|
-
const lastCommentNode = node.trailingComments[node.trailingComments.length - 1];
|
|
4033
|
-
end = lastCommentNode.end + startOffset;
|
|
4034
|
-
}
|
|
4035
|
-
// locate the end of whitespace between this statement and the next
|
|
4036
|
-
while (end <= source.length) {
|
|
4037
|
-
if (!/\s/.test(source.charAt(end))) {
|
|
4038
|
-
break;
|
|
4039
|
-
}
|
|
4040
|
-
end++;
|
|
4041
|
-
}
|
|
4042
4167
|
// (Dropped) `ref: x` bindings
|
|
4168
|
+
// TODO remove when out of experimental
|
|
4043
4169
|
if (node.type === 'LabeledStatement' &&
|
|
4044
4170
|
node.label.name === 'ref' &&
|
|
4045
4171
|
node.body.type === 'ExpressionStatement') {
|
|
@@ -4047,59 +4173,6 @@ function compileScript(sfc, options) {
|
|
|
4047
4173
|
`has been dropped based on community feedback. Please check out ` +
|
|
4048
4174
|
`the new proposal at https://github.com/vuejs/rfcs/discussions/369`, node);
|
|
4049
4175
|
}
|
|
4050
|
-
if (node.type === 'ImportDeclaration') {
|
|
4051
|
-
// import declarations are moved to top
|
|
4052
|
-
s.move(start, end, 0);
|
|
4053
|
-
// dedupe imports
|
|
4054
|
-
let removed = 0;
|
|
4055
|
-
const removeSpecifier = (i) => {
|
|
4056
|
-
const removeLeft = i > removed;
|
|
4057
|
-
removed++;
|
|
4058
|
-
const current = node.specifiers[i];
|
|
4059
|
-
const next = node.specifiers[i + 1];
|
|
4060
|
-
s.remove(removeLeft
|
|
4061
|
-
? node.specifiers[i - 1].end + startOffset
|
|
4062
|
-
: current.start + startOffset, next && !removeLeft
|
|
4063
|
-
? next.start + startOffset
|
|
4064
|
-
: current.end + startOffset);
|
|
4065
|
-
};
|
|
4066
|
-
for (let i = 0; i < node.specifiers.length; i++) {
|
|
4067
|
-
const specifier = node.specifiers[i];
|
|
4068
|
-
const local = specifier.local.name;
|
|
4069
|
-
let imported = specifier.type === 'ImportSpecifier' &&
|
|
4070
|
-
specifier.imported.type === 'Identifier' &&
|
|
4071
|
-
specifier.imported.name;
|
|
4072
|
-
if (specifier.type === 'ImportNamespaceSpecifier') {
|
|
4073
|
-
imported = '*';
|
|
4074
|
-
}
|
|
4075
|
-
const source = node.source.value;
|
|
4076
|
-
const existing = userImports[local];
|
|
4077
|
-
if (source === 'vue' &&
|
|
4078
|
-
(imported === DEFINE_PROPS ||
|
|
4079
|
-
imported === DEFINE_EMITS ||
|
|
4080
|
-
imported === DEFINE_EXPOSE)) {
|
|
4081
|
-
warnOnce(`\`${imported}\` is a compiler macro and no longer needs to be imported.`);
|
|
4082
|
-
removeSpecifier(i);
|
|
4083
|
-
}
|
|
4084
|
-
else if (existing) {
|
|
4085
|
-
if (existing.source === source && existing.imported === imported) {
|
|
4086
|
-
// already imported in <script setup>, dedupe
|
|
4087
|
-
removeSpecifier(i);
|
|
4088
|
-
}
|
|
4089
|
-
else {
|
|
4090
|
-
error(`different imports aliased to same local name.`, specifier);
|
|
4091
|
-
}
|
|
4092
|
-
}
|
|
4093
|
-
else {
|
|
4094
|
-
registerUserImport(source, local, imported, node.importKind === 'type' ||
|
|
4095
|
-
(specifier.type === 'ImportSpecifier' &&
|
|
4096
|
-
specifier.importKind === 'type'), true, !options.inlineTemplate);
|
|
4097
|
-
}
|
|
4098
|
-
}
|
|
4099
|
-
if (node.specifiers.length && removed === node.specifiers.length) {
|
|
4100
|
-
s.remove(node.start + startOffset, node.end + startOffset);
|
|
4101
|
-
}
|
|
4102
|
-
}
|
|
4103
4176
|
if (node.type === 'ExpressionStatement') {
|
|
4104
4177
|
// process `defineProps` and `defineEmit(s)` calls
|
|
4105
4178
|
if (processDefineProps(node.expression) ||
|
|
@@ -4130,12 +4203,12 @@ function compileScript(sfc, options) {
|
|
|
4130
4203
|
else {
|
|
4131
4204
|
let start = decl.start + startOffset;
|
|
4132
4205
|
let end = decl.end + startOffset;
|
|
4133
|
-
if (i
|
|
4134
|
-
//
|
|
4206
|
+
if (i === 0) {
|
|
4207
|
+
// first one, locate the start of the next
|
|
4135
4208
|
end = node.declarations[i + 1].start + startOffset;
|
|
4136
4209
|
}
|
|
4137
4210
|
else {
|
|
4138
|
-
//
|
|
4211
|
+
// not first one, locate the end of the prev
|
|
4139
4212
|
start = node.declarations[i - 1].end + startOffset;
|
|
4140
4213
|
}
|
|
4141
4214
|
s.remove(start, end);
|
|
@@ -4150,7 +4223,7 @@ function compileScript(sfc, options) {
|
|
|
4150
4223
|
node.type === 'FunctionDeclaration' ||
|
|
4151
4224
|
node.type === 'ClassDeclaration') &&
|
|
4152
4225
|
!node.declare) {
|
|
4153
|
-
walkDeclaration(node, setupBindings,
|
|
4226
|
+
walkDeclaration(node, setupBindings, vueImportAliases);
|
|
4154
4227
|
}
|
|
4155
4228
|
// walk statements & named exports / variable declarations for top level
|
|
4156
4229
|
// await
|
|
@@ -4204,7 +4277,7 @@ function compileScript(sfc, options) {
|
|
|
4204
4277
|
node.exportKind === 'type') ||
|
|
4205
4278
|
(node.type === 'VariableDeclaration' && node.declare)) {
|
|
4206
4279
|
recordType(node, declaredTypes);
|
|
4207
|
-
|
|
4280
|
+
hoistNode(node);
|
|
4208
4281
|
}
|
|
4209
4282
|
}
|
|
4210
4283
|
}
|
|
@@ -4321,10 +4394,10 @@ function compileScript(sfc, options) {
|
|
|
4321
4394
|
// we use a default __props so that template expressions referencing props
|
|
4322
4395
|
// can use it directly
|
|
4323
4396
|
if (propsIdentifier) {
|
|
4324
|
-
s.prependLeft(startOffset, `\nconst ${propsIdentifier} = __props${propsTypeDecl ? ` as ${genSetupPropsType(propsTypeDecl)}` : ``}
|
|
4397
|
+
s.prependLeft(startOffset, `\nconst ${propsIdentifier} = __props${propsTypeDecl ? ` as ${genSetupPropsType(propsTypeDecl)}` : ``};\n`);
|
|
4325
4398
|
}
|
|
4326
4399
|
if (propsDestructureRestId) {
|
|
4327
|
-
s.prependLeft(startOffset, `\nconst ${propsDestructureRestId} = ${helper(`createPropsRestProxy`)}(__props, ${JSON.stringify(Object.keys(propsDestructuredBindings))})
|
|
4400
|
+
s.prependLeft(startOffset, `\nconst ${propsDestructureRestId} = ${helper(`createPropsRestProxy`)}(__props, ${JSON.stringify(Object.keys(propsDestructuredBindings))});\n`);
|
|
4328
4401
|
}
|
|
4329
4402
|
// inject temp variables for async context preservation
|
|
4330
4403
|
if (hasAwait) {
|
|
@@ -4519,7 +4592,7 @@ function compileScript(sfc, options) {
|
|
|
4519
4592
|
function registerBinding(bindings, node, type) {
|
|
4520
4593
|
bindings[node.name] = type;
|
|
4521
4594
|
}
|
|
4522
|
-
function walkDeclaration(node, bindings,
|
|
4595
|
+
function walkDeclaration(node, bindings, userImportAliases) {
|
|
4523
4596
|
if (node.type === 'VariableDeclaration') {
|
|
4524
4597
|
const isConst = node.kind === 'const';
|
|
4525
4598
|
// export const foo = ...
|
|
@@ -4528,7 +4601,7 @@ function walkDeclaration(node, bindings, userImportAlias) {
|
|
|
4528
4601
|
isCallOf(init, c => c === DEFINE_PROPS || c === DEFINE_EMITS || c === WITH_DEFAULTS));
|
|
4529
4602
|
if (id.type === 'Identifier') {
|
|
4530
4603
|
let bindingType;
|
|
4531
|
-
const userReactiveBinding =
|
|
4604
|
+
const userReactiveBinding = userImportAliases['reactive'];
|
|
4532
4605
|
if (isCallOf(init, userReactiveBinding)) {
|
|
4533
4606
|
// treat reactive() calls as let since it's meant to be mutable
|
|
4534
4607
|
bindingType = isConst
|
|
@@ -4545,7 +4618,7 @@ function walkDeclaration(node, bindings, userImportAlias) {
|
|
|
4545
4618
|
: "setup-const" /* BindingTypes.SETUP_CONST */;
|
|
4546
4619
|
}
|
|
4547
4620
|
else if (isConst) {
|
|
4548
|
-
if (isCallOf(init,
|
|
4621
|
+
if (isCallOf(init, userImportAliases['ref'])) {
|
|
4549
4622
|
bindingType = "setup-ref" /* BindingTypes.SETUP_REF */;
|
|
4550
4623
|
}
|
|
4551
4624
|
else {
|
|
@@ -4793,6 +4866,7 @@ function genRuntimeEmits(emits) {
|
|
|
4793
4866
|
}
|
|
4794
4867
|
function isCallOf(node, test) {
|
|
4795
4868
|
return !!(node &&
|
|
4869
|
+
test &&
|
|
4796
4870
|
node.type === 'CallExpression' &&
|
|
4797
4871
|
node.callee.type === 'Identifier' &&
|
|
4798
4872
|
(typeof test === 'string'
|
|
@@ -4903,15 +4977,11 @@ function analyzeBindingsFromOptions(node) {
|
|
|
4903
4977
|
function getObjectExpressionKeys(node) {
|
|
4904
4978
|
const keys = [];
|
|
4905
4979
|
for (const prop of node.properties) {
|
|
4906
|
-
if (
|
|
4907
|
-
|
|
4908
|
-
|
|
4909
|
-
|
|
4910
|
-
|
|
4911
|
-
else if (prop.key.type === 'StringLiteral') {
|
|
4912
|
-
keys.push(prop.key.value);
|
|
4913
|
-
}
|
|
4914
|
-
}
|
|
4980
|
+
if (prop.type === 'SpreadElement')
|
|
4981
|
+
continue;
|
|
4982
|
+
const key = resolveObjectKey(prop.key, prop.computed);
|
|
4983
|
+
if (key)
|
|
4984
|
+
keys.push(String(key));
|
|
4915
4985
|
}
|
|
4916
4986
|
return keys;
|
|
4917
4987
|
}
|
|
@@ -5036,6 +5106,17 @@ function hmrShouldReload(prevImports, next) {
|
|
|
5036
5106
|
}
|
|
5037
5107
|
return false;
|
|
5038
5108
|
}
|
|
5109
|
+
function resolveObjectKey(node, computed) {
|
|
5110
|
+
switch (node.type) {
|
|
5111
|
+
case 'StringLiteral':
|
|
5112
|
+
case 'NumericLiteral':
|
|
5113
|
+
return node.value;
|
|
5114
|
+
case 'Identifier':
|
|
5115
|
+
if (!computed)
|
|
5116
|
+
return node.name;
|
|
5117
|
+
}
|
|
5118
|
+
return undefined;
|
|
5119
|
+
}
|
|
5039
5120
|
|
|
5040
5121
|
const DEFAULT_FILENAME = 'anonymous.vue';
|
|
5041
5122
|
const sourceToSFC = createCache();
|
|
@@ -5140,6 +5221,9 @@ function parse(source, { sourceMap = true, filename = DEFAULT_FILENAME, sourceRo
|
|
|
5140
5221
|
break;
|
|
5141
5222
|
}
|
|
5142
5223
|
});
|
|
5224
|
+
if (!descriptor.template && !descriptor.script && !descriptor.scriptSetup) {
|
|
5225
|
+
errors.push(new SyntaxError(`At least one <template> or <script> is required in a single file component.`));
|
|
5226
|
+
}
|
|
5143
5227
|
if (descriptor.scriptSetup) {
|
|
5144
5228
|
if (descriptor.scriptSetup.src) {
|
|
5145
5229
|
errors.push(new SyntaxError(`<script setup> cannot use the "src" attribute because ` +
|
package/dist/compiler-sfc.d.ts
CHANGED
|
@@ -17,6 +17,7 @@ import { Result } from 'postcss';
|
|
|
17
17
|
import { RootNode } from '@vue/compiler-core';
|
|
18
18
|
import { shouldTransform as shouldTransformRef } from '@vue/reactivity-transform';
|
|
19
19
|
import { SourceLocation } from '@vue/compiler-core';
|
|
20
|
+
import { Statement } from '@babel/types';
|
|
20
21
|
import { transform as transformRef } from '@vue/reactivity-transform';
|
|
21
22
|
import { transformAST as transformRefAST } from '@vue/reactivity-transform';
|
|
22
23
|
import { walkIdentifiers } from '@vue/compiler-core';
|
|
@@ -79,6 +80,7 @@ export { generateCodeFrame }
|
|
|
79
80
|
declare interface ImportBinding {
|
|
80
81
|
isType: boolean;
|
|
81
82
|
imported: string;
|
|
83
|
+
local: string;
|
|
82
84
|
source: string;
|
|
83
85
|
isFromSetup: boolean;
|
|
84
86
|
isUsedInTemplate: boolean;
|
|
@@ -160,14 +162,8 @@ export declare interface SFCScriptBlock extends SFCBlock {
|
|
|
160
162
|
setup?: string | boolean;
|
|
161
163
|
bindings?: BindingMetadata;
|
|
162
164
|
imports?: Record<string, ImportBinding>;
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
*/
|
|
166
|
-
scriptAst?: any[];
|
|
167
|
-
/**
|
|
168
|
-
* import('\@babel/types').Statement
|
|
169
|
-
*/
|
|
170
|
-
scriptSetupAst?: any[];
|
|
165
|
+
scriptAst?: Statement[];
|
|
166
|
+
scriptSetupAst?: Statement[];
|
|
171
167
|
}
|
|
172
168
|
|
|
173
169
|
export declare interface SFCScriptCompileOptions {
|