@vue/compiler-sfc 3.1.0 → 3.1.4
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 +380 -234
- package/dist/compiler-sfc.d.ts +30 -0
- package/dist/compiler-sfc.esm-browser.js +8820 -4777
- package/package.json +7 -6
package/dist/compiler-sfc.cjs.js
CHANGED
|
@@ -421,15 +421,9 @@ const defaultAssetUrlOptions = {
|
|
|
421
421
|
const normalizeOptions = (options) => {
|
|
422
422
|
if (Object.keys(options).some(key => shared.isArray(options[key]))) {
|
|
423
423
|
// legacy option format which directly passes in tags config
|
|
424
|
-
return {
|
|
425
|
-
...defaultAssetUrlOptions,
|
|
426
|
-
tags: options
|
|
427
|
-
};
|
|
424
|
+
return Object.assign(Object.assign({}, defaultAssetUrlOptions), { tags: options });
|
|
428
425
|
}
|
|
429
|
-
return {
|
|
430
|
-
...defaultAssetUrlOptions,
|
|
431
|
-
...options
|
|
432
|
-
};
|
|
426
|
+
return Object.assign(Object.assign({}, defaultAssetUrlOptions), options);
|
|
433
427
|
};
|
|
434
428
|
const createAssetUrlTransformWithOptions = (options) => {
|
|
435
429
|
return (node, context) => transformAssetUrl(node, context, options);
|
|
@@ -637,7 +631,7 @@ function preprocess({ source, filename, preprocessOptions }, preprocessor) {
|
|
|
637
631
|
// have to be sync because they are applied via Node.js require hooks)
|
|
638
632
|
let res = '';
|
|
639
633
|
let err = null;
|
|
640
|
-
preprocessor.render(source, { filename,
|
|
634
|
+
preprocessor.render(source, Object.assign({ filename }, preprocessOptions), (_err, _res) => {
|
|
641
635
|
if (_err)
|
|
642
636
|
err = _err;
|
|
643
637
|
res = _res;
|
|
@@ -655,10 +649,7 @@ function compileTemplate(options) {
|
|
|
655
649
|
: false;
|
|
656
650
|
if (preprocessor) {
|
|
657
651
|
try {
|
|
658
|
-
return doCompileTemplate({
|
|
659
|
-
...options,
|
|
660
|
-
source: preprocess(options, preprocessor)
|
|
661
|
-
});
|
|
652
|
+
return doCompileTemplate(Object.assign(Object.assign({}, options), { source: preprocess(options, preprocessor) }));
|
|
662
653
|
}
|
|
663
654
|
catch (e) {
|
|
664
655
|
return {
|
|
@@ -709,23 +700,9 @@ function doCompileTemplate({ filename, id, scoped, slotted, inMap, source, ssr =
|
|
|
709
700
|
}
|
|
710
701
|
const shortId = id.replace(/^data-v-/, '');
|
|
711
702
|
const longId = `data-v-${shortId}`;
|
|
712
|
-
let { code, ast, preamble, map } = compiler.compile(source, {
|
|
713
|
-
mode: 'module',
|
|
714
|
-
prefixIdentifiers: true,
|
|
715
|
-
hoistStatic: true,
|
|
716
|
-
cacheHandlers: true,
|
|
717
|
-
ssrCssVars: ssr && ssrCssVars && ssrCssVars.length
|
|
703
|
+
let { code, ast, preamble, map } = compiler.compile(source, Object.assign(Object.assign({ mode: 'module', prefixIdentifiers: true, hoistStatic: true, cacheHandlers: true, ssrCssVars: ssr && ssrCssVars && ssrCssVars.length
|
|
718
704
|
? genCssVarsFromList(ssrCssVars, shortId, isProd)
|
|
719
|
-
: '',
|
|
720
|
-
scopeId: scoped ? longId : undefined,
|
|
721
|
-
slotted,
|
|
722
|
-
...compilerOptions,
|
|
723
|
-
nodeTransforms: nodeTransforms.concat(compilerOptions.nodeTransforms || []),
|
|
724
|
-
filename,
|
|
725
|
-
sourceMap: true,
|
|
726
|
-
onError: e => errors.push(e),
|
|
727
|
-
onWarn: w => warnings.push(w)
|
|
728
|
-
});
|
|
705
|
+
: '', scopeId: scoped ? longId : undefined, slotted }, compilerOptions), { nodeTransforms: nodeTransforms.concat(compilerOptions.nodeTransforms || []), filename, sourceMap: true, onError: e => errors.push(e), onWarn: w => warnings.push(w) }));
|
|
729
706
|
// inMap should be the map produced by ./parse.ts which is a simple line-only
|
|
730
707
|
// mapping. If it is present, we need to adjust the final map and errors to
|
|
731
708
|
// reflect the original line numbers.
|
|
@@ -1002,13 +979,7 @@ scopedPlugin.postcss = true;
|
|
|
1002
979
|
// .scss/.sass processor
|
|
1003
980
|
const scss = (source, map, options, load = require) => {
|
|
1004
981
|
const nodeSass = load('sass');
|
|
1005
|
-
const finalOptions = {
|
|
1006
|
-
...options,
|
|
1007
|
-
data: getSource(source, options.filename, options.additionalData),
|
|
1008
|
-
file: options.filename,
|
|
1009
|
-
outFile: options.filename,
|
|
1010
|
-
sourceMap: !!map
|
|
1011
|
-
};
|
|
982
|
+
const finalOptions = Object.assign(Object.assign({}, options), { data: getSource(source, options.filename, options.additionalData), file: options.filename, outFile: options.filename, sourceMap: !!map });
|
|
1012
983
|
try {
|
|
1013
984
|
const result = nodeSass.renderSync(finalOptions);
|
|
1014
985
|
const dependencies = result.stats.includedFiles;
|
|
@@ -1026,16 +997,13 @@ const scss = (source, map, options, load = require) => {
|
|
|
1026
997
|
return { code: '', errors: [e], dependencies: [] };
|
|
1027
998
|
}
|
|
1028
999
|
};
|
|
1029
|
-
const sass = (source, map, options, load) => scss(source, map, {
|
|
1030
|
-
...options,
|
|
1031
|
-
indentedSyntax: true
|
|
1032
|
-
}, load);
|
|
1000
|
+
const sass = (source, map, options, load) => scss(source, map, Object.assign(Object.assign({}, options), { indentedSyntax: true }), load);
|
|
1033
1001
|
// .less
|
|
1034
1002
|
const less = (source, map, options, load = require) => {
|
|
1035
1003
|
const nodeLess = load('less');
|
|
1036
1004
|
let result;
|
|
1037
1005
|
let error = null;
|
|
1038
|
-
nodeLess.render(getSource(source, options.filename, options.additionalData), {
|
|
1006
|
+
nodeLess.render(getSource(source, options.filename, options.additionalData), Object.assign(Object.assign({}, options), { syncImport: true }), (err, output) => {
|
|
1039
1007
|
error = err;
|
|
1040
1008
|
result = output;
|
|
1041
1009
|
});
|
|
@@ -1097,13 +1065,10 @@ const processors = {
|
|
|
1097
1065
|
};
|
|
1098
1066
|
|
|
1099
1067
|
function compileStyle(options) {
|
|
1100
|
-
return doCompileStyle({
|
|
1101
|
-
...options,
|
|
1102
|
-
isAsync: false
|
|
1103
|
-
});
|
|
1068
|
+
return doCompileStyle(Object.assign(Object.assign({}, options), { isAsync: false }));
|
|
1104
1069
|
}
|
|
1105
1070
|
function compileStyleAsync(options) {
|
|
1106
|
-
return doCompileStyle({
|
|
1071
|
+
return doCompileStyle(Object.assign(Object.assign({}, options), { isAsync: true }));
|
|
1107
1072
|
}
|
|
1108
1073
|
function doCompileStyle(options) {
|
|
1109
1074
|
const { filename, id, scoped = false, trim = true, isProd = false, modules = false, modulesOptions = {}, preprocessLang, postcssOptions, postcssPlugins } = options;
|
|
@@ -1128,18 +1093,11 @@ function doCompileStyle(options) {
|
|
|
1128
1093
|
if (!options.isAsync) {
|
|
1129
1094
|
throw new Error('[@vue/compiler-sfc] `modules` option can only be used with compileStyleAsync().');
|
|
1130
1095
|
}
|
|
1131
|
-
plugins.push(require('postcss-modules')({
|
|
1132
|
-
...modulesOptions,
|
|
1133
|
-
getJSON: (_cssFileName, json) => {
|
|
1096
|
+
plugins.push(require('postcss-modules')(Object.assign(Object.assign({}, modulesOptions), { getJSON: (_cssFileName, json) => {
|
|
1134
1097
|
cssModules = json;
|
|
1135
|
-
}
|
|
1136
|
-
}));
|
|
1098
|
+
} })));
|
|
1137
1099
|
}
|
|
1138
|
-
const postCSSOptions = {
|
|
1139
|
-
...postcssOptions,
|
|
1140
|
-
to: filename,
|
|
1141
|
-
from: filename
|
|
1142
|
-
};
|
|
1100
|
+
const postCSSOptions = Object.assign(Object.assign({}, postcssOptions), { to: filename, from: filename });
|
|
1143
1101
|
if (map) {
|
|
1144
1102
|
postCSSOptions.map = {
|
|
1145
1103
|
inline: false,
|
|
@@ -1205,14 +1163,11 @@ function doCompileStyle(options) {
|
|
|
1205
1163
|
};
|
|
1206
1164
|
}
|
|
1207
1165
|
function preprocess$1(options, preprocessor) {
|
|
1208
|
-
return preprocessor(options.source, options.inMap || options.map, {
|
|
1209
|
-
filename: options.filename,
|
|
1210
|
-
...options.preprocessOptions
|
|
1211
|
-
}, options.preprocessCustomRequire);
|
|
1166
|
+
return preprocessor(options.source, options.inMap || options.map, Object.assign({ filename: options.filename }, options.preprocessOptions), options.preprocessCustomRequire);
|
|
1212
1167
|
}
|
|
1213
1168
|
|
|
1214
1169
|
const defaultExportRE = /((?:^|\n|;)\s*)export(\s*)default/;
|
|
1215
|
-
const namedDefaultExportRE = /((?:^|\n|;)\s*)export(.+)as(\s*)default
|
|
1170
|
+
const namedDefaultExportRE = /((?:^|\n|;)\s*)export(.+)as(\s*)default/s;
|
|
1216
1171
|
const exportDefaultClassRE = /((?:^|\n|;)\s*)export\s+default\s+class\s+([\w$]+)/;
|
|
1217
1172
|
/**
|
|
1218
1173
|
* Utility for rewriting `export default` in a script block into a variable
|
|
@@ -1266,15 +1221,32 @@ function hasDefaultExport(input) {
|
|
|
1266
1221
|
|
|
1267
1222
|
const DEFINE_PROPS = 'defineProps';
|
|
1268
1223
|
const DEFINE_EMIT = 'defineEmit';
|
|
1224
|
+
const DEFINE_EXPOSE = 'defineExpose';
|
|
1225
|
+
const WITH_DEFAULTS = 'withDefaults';
|
|
1226
|
+
// deprecated
|
|
1227
|
+
const DEFINE_EMITS = 'defineEmits';
|
|
1269
1228
|
/**
|
|
1270
1229
|
* Compile `<script setup>`
|
|
1271
1230
|
* It requires the whole SFC descriptor because we need to handle and merge
|
|
1272
1231
|
* normal `<script>` + `<script setup>` if both are present.
|
|
1273
1232
|
*/
|
|
1274
1233
|
function compileScript(sfc, options) {
|
|
1275
|
-
|
|
1234
|
+
let { script, scriptSetup, source, filename } = sfc;
|
|
1235
|
+
// feature flags
|
|
1236
|
+
const enableRefSugar = !!options.refSugar;
|
|
1237
|
+
const parseOnly = !!options.parseOnly;
|
|
1276
1238
|
if (scriptSetup) {
|
|
1277
|
-
warnExperimental(`<script setup>`, 227);
|
|
1239
|
+
!parseOnly && warnExperimental(`<script setup>`, 227);
|
|
1240
|
+
}
|
|
1241
|
+
else if (parseOnly) {
|
|
1242
|
+
// in parse-only mode, construct a fake script setup so we still perform
|
|
1243
|
+
// the full parse logic.
|
|
1244
|
+
scriptSetup = {
|
|
1245
|
+
type: 'script',
|
|
1246
|
+
content: '',
|
|
1247
|
+
attrs: {},
|
|
1248
|
+
loc: compilerCore.locStub
|
|
1249
|
+
};
|
|
1278
1250
|
}
|
|
1279
1251
|
// for backwards compat
|
|
1280
1252
|
if (!options) {
|
|
@@ -1285,9 +1257,14 @@ function compileScript(sfc, options) {
|
|
|
1285
1257
|
`Upgrade your vite or vue-loader version for compatibility with ` +
|
|
1286
1258
|
`the latest experimental proposals.`);
|
|
1287
1259
|
}
|
|
1260
|
+
// TODO remove on 3.2
|
|
1261
|
+
if (sfc.template && sfc.template.attrs['inherit-attrs'] === 'false') {
|
|
1262
|
+
warnOnce(`experimetnal support for <template inherit-attrs="false"> support has ` +
|
|
1263
|
+
`been removed. Use a <script> block with \`export default\` to ` +
|
|
1264
|
+
`declare options.`);
|
|
1265
|
+
}
|
|
1288
1266
|
const scopeId = options.id ? options.id.replace(/^data-v-/, '') : '';
|
|
1289
1267
|
const cssVars = sfc.cssVars;
|
|
1290
|
-
const hasInheritAttrsFlag = sfc.template && sfc.template.attrs['inherit-attrs'] === 'false';
|
|
1291
1268
|
const scriptLang = script && script.lang;
|
|
1292
1269
|
const scriptSetupLang = scriptSetup && scriptSetup.lang;
|
|
1293
1270
|
const isTS = scriptLang === 'ts' ||
|
|
@@ -1310,27 +1287,21 @@ function compileScript(sfc, options) {
|
|
|
1310
1287
|
try {
|
|
1311
1288
|
const scriptAst = parser.parse(script.content, {
|
|
1312
1289
|
plugins,
|
|
1313
|
-
sourceType: 'module'
|
|
1290
|
+
sourceType: 'module',
|
|
1291
|
+
errorRecovery: parseOnly
|
|
1314
1292
|
}).program.body;
|
|
1315
1293
|
const bindings = analyzeScriptBindings(scriptAst);
|
|
1316
|
-
const needRewrite = cssVars.length || hasInheritAttrsFlag;
|
|
1317
1294
|
let content = script.content;
|
|
1318
|
-
if (
|
|
1295
|
+
if (cssVars.length) {
|
|
1319
1296
|
content = rewriteDefault(content, `__default__`, plugins);
|
|
1320
1297
|
if (cssVars.length) {
|
|
1321
1298
|
content += genNormalScriptCssVarsCode(cssVars, bindings, scopeId, !!options.isProd);
|
|
1322
1299
|
}
|
|
1323
|
-
if (hasInheritAttrsFlag) {
|
|
1324
|
-
content += `__default__.inheritAttrs = false`;
|
|
1325
|
-
}
|
|
1326
1300
|
content += `\nexport default __default__`;
|
|
1327
1301
|
}
|
|
1328
|
-
return {
|
|
1329
|
-
...script,
|
|
1330
|
-
content,
|
|
1302
|
+
return Object.assign(Object.assign({}, script), { content,
|
|
1331
1303
|
bindings,
|
|
1332
|
-
scriptAst
|
|
1333
|
-
};
|
|
1304
|
+
scriptAst });
|
|
1334
1305
|
}
|
|
1335
1306
|
catch (e) {
|
|
1336
1307
|
// silently fallback if parse fails since user may be using custom
|
|
@@ -1339,29 +1310,40 @@ function compileScript(sfc, options) {
|
|
|
1339
1310
|
}
|
|
1340
1311
|
}
|
|
1341
1312
|
if (script && scriptLang !== scriptSetupLang) {
|
|
1342
|
-
throw new Error(`[@vue/compiler-sfc] <script> and <script setup> must have the same
|
|
1313
|
+
throw new Error(`[@vue/compiler-sfc] <script> and <script setup> must have the same ` +
|
|
1314
|
+
`language type.`);
|
|
1343
1315
|
}
|
|
1344
1316
|
if (scriptSetupLang && !isTS && scriptSetupLang !== 'jsx') {
|
|
1345
1317
|
// do not process non js/ts script blocks
|
|
1346
1318
|
return scriptSetup;
|
|
1347
1319
|
}
|
|
1348
|
-
|
|
1320
|
+
// metadata that needs to be returned
|
|
1349
1321
|
const bindingMetadata = {};
|
|
1322
|
+
const ranges = parseOnly
|
|
1323
|
+
? {
|
|
1324
|
+
scriptBindings: [],
|
|
1325
|
+
scriptSetupBindings: []
|
|
1326
|
+
}
|
|
1327
|
+
: undefined;
|
|
1328
|
+
const defaultTempVar = `__default__`;
|
|
1350
1329
|
const helperImports = new Set();
|
|
1351
1330
|
const userImports = Object.create(null);
|
|
1352
1331
|
const userImportAlias = Object.create(null);
|
|
1353
1332
|
const setupBindings = Object.create(null);
|
|
1354
1333
|
const refBindings = Object.create(null);
|
|
1355
1334
|
const refIdentifiers = new Set();
|
|
1356
|
-
const enableRefSugar = options.refSugar !== false;
|
|
1357
1335
|
let defaultExport;
|
|
1358
1336
|
let hasDefinePropsCall = false;
|
|
1359
1337
|
let hasDefineEmitCall = false;
|
|
1338
|
+
let hasDefineExposeCall = false;
|
|
1360
1339
|
let propsRuntimeDecl;
|
|
1340
|
+
let propsRuntimeDefaults;
|
|
1361
1341
|
let propsTypeDecl;
|
|
1342
|
+
let propsTypeDeclRaw;
|
|
1362
1343
|
let propsIdentifier;
|
|
1363
|
-
let
|
|
1364
|
-
let
|
|
1344
|
+
let emitsRuntimeDecl;
|
|
1345
|
+
let emitsTypeDecl;
|
|
1346
|
+
let emitsTypeDeclRaw;
|
|
1365
1347
|
let emitIdentifier;
|
|
1366
1348
|
let hasAwait = false;
|
|
1367
1349
|
let hasInlinedSsrRenderFn = false;
|
|
@@ -1382,6 +1364,7 @@ function compileScript(sfc, options) {
|
|
|
1382
1364
|
}
|
|
1383
1365
|
function parse(input, options, offset) {
|
|
1384
1366
|
try {
|
|
1367
|
+
options.errorRecovery = parseOnly;
|
|
1385
1368
|
return parser.parse(input, options).program.body;
|
|
1386
1369
|
}
|
|
1387
1370
|
catch (e) {
|
|
@@ -1392,63 +1375,116 @@ function compileScript(sfc, options) {
|
|
|
1392
1375
|
function error(msg, node, end = node.end + startOffset) {
|
|
1393
1376
|
throw new Error(`[@vue/compiler-sfc] ${msg}\n\n${sfc.filename}\n${shared.generateCodeFrame(source, node.start + startOffset, end)}`);
|
|
1394
1377
|
}
|
|
1395
|
-
function registerUserImport(source, local, imported, isType) {
|
|
1378
|
+
function registerUserImport(source, local, imported, isType, isFromSetup, rangeNode) {
|
|
1396
1379
|
if (source === 'vue' && imported) {
|
|
1397
1380
|
userImportAlias[imported] = local;
|
|
1398
1381
|
}
|
|
1399
1382
|
userImports[local] = {
|
|
1400
1383
|
isType,
|
|
1401
1384
|
imported: imported || 'default',
|
|
1402
|
-
source
|
|
1385
|
+
source,
|
|
1386
|
+
rangeNode,
|
|
1387
|
+
isFromSetup
|
|
1403
1388
|
};
|
|
1404
1389
|
}
|
|
1405
1390
|
function processDefineProps(node) {
|
|
1406
|
-
if (isCallOf(node, DEFINE_PROPS)) {
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
}
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1391
|
+
if (!isCallOf(node, DEFINE_PROPS)) {
|
|
1392
|
+
return false;
|
|
1393
|
+
}
|
|
1394
|
+
if (hasDefinePropsCall) {
|
|
1395
|
+
error(`duplicate ${DEFINE_PROPS}() call`, node);
|
|
1396
|
+
}
|
|
1397
|
+
hasDefinePropsCall = true;
|
|
1398
|
+
propsRuntimeDecl = node.arguments[0];
|
|
1399
|
+
// call has type parameters - infer runtime types from it
|
|
1400
|
+
if (node.typeParameters) {
|
|
1401
|
+
if (propsRuntimeDecl) {
|
|
1402
|
+
error(`${DEFINE_PROPS}() cannot accept both type and non-type arguments ` +
|
|
1403
|
+
`at the same time. Use one or the other.`, node);
|
|
1404
|
+
}
|
|
1405
|
+
propsTypeDeclRaw = node.typeParameters.params[0];
|
|
1406
|
+
propsTypeDecl = resolveQualifiedType(propsTypeDeclRaw, node => node.type === 'TSTypeLiteral');
|
|
1407
|
+
if (!propsTypeDecl) {
|
|
1408
|
+
error(`type argument passed to ${DEFINE_PROPS}() must be a literal type, ` +
|
|
1409
|
+
`or a reference to an interface or literal type.`, propsTypeDeclRaw);
|
|
1425
1410
|
}
|
|
1426
|
-
return true;
|
|
1427
1411
|
}
|
|
1428
|
-
return
|
|
1412
|
+
return true;
|
|
1413
|
+
}
|
|
1414
|
+
function processWithDefaults(node) {
|
|
1415
|
+
if (!isCallOf(node, WITH_DEFAULTS)) {
|
|
1416
|
+
return false;
|
|
1417
|
+
}
|
|
1418
|
+
if (processDefineProps(node.arguments[0])) {
|
|
1419
|
+
if (propsRuntimeDecl) {
|
|
1420
|
+
error(`${WITH_DEFAULTS} can only be used with type-based ` +
|
|
1421
|
+
`${DEFINE_PROPS} declaration.`, node);
|
|
1422
|
+
}
|
|
1423
|
+
propsRuntimeDefaults = node.arguments[1];
|
|
1424
|
+
}
|
|
1425
|
+
else {
|
|
1426
|
+
error(`${WITH_DEFAULTS}' first argument must be a ${DEFINE_PROPS} call.`, node.arguments[0] || node);
|
|
1427
|
+
}
|
|
1428
|
+
return true;
|
|
1429
1429
|
}
|
|
1430
|
-
function
|
|
1431
|
-
if (isCallOf(node, DEFINE_EMIT)) {
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1430
|
+
function processDefineEmits(node) {
|
|
1431
|
+
if (!isCallOf(node, c => c === DEFINE_EMIT || c === DEFINE_EMITS)) {
|
|
1432
|
+
return false;
|
|
1433
|
+
}
|
|
1434
|
+
if (hasDefineEmitCall) {
|
|
1435
|
+
error(`duplicate ${DEFINE_EMITS}() call`, node);
|
|
1436
|
+
}
|
|
1437
|
+
hasDefineEmitCall = true;
|
|
1438
|
+
emitsRuntimeDecl = node.arguments[0];
|
|
1439
|
+
if (node.typeParameters) {
|
|
1440
|
+
if (emitsRuntimeDecl) {
|
|
1441
|
+
error(`${DEFINE_EMIT}() cannot accept both type and non-type arguments ` +
|
|
1442
|
+
`at the same time. Use one or the other.`, node);
|
|
1443
|
+
}
|
|
1444
|
+
emitsTypeDeclRaw = node.typeParameters.params[0];
|
|
1445
|
+
emitsTypeDecl = resolveQualifiedType(emitsTypeDeclRaw, node => node.type === 'TSFunctionType' || node.type === 'TSTypeLiteral');
|
|
1446
|
+
if (!emitsTypeDecl) {
|
|
1447
|
+
error(`type argument passed to ${DEFINE_EMITS}() must be a function type, ` +
|
|
1448
|
+
`a literal type with call signatures, or a reference to the above types.`, emitsTypeDeclRaw);
|
|
1449
|
+
}
|
|
1450
|
+
}
|
|
1451
|
+
return true;
|
|
1452
|
+
}
|
|
1453
|
+
function resolveQualifiedType(node, qualifier) {
|
|
1454
|
+
if (qualifier(node)) {
|
|
1455
|
+
return node;
|
|
1456
|
+
}
|
|
1457
|
+
if (node.type === 'TSTypeReference' &&
|
|
1458
|
+
node.typeName.type === 'Identifier') {
|
|
1459
|
+
const refName = node.typeName.name;
|
|
1460
|
+
const isQualifiedType = (node) => {
|
|
1461
|
+
if (node.type === 'TSInterfaceDeclaration' &&
|
|
1462
|
+
node.id.name === refName) {
|
|
1463
|
+
return node.body;
|
|
1441
1464
|
}
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1465
|
+
else if (node.type === 'TSTypeAliasDeclaration' &&
|
|
1466
|
+
node.id.name === refName &&
|
|
1467
|
+
qualifier(node.typeAnnotation)) {
|
|
1468
|
+
return node.typeAnnotation;
|
|
1446
1469
|
}
|
|
1447
|
-
else {
|
|
1448
|
-
|
|
1449
|
-
|
|
1470
|
+
else if (node.type === 'ExportNamedDeclaration' && node.declaration) {
|
|
1471
|
+
return isQualifiedType(node.declaration);
|
|
1472
|
+
}
|
|
1473
|
+
};
|
|
1474
|
+
for (const node of scriptSetupAst) {
|
|
1475
|
+
const qualified = isQualifiedType(node);
|
|
1476
|
+
if (qualified) {
|
|
1477
|
+
return qualified;
|
|
1450
1478
|
}
|
|
1451
1479
|
}
|
|
1480
|
+
}
|
|
1481
|
+
}
|
|
1482
|
+
function processDefineExpose(node) {
|
|
1483
|
+
if (isCallOf(node, DEFINE_EXPOSE)) {
|
|
1484
|
+
if (hasDefineExposeCall) {
|
|
1485
|
+
error(`duplicate ${DEFINE_EXPOSE}() call`, node);
|
|
1486
|
+
}
|
|
1487
|
+
hasDefineExposeCall = true;
|
|
1452
1488
|
return true;
|
|
1453
1489
|
}
|
|
1454
1490
|
return false;
|
|
@@ -1513,7 +1549,10 @@ function compileScript(sfc, options) {
|
|
|
1513
1549
|
if (id.name[0] === '$') {
|
|
1514
1550
|
error(`ref variable identifiers cannot start with $.`, id);
|
|
1515
1551
|
}
|
|
1516
|
-
refBindings[id.name] = setupBindings[id.name] =
|
|
1552
|
+
refBindings[id.name] = setupBindings[id.name] = {
|
|
1553
|
+
type: "setup-ref" /* SETUP_REF */,
|
|
1554
|
+
rangeNode: id
|
|
1555
|
+
};
|
|
1517
1556
|
refIdentifiers.add(id);
|
|
1518
1557
|
}
|
|
1519
1558
|
function processRefObjectPattern(pattern, statement) {
|
|
@@ -1592,6 +1631,39 @@ function compileScript(sfc, options) {
|
|
|
1592
1631
|
}
|
|
1593
1632
|
}
|
|
1594
1633
|
}
|
|
1634
|
+
function genRuntimeProps(props) {
|
|
1635
|
+
const keys = Object.keys(props);
|
|
1636
|
+
if (!keys.length) {
|
|
1637
|
+
return ``;
|
|
1638
|
+
}
|
|
1639
|
+
// check defaults. If the default object is an object literal with only
|
|
1640
|
+
// static properties, we can directly generate more optimzied default
|
|
1641
|
+
// decalrations. Otherwise we will have to fallback to runtime merging.
|
|
1642
|
+
const hasStaticDefaults = propsRuntimeDefaults &&
|
|
1643
|
+
propsRuntimeDefaults.type === 'ObjectExpression' &&
|
|
1644
|
+
propsRuntimeDefaults.properties.every(node => node.type === 'ObjectProperty' && !node.computed);
|
|
1645
|
+
let propsDecls = `{
|
|
1646
|
+
${keys
|
|
1647
|
+
.map(key => {
|
|
1648
|
+
let defaultString;
|
|
1649
|
+
if (hasStaticDefaults) {
|
|
1650
|
+
const prop = propsRuntimeDefaults.properties.find((node) => node.key.name === key);
|
|
1651
|
+
if (prop) {
|
|
1652
|
+
// prop has corresponding static default value
|
|
1653
|
+
defaultString = `default: ${source.slice(prop.value.start + startOffset, prop.value.end + startOffset)}`;
|
|
1654
|
+
}
|
|
1655
|
+
}
|
|
1656
|
+
{
|
|
1657
|
+
const { type, required } = props[key];
|
|
1658
|
+
return `${key}: { type: ${toRuntimeTypeString(type)}, required: ${required}${defaultString ? `, ${defaultString}` : ``} }`;
|
|
1659
|
+
}
|
|
1660
|
+
})
|
|
1661
|
+
.join(',\n ')}\n }`;
|
|
1662
|
+
if (propsRuntimeDefaults && !hasStaticDefaults) {
|
|
1663
|
+
propsDecls = `${helper('mergeDefaults')}(${propsDecls}, ${source.slice(propsRuntimeDefaults.start + startOffset, propsRuntimeDefaults.end + startOffset)})`;
|
|
1664
|
+
}
|
|
1665
|
+
return `\n props: ${propsDecls} as unknown as undefined,`;
|
|
1666
|
+
}
|
|
1595
1667
|
// 1. process normal <script> first if it exists
|
|
1596
1668
|
let scriptAst;
|
|
1597
1669
|
if (script) {
|
|
@@ -1607,7 +1679,7 @@ function compileScript(sfc, options) {
|
|
|
1607
1679
|
const imported = specifier.type === 'ImportSpecifier' &&
|
|
1608
1680
|
specifier.imported.type === 'Identifier' &&
|
|
1609
1681
|
specifier.imported.name;
|
|
1610
|
-
registerUserImport(node.source.value, specifier.local.name, imported, node.importKind === 'type');
|
|
1682
|
+
registerUserImport(node.source.value, specifier.local.name, imported, node.importKind === 'type', false, specifier.local);
|
|
1611
1683
|
}
|
|
1612
1684
|
}
|
|
1613
1685
|
else if (node.type === 'ExportDefaultDeclaration') {
|
|
@@ -1654,7 +1726,6 @@ function compileScript(sfc, options) {
|
|
|
1654
1726
|
for (const node of scriptSetupAst) {
|
|
1655
1727
|
const start = node.start + startOffset;
|
|
1656
1728
|
let end = node.end + startOffset;
|
|
1657
|
-
// import or type declarations: move to top
|
|
1658
1729
|
// locate comment
|
|
1659
1730
|
if (node.trailingComments && node.trailingComments.length > 0) {
|
|
1660
1731
|
const lastCommentNode = node.trailingComments[node.trailingComments.length - 1];
|
|
@@ -1672,14 +1743,15 @@ function compileScript(sfc, options) {
|
|
|
1672
1743
|
node.label.name === 'ref' &&
|
|
1673
1744
|
node.body.type === 'ExpressionStatement') {
|
|
1674
1745
|
if (enableRefSugar) {
|
|
1675
|
-
warnExperimental(`ref: sugar`, 228);
|
|
1746
|
+
!parseOnly && warnExperimental(`ref: sugar`, 228);
|
|
1676
1747
|
s.overwrite(node.label.start + startOffset, node.body.start + startOffset, 'const ');
|
|
1677
1748
|
processRefExpression(node.body.expression, node);
|
|
1678
1749
|
}
|
|
1679
1750
|
else {
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1751
|
+
error(`ref: sugar now needs to be explicitly enabled via @vitejs/plugin-vue ` +
|
|
1752
|
+
`or vue-loader options:\n` +
|
|
1753
|
+
`- @vitejs/plugin-vue: via \`script.refSugar\`\n` +
|
|
1754
|
+
`- vue-loader: via \`refSugar\` (requires 16.3.0+)`, node);
|
|
1683
1755
|
}
|
|
1684
1756
|
}
|
|
1685
1757
|
if (node.type === 'ImportDeclaration') {
|
|
@@ -1707,7 +1779,11 @@ function compileScript(sfc, options) {
|
|
|
1707
1779
|
const source = node.source.value;
|
|
1708
1780
|
const existing = userImports[local];
|
|
1709
1781
|
if (source === 'vue' &&
|
|
1710
|
-
(imported === DEFINE_PROPS ||
|
|
1782
|
+
(imported === DEFINE_PROPS ||
|
|
1783
|
+
imported === DEFINE_EMIT ||
|
|
1784
|
+
imported === DEFINE_EMITS ||
|
|
1785
|
+
imported === DEFINE_EXPOSE)) {
|
|
1786
|
+
warnOnce(`\`${imported}\` is a compiler macro and no longer needs to be imported.`);
|
|
1711
1787
|
removeSpecifier(i);
|
|
1712
1788
|
}
|
|
1713
1789
|
else if (existing) {
|
|
@@ -1720,36 +1796,57 @@ function compileScript(sfc, options) {
|
|
|
1720
1796
|
}
|
|
1721
1797
|
}
|
|
1722
1798
|
else {
|
|
1723
|
-
registerUserImport(source, local, imported, node.importKind === 'type');
|
|
1799
|
+
registerUserImport(source, local, imported, node.importKind === 'type', true, specifier.local);
|
|
1724
1800
|
}
|
|
1725
1801
|
}
|
|
1726
1802
|
if (node.specifiers.length && removed === node.specifiers.length) {
|
|
1727
1803
|
s.remove(node.start + startOffset, node.end + startOffset);
|
|
1728
1804
|
}
|
|
1729
1805
|
}
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
(processDefineProps(node.expression) ||
|
|
1733
|
-
|
|
1734
|
-
|
|
1806
|
+
if (node.type === 'ExpressionStatement') {
|
|
1807
|
+
// process `defineProps` and `defineEmit(s)` calls
|
|
1808
|
+
if (processDefineProps(node.expression) ||
|
|
1809
|
+
processDefineEmits(node.expression) ||
|
|
1810
|
+
processWithDefaults(node.expression)) {
|
|
1811
|
+
s.remove(node.start + startOffset, node.end + startOffset);
|
|
1812
|
+
}
|
|
1813
|
+
else if (processDefineExpose(node.expression)) {
|
|
1814
|
+
// defineExpose({}) -> expose({})
|
|
1815
|
+
const callee = node.expression.callee;
|
|
1816
|
+
s.overwrite(callee.start + startOffset, callee.end + startOffset, 'expose');
|
|
1817
|
+
}
|
|
1735
1818
|
}
|
|
1736
1819
|
if (node.type === 'VariableDeclaration' && !node.declare) {
|
|
1737
|
-
|
|
1820
|
+
const total = node.declarations.length;
|
|
1821
|
+
let left = total;
|
|
1822
|
+
for (let i = 0; i < total; i++) {
|
|
1823
|
+
const decl = node.declarations[i];
|
|
1738
1824
|
if (decl.init) {
|
|
1739
|
-
const isDefineProps = processDefineProps(decl.init);
|
|
1825
|
+
const isDefineProps = processDefineProps(decl.init) || processWithDefaults(decl.init);
|
|
1740
1826
|
if (isDefineProps) {
|
|
1741
1827
|
propsIdentifier = scriptSetup.content.slice(decl.id.start, decl.id.end);
|
|
1742
1828
|
}
|
|
1743
|
-
const
|
|
1744
|
-
if (
|
|
1829
|
+
const isDefineEmits = processDefineEmits(decl.init);
|
|
1830
|
+
if (isDefineEmits) {
|
|
1745
1831
|
emitIdentifier = scriptSetup.content.slice(decl.id.start, decl.id.end);
|
|
1746
1832
|
}
|
|
1747
|
-
if (isDefineProps ||
|
|
1748
|
-
if (
|
|
1833
|
+
if (isDefineProps || isDefineEmits)
|
|
1834
|
+
if (left === 1) {
|
|
1749
1835
|
s.remove(node.start + startOffset, node.end + startOffset);
|
|
1750
1836
|
}
|
|
1751
1837
|
else {
|
|
1752
|
-
|
|
1838
|
+
let start = decl.start + startOffset;
|
|
1839
|
+
let end = decl.end + startOffset;
|
|
1840
|
+
if (i < total - 1) {
|
|
1841
|
+
// not the last one, locate the start of the next
|
|
1842
|
+
end = node.declarations[i + 1].start + startOffset;
|
|
1843
|
+
}
|
|
1844
|
+
else {
|
|
1845
|
+
// last one, locate the end of the prev
|
|
1846
|
+
start = node.declarations[i - 1].end + startOffset;
|
|
1847
|
+
}
|
|
1848
|
+
s.remove(start, end);
|
|
1849
|
+
left--;
|
|
1753
1850
|
}
|
|
1754
1851
|
}
|
|
1755
1852
|
}
|
|
@@ -1761,16 +1858,6 @@ function compileScript(sfc, options) {
|
|
|
1761
1858
|
!node.declare) {
|
|
1762
1859
|
walkDeclaration(node, setupBindings, userImportAlias);
|
|
1763
1860
|
}
|
|
1764
|
-
// Type declarations
|
|
1765
|
-
if (node.type === 'VariableDeclaration' && node.declare) {
|
|
1766
|
-
s.remove(start, end);
|
|
1767
|
-
}
|
|
1768
|
-
// move all type declarations to outer scope
|
|
1769
|
-
if (node.type.startsWith('TS') ||
|
|
1770
|
-
(node.type === 'ExportNamedDeclaration' && node.exportKind === 'type')) {
|
|
1771
|
-
recordType(node, declaredTypes);
|
|
1772
|
-
s.move(start, end, 0);
|
|
1773
|
-
}
|
|
1774
1861
|
// walk statements & named exports / variable declarations for top level
|
|
1775
1862
|
// await
|
|
1776
1863
|
if ((node.type === 'VariableDeclaration' && !node.declare) ||
|
|
@@ -1782,6 +1869,8 @@ function compileScript(sfc, options) {
|
|
|
1782
1869
|
}
|
|
1783
1870
|
if (node.type === 'AwaitExpression') {
|
|
1784
1871
|
hasAwait = true;
|
|
1872
|
+
s.prependRight(node.argument.start + startOffset, helper(`withAsyncContext`) + `(`);
|
|
1873
|
+
s.appendLeft(node.argument.end + startOffset, `)`);
|
|
1785
1874
|
}
|
|
1786
1875
|
}
|
|
1787
1876
|
});
|
|
@@ -1793,6 +1882,52 @@ function compileScript(sfc, options) {
|
|
|
1793
1882
|
`If you are using a previous version of <script setup>, please ` +
|
|
1794
1883
|
`consult the updated RFC at https://github.com/vuejs/rfcs/pull/227.`, node);
|
|
1795
1884
|
}
|
|
1885
|
+
if (isTS) {
|
|
1886
|
+
// runtime enum
|
|
1887
|
+
if (node.type === 'TSEnumDeclaration' && !node.const) {
|
|
1888
|
+
registerBinding(setupBindings, node.id, "setup-const" /* SETUP_CONST */);
|
|
1889
|
+
}
|
|
1890
|
+
// move all Type declarations to outer scope
|
|
1891
|
+
if (node.type.startsWith('TS') ||
|
|
1892
|
+
(node.type === 'ExportNamedDeclaration' &&
|
|
1893
|
+
node.exportKind === 'type') ||
|
|
1894
|
+
(node.type === 'VariableDeclaration' && node.declare)) {
|
|
1895
|
+
recordType(node, declaredTypes);
|
|
1896
|
+
s.move(start, end, 0);
|
|
1897
|
+
}
|
|
1898
|
+
}
|
|
1899
|
+
}
|
|
1900
|
+
// in parse only mode, we should have collected all the information we need,
|
|
1901
|
+
// return early.
|
|
1902
|
+
if (parseOnly) {
|
|
1903
|
+
for (const key in userImports) {
|
|
1904
|
+
const { rangeNode, isFromSetup } = userImports[key];
|
|
1905
|
+
const bindings = isFromSetup
|
|
1906
|
+
? ranges.scriptSetupBindings
|
|
1907
|
+
: ranges.scriptBindings;
|
|
1908
|
+
bindings.push(toTextRange(rangeNode));
|
|
1909
|
+
}
|
|
1910
|
+
for (const key in setupBindings) {
|
|
1911
|
+
ranges.scriptSetupBindings.push(toTextRange(setupBindings[key].rangeNode));
|
|
1912
|
+
}
|
|
1913
|
+
if (propsRuntimeDecl) {
|
|
1914
|
+
ranges.propsRuntimeArg = toTextRange(propsRuntimeDecl);
|
|
1915
|
+
}
|
|
1916
|
+
if (propsTypeDeclRaw) {
|
|
1917
|
+
ranges.propsTypeArg = toTextRange(propsTypeDeclRaw);
|
|
1918
|
+
}
|
|
1919
|
+
if (emitsRuntimeDecl) {
|
|
1920
|
+
ranges.emitsRuntimeArg = toTextRange(emitsRuntimeDecl);
|
|
1921
|
+
}
|
|
1922
|
+
if (emitsTypeDeclRaw) {
|
|
1923
|
+
ranges.emitsTypeArg = toTextRange(emitsTypeDeclRaw);
|
|
1924
|
+
}
|
|
1925
|
+
if (propsRuntimeDefaults) {
|
|
1926
|
+
ranges.withDefaultsArg = toTextRange(propsRuntimeDefaults);
|
|
1927
|
+
}
|
|
1928
|
+
return Object.assign(Object.assign({}, scriptSetup), { ranges,
|
|
1929
|
+
scriptAst,
|
|
1930
|
+
scriptSetupAst });
|
|
1796
1931
|
}
|
|
1797
1932
|
// 3. Do a full walk to rewrite identifiers referencing let exports with ref
|
|
1798
1933
|
// value access
|
|
@@ -1826,13 +1961,14 @@ function compileScript(sfc, options) {
|
|
|
1826
1961
|
if (propsTypeDecl) {
|
|
1827
1962
|
extractRuntimeProps(propsTypeDecl, typeDeclaredProps, declaredTypes);
|
|
1828
1963
|
}
|
|
1829
|
-
if (
|
|
1830
|
-
extractRuntimeEmits(
|
|
1964
|
+
if (emitsTypeDecl) {
|
|
1965
|
+
extractRuntimeEmits(emitsTypeDecl, typeDeclaredEmits);
|
|
1831
1966
|
}
|
|
1832
1967
|
// 5. check useOptions args to make sure it doesn't reference setup scope
|
|
1833
1968
|
// variables
|
|
1834
1969
|
checkInvalidScopeReference(propsRuntimeDecl, DEFINE_PROPS);
|
|
1835
|
-
checkInvalidScopeReference(
|
|
1970
|
+
checkInvalidScopeReference(propsRuntimeDefaults, DEFINE_PROPS);
|
|
1971
|
+
checkInvalidScopeReference(emitsRuntimeDecl, DEFINE_PROPS);
|
|
1836
1972
|
// 6. remove non-script content
|
|
1837
1973
|
if (script) {
|
|
1838
1974
|
if (startOffset < scriptStartOffset) {
|
|
@@ -1874,7 +2010,7 @@ function compileScript(sfc, options) {
|
|
|
1874
2010
|
: "setup-maybe-ref" /* SETUP_MAYBE_REF */;
|
|
1875
2011
|
}
|
|
1876
2012
|
for (const key in setupBindings) {
|
|
1877
|
-
bindingMetadata[key] = setupBindings[key];
|
|
2013
|
+
bindingMetadata[key] = setupBindings[key].type;
|
|
1878
2014
|
}
|
|
1879
2015
|
// 8. inject `useCssVars` calls
|
|
1880
2016
|
if (cssVars.length) {
|
|
@@ -1893,15 +2029,14 @@ function compileScript(sfc, options) {
|
|
|
1893
2029
|
if (propsIdentifier) {
|
|
1894
2030
|
s.prependRight(startOffset, `\nconst ${propsIdentifier} = __props`);
|
|
1895
2031
|
}
|
|
2032
|
+
const destructureElements = hasDefineExposeCall || !options.inlineTemplate ? [`expose`] : [];
|
|
1896
2033
|
if (emitIdentifier) {
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
attrs: any
|
|
1904
|
-
}`;
|
|
2034
|
+
destructureElements.push(emitIdentifier === `emit` ? `emit` : `emit: ${emitIdentifier}`);
|
|
2035
|
+
}
|
|
2036
|
+
if (destructureElements.length) {
|
|
2037
|
+
args += `, { ${destructureElements.join(', ')} }`;
|
|
2038
|
+
if (emitsTypeDecl) {
|
|
2039
|
+
args += `: { emit: (${scriptSetup.content.slice(emitsTypeDecl.start, emitsTypeDecl.end)}), expose: any, slots: any, attrs: any }`;
|
|
1905
2040
|
}
|
|
1906
2041
|
}
|
|
1907
2042
|
// 10. generate return statement
|
|
@@ -1913,23 +2048,9 @@ function compileScript(sfc, options) {
|
|
|
1913
2048
|
}
|
|
1914
2049
|
// inline render function mode - we are going to compile the template and
|
|
1915
2050
|
// inline it right here
|
|
1916
|
-
const { code, ast, preamble, tips, errors } = compileTemplate({
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
inMap: sfc.template.map,
|
|
1920
|
-
...options.templateOptions,
|
|
1921
|
-
id: scopeId,
|
|
1922
|
-
scoped: sfc.styles.some(s => s.scoped),
|
|
1923
|
-
isProd: options.isProd,
|
|
1924
|
-
ssrCssVars: sfc.cssVars,
|
|
1925
|
-
compilerOptions: {
|
|
1926
|
-
...(options.templateOptions &&
|
|
1927
|
-
options.templateOptions.compilerOptions),
|
|
1928
|
-
inline: true,
|
|
1929
|
-
isTS,
|
|
1930
|
-
bindingMetadata
|
|
1931
|
-
}
|
|
1932
|
-
});
|
|
2051
|
+
const { code, ast, preamble, tips, errors } = compileTemplate(Object.assign(Object.assign({ filename, source: sfc.template.content, inMap: sfc.template.map }, options.templateOptions), { id: scopeId, scoped: sfc.styles.some(s => s.scoped), isProd: options.isProd, ssrCssVars: sfc.cssVars, compilerOptions: Object.assign(Object.assign({}, (options.templateOptions &&
|
|
2052
|
+
options.templateOptions.compilerOptions)), { inline: true, isTS,
|
|
2053
|
+
bindingMetadata }) }));
|
|
1933
2054
|
if (tips.length) {
|
|
1934
2055
|
tips.forEach(warnOnce);
|
|
1935
2056
|
}
|
|
@@ -1965,7 +2086,7 @@ function compileScript(sfc, options) {
|
|
|
1965
2086
|
}
|
|
1966
2087
|
else {
|
|
1967
2088
|
// return bindings from setup
|
|
1968
|
-
const allBindings = {
|
|
2089
|
+
const allBindings = Object.assign({}, setupBindings);
|
|
1969
2090
|
for (const key in userImports) {
|
|
1970
2091
|
if (!userImports[key].isType) {
|
|
1971
2092
|
allBindings[key] = true;
|
|
@@ -1973,13 +2094,19 @@ function compileScript(sfc, options) {
|
|
|
1973
2094
|
}
|
|
1974
2095
|
returned = `{ ${Object.keys(allBindings).join(', ')} }`;
|
|
1975
2096
|
}
|
|
1976
|
-
|
|
1977
|
-
|
|
1978
|
-
|
|
1979
|
-
|
|
1980
|
-
|
|
1981
|
-
|
|
2097
|
+
if (!options.inlineTemplate && !false) {
|
|
2098
|
+
// in non-inline mode, the `__isScriptSetup: true` flag is used by
|
|
2099
|
+
// componentPublicInstance proxy to allow properties that start with $ or _
|
|
2100
|
+
s.appendRight(endOffset, `\nconst __returned__ = ${returned}\n` +
|
|
2101
|
+
`Object.defineProperty(__returned__, '__isScriptSetup', { enumerable: false, value: true })\n` +
|
|
2102
|
+
`return __returned__` +
|
|
2103
|
+
`\n}\n\n`);
|
|
1982
2104
|
}
|
|
2105
|
+
else {
|
|
2106
|
+
s.appendRight(endOffset, `\nreturn ${returned}\n}\n\n`);
|
|
2107
|
+
}
|
|
2108
|
+
// 11. finalize default export
|
|
2109
|
+
let runtimeOptions = ``;
|
|
1983
2110
|
if (hasInlinedSsrRenderFn) {
|
|
1984
2111
|
runtimeOptions += `\n __ssrInlineRender: true,`;
|
|
1985
2112
|
}
|
|
@@ -1991,14 +2118,17 @@ function compileScript(sfc, options) {
|
|
|
1991
2118
|
else if (propsTypeDecl) {
|
|
1992
2119
|
runtimeOptions += genRuntimeProps(typeDeclaredProps);
|
|
1993
2120
|
}
|
|
1994
|
-
if (
|
|
2121
|
+
if (emitsRuntimeDecl) {
|
|
1995
2122
|
runtimeOptions += `\n emits: ${scriptSetup.content
|
|
1996
|
-
.slice(
|
|
2123
|
+
.slice(emitsRuntimeDecl.start, emitsRuntimeDecl.end)
|
|
1997
2124
|
.trim()},`;
|
|
1998
2125
|
}
|
|
1999
|
-
else if (
|
|
2126
|
+
else if (emitsTypeDecl) {
|
|
2000
2127
|
runtimeOptions += genRuntimeEmits(typeDeclaredEmits);
|
|
2001
2128
|
}
|
|
2129
|
+
// <script setup> components are closed by default. If the user did not
|
|
2130
|
+
// explicitly call `defineExpose`, call expose() with no args.
|
|
2131
|
+
const exposeCall = hasDefineExposeCall || options.inlineTemplate ? `` : ` expose()\n`;
|
|
2002
2132
|
if (isTS) {
|
|
2003
2133
|
// for TS, make sure the exported type is still valid type with
|
|
2004
2134
|
// correct props information
|
|
@@ -2008,7 +2138,7 @@ function compileScript(sfc, options) {
|
|
|
2008
2138
|
// wrap setup code with function.
|
|
2009
2139
|
// export the content of <script setup> as a named export, `setup`.
|
|
2010
2140
|
// this allows `import { setup } from '*.vue'` for testing purposes.
|
|
2011
|
-
s.prependLeft(startOffset, `\nexport default ${helper(`defineComponent`)}({${def}${runtimeOptions}\n ${hasAwait ? `async ` : ``}setup(${args}) {\n`);
|
|
2141
|
+
s.prependLeft(startOffset, `\nexport default ${helper(`defineComponent`)}({${def}${runtimeOptions}\n ${hasAwait ? `async ` : ``}setup(${args}) {\n${exposeCall}`);
|
|
2012
2142
|
s.appendRight(endOffset, `})`);
|
|
2013
2143
|
}
|
|
2014
2144
|
else {
|
|
@@ -2019,7 +2149,7 @@ function compileScript(sfc, options) {
|
|
|
2019
2149
|
}
|
|
2020
2150
|
else {
|
|
2021
2151
|
s.prependLeft(startOffset, `\nexport default {${runtimeOptions}\n ` +
|
|
2022
|
-
`${hasAwait ? `async ` : ``}setup(${args}) {\n`);
|
|
2152
|
+
`${hasAwait ? `async ` : ``}setup(${args}) {\n${exposeCall}`);
|
|
2023
2153
|
s.appendRight(endOffset, `}`);
|
|
2024
2154
|
}
|
|
2025
2155
|
}
|
|
@@ -2030,17 +2160,17 @@ function compileScript(sfc, options) {
|
|
|
2030
2160
|
.join(', ')} } from 'vue'\n`);
|
|
2031
2161
|
}
|
|
2032
2162
|
s.trim();
|
|
2033
|
-
return {
|
|
2034
|
-
...scriptSetup,
|
|
2035
|
-
bindings: bindingMetadata,
|
|
2036
|
-
content: s.toString(),
|
|
2037
|
-
map: s.generateMap({
|
|
2163
|
+
return Object.assign(Object.assign({}, scriptSetup), { bindings: bindingMetadata, content: s.toString(), map: s.generateMap({
|
|
2038
2164
|
source: filename,
|
|
2039
2165
|
hires: true,
|
|
2040
2166
|
includeContent: true
|
|
2041
|
-
}),
|
|
2042
|
-
|
|
2043
|
-
|
|
2167
|
+
}), scriptAst,
|
|
2168
|
+
scriptSetupAst });
|
|
2169
|
+
}
|
|
2170
|
+
function registerBinding(bindings, node, type) {
|
|
2171
|
+
bindings[node.name] = {
|
|
2172
|
+
type,
|
|
2173
|
+
rangeNode: node
|
|
2044
2174
|
};
|
|
2045
2175
|
}
|
|
2046
2176
|
function walkDeclaration(node, bindings, userImportAlias) {
|
|
@@ -2049,7 +2179,10 @@ function walkDeclaration(node, bindings, userImportAlias) {
|
|
|
2049
2179
|
// export const foo = ...
|
|
2050
2180
|
for (const { id, init } of node.declarations) {
|
|
2051
2181
|
const isDefineCall = !!(isConst &&
|
|
2052
|
-
|
|
2182
|
+
isCallOf(init, c => c === DEFINE_PROPS ||
|
|
2183
|
+
c === DEFINE_EMIT ||
|
|
2184
|
+
c === DEFINE_EMITS ||
|
|
2185
|
+
c === WITH_DEFAULTS));
|
|
2053
2186
|
if (id.type === 'Identifier') {
|
|
2054
2187
|
let bindingType;
|
|
2055
2188
|
const userReactiveBinding = userImportAlias['reactive'] || 'reactive';
|
|
@@ -2075,7 +2208,7 @@ function walkDeclaration(node, bindings, userImportAlias) {
|
|
|
2075
2208
|
else {
|
|
2076
2209
|
bindingType = "setup-let" /* SETUP_LET */;
|
|
2077
2210
|
}
|
|
2078
|
-
bindings
|
|
2211
|
+
registerBinding(bindings, id, bindingType);
|
|
2079
2212
|
}
|
|
2080
2213
|
else if (id.type === 'ObjectPattern') {
|
|
2081
2214
|
walkObjectPattern(id, bindings, isConst, isDefineCall);
|
|
@@ -2089,7 +2222,10 @@ function walkDeclaration(node, bindings, userImportAlias) {
|
|
|
2089
2222
|
node.type === 'ClassDeclaration') {
|
|
2090
2223
|
// export function foo() {} / export class Foo {}
|
|
2091
2224
|
// export declarations must be named.
|
|
2092
|
-
bindings[node.id.name] =
|
|
2225
|
+
bindings[node.id.name] = {
|
|
2226
|
+
type: "setup-const" /* SETUP_CONST */,
|
|
2227
|
+
rangeNode: node.id
|
|
2228
|
+
};
|
|
2093
2229
|
}
|
|
2094
2230
|
}
|
|
2095
2231
|
function walkObjectPattern(node, bindings, isConst, isDefineCall = false) {
|
|
@@ -2099,11 +2235,12 @@ function walkObjectPattern(node, bindings, isConst, isDefineCall = false) {
|
|
|
2099
2235
|
if (p.key.type === 'Identifier') {
|
|
2100
2236
|
if (p.key === p.value) {
|
|
2101
2237
|
// const { x } = ...
|
|
2102
|
-
|
|
2238
|
+
const type = isDefineCall
|
|
2103
2239
|
? "setup-const" /* SETUP_CONST */
|
|
2104
2240
|
: isConst
|
|
2105
2241
|
? "setup-maybe-ref" /* SETUP_MAYBE_REF */
|
|
2106
2242
|
: "setup-let" /* SETUP_LET */;
|
|
2243
|
+
registerBinding(bindings, p.key, type);
|
|
2107
2244
|
}
|
|
2108
2245
|
else {
|
|
2109
2246
|
walkPattern(p.value, bindings, isConst, isDefineCall);
|
|
@@ -2113,9 +2250,8 @@ function walkObjectPattern(node, bindings, isConst, isDefineCall = false) {
|
|
|
2113
2250
|
else {
|
|
2114
2251
|
// ...rest
|
|
2115
2252
|
// argument can only be identifer when destructuring
|
|
2116
|
-
|
|
2117
|
-
|
|
2118
|
-
: "setup-let" /* SETUP_LET */;
|
|
2253
|
+
const type = isConst ? "setup-const" /* SETUP_CONST */ : "setup-let" /* SETUP_LET */;
|
|
2254
|
+
registerBinding(bindings, p.argument, type);
|
|
2119
2255
|
}
|
|
2120
2256
|
}
|
|
2121
2257
|
}
|
|
@@ -2126,17 +2262,17 @@ function walkArrayPattern(node, bindings, isConst, isDefineCall = false) {
|
|
|
2126
2262
|
}
|
|
2127
2263
|
function walkPattern(node, bindings, isConst, isDefineCall = false) {
|
|
2128
2264
|
if (node.type === 'Identifier') {
|
|
2129
|
-
|
|
2265
|
+
const type = isDefineCall
|
|
2130
2266
|
? "setup-const" /* SETUP_CONST */
|
|
2131
2267
|
: isConst
|
|
2132
2268
|
? "setup-maybe-ref" /* SETUP_MAYBE_REF */
|
|
2133
2269
|
: "setup-let" /* SETUP_LET */;
|
|
2270
|
+
registerBinding(bindings, node, type);
|
|
2134
2271
|
}
|
|
2135
2272
|
else if (node.type === 'RestElement') {
|
|
2136
2273
|
// argument can only be identifer when destructuring
|
|
2137
|
-
|
|
2138
|
-
|
|
2139
|
-
: "setup-let" /* SETUP_LET */;
|
|
2274
|
+
const type = isConst ? "setup-const" /* SETUP_CONST */ : "setup-let" /* SETUP_LET */;
|
|
2275
|
+
registerBinding(bindings, node.argument, type);
|
|
2140
2276
|
}
|
|
2141
2277
|
else if (node.type === 'ObjectPattern') {
|
|
2142
2278
|
walkObjectPattern(node, bindings, isConst);
|
|
@@ -2146,11 +2282,12 @@ function walkPattern(node, bindings, isConst, isDefineCall = false) {
|
|
|
2146
2282
|
}
|
|
2147
2283
|
else if (node.type === 'AssignmentPattern') {
|
|
2148
2284
|
if (node.left.type === 'Identifier') {
|
|
2149
|
-
|
|
2285
|
+
const type = isDefineCall
|
|
2150
2286
|
? "setup-const" /* SETUP_CONST */
|
|
2151
2287
|
: isConst
|
|
2152
2288
|
? "setup-maybe-ref" /* SETUP_MAYBE_REF */
|
|
2153
2289
|
: "setup-let" /* SETUP_LET */;
|
|
2290
|
+
registerBinding(bindings, node.left, type);
|
|
2154
2291
|
}
|
|
2155
2292
|
else {
|
|
2156
2293
|
walkPattern(node.left, bindings, isConst);
|
|
@@ -2169,14 +2306,23 @@ function recordType(node, declaredTypes) {
|
|
|
2169
2306
|
}
|
|
2170
2307
|
}
|
|
2171
2308
|
function extractRuntimeProps(node, props, declaredTypes) {
|
|
2172
|
-
|
|
2173
|
-
|
|
2309
|
+
const members = node.type === 'TSTypeLiteral' ? node.members : node.body;
|
|
2310
|
+
for (const m of members) {
|
|
2311
|
+
if ((m.type === 'TSPropertySignature' || m.type === 'TSMethodSignature') &&
|
|
2312
|
+
m.key.type === 'Identifier') {
|
|
2313
|
+
let type;
|
|
2314
|
+
{
|
|
2315
|
+
if (m.type === 'TSMethodSignature') {
|
|
2316
|
+
type = ['Function'];
|
|
2317
|
+
}
|
|
2318
|
+
else if (m.typeAnnotation) {
|
|
2319
|
+
type = inferRuntimeType(m.typeAnnotation.typeAnnotation, declaredTypes);
|
|
2320
|
+
}
|
|
2321
|
+
}
|
|
2174
2322
|
props[m.key.name] = {
|
|
2175
2323
|
key: m.key.name,
|
|
2176
2324
|
required: !m.optional,
|
|
2177
|
-
type:
|
|
2178
|
-
? inferRuntimeType(m.typeAnnotation.typeAnnotation, declaredTypes)
|
|
2179
|
-
: [`null`]
|
|
2325
|
+
type: type || [`null`]
|
|
2180
2326
|
};
|
|
2181
2327
|
}
|
|
2182
2328
|
}
|
|
@@ -2249,18 +2395,6 @@ function inferRuntimeType(node, declaredTypes) {
|
|
|
2249
2395
|
return [`null`]; // no runtime check
|
|
2250
2396
|
}
|
|
2251
2397
|
}
|
|
2252
|
-
function genRuntimeProps(props) {
|
|
2253
|
-
const keys = Object.keys(props);
|
|
2254
|
-
if (!keys.length) {
|
|
2255
|
-
return ``;
|
|
2256
|
-
}
|
|
2257
|
-
return `\n props: {\n ${keys
|
|
2258
|
-
.map(key => {
|
|
2259
|
-
const { type, required } = props[key];
|
|
2260
|
-
return `${key}: { type: ${toRuntimeTypeString(type)}, required: ${required} }`;
|
|
2261
|
-
})
|
|
2262
|
-
.join(',\n ')}\n } as unknown as undefined,`;
|
|
2263
|
-
}
|
|
2264
2398
|
function toRuntimeTypeString(types) {
|
|
2265
2399
|
return types.some(t => t === 'null')
|
|
2266
2400
|
? `null`
|
|
@@ -2269,8 +2403,9 @@ function toRuntimeTypeString(types) {
|
|
|
2269
2403
|
: types[0];
|
|
2270
2404
|
}
|
|
2271
2405
|
function extractRuntimeEmits(node, emits) {
|
|
2272
|
-
if (node.type === 'TSTypeLiteral') {
|
|
2273
|
-
|
|
2406
|
+
if (node.type === 'TSTypeLiteral' || node.type === 'TSInterfaceBody') {
|
|
2407
|
+
const members = node.type === 'TSTypeLiteral' ? node.members : node.body;
|
|
2408
|
+
for (let t of members) {
|
|
2274
2409
|
if (t.type === 'TSCallSignatureDeclaration') {
|
|
2275
2410
|
extractEventNames(t.parameters[0], emits);
|
|
2276
2411
|
}
|
|
@@ -2386,6 +2521,9 @@ function walkIdentifiers(root, onIdentifier) {
|
|
|
2386
2521
|
});
|
|
2387
2522
|
}
|
|
2388
2523
|
function isRefIdentifier(id, parent, parentStack) {
|
|
2524
|
+
if (!parent) {
|
|
2525
|
+
return true;
|
|
2526
|
+
}
|
|
2389
2527
|
// declaration id
|
|
2390
2528
|
if ((parent.type === 'VariableDeclarator' ||
|
|
2391
2529
|
parent.type === 'ClassDeclaration') &&
|
|
@@ -2432,11 +2570,13 @@ const isStaticPropertyKey = (node, parent) => isStaticProperty(parent) && parent
|
|
|
2432
2570
|
function isFunction(node) {
|
|
2433
2571
|
return /Function(?:Expression|Declaration)$|Method$/.test(node.type);
|
|
2434
2572
|
}
|
|
2435
|
-
function isCallOf(node,
|
|
2573
|
+
function isCallOf(node, test) {
|
|
2436
2574
|
return !!(node &&
|
|
2437
2575
|
node.type === 'CallExpression' &&
|
|
2438
2576
|
node.callee.type === 'Identifier' &&
|
|
2439
|
-
|
|
2577
|
+
(typeof test === 'string'
|
|
2578
|
+
? node.callee.name === test
|
|
2579
|
+
: test(node.callee.name)));
|
|
2440
2580
|
}
|
|
2441
2581
|
function canNeverBeRef(node, userReactiveImport) {
|
|
2442
2582
|
if (isCallOf(node, userReactiveImport)) {
|
|
@@ -2627,6 +2767,12 @@ function extractIdentifiers(param, nodes = []) {
|
|
|
2627
2767
|
break;
|
|
2628
2768
|
}
|
|
2629
2769
|
return nodes;
|
|
2770
|
+
}
|
|
2771
|
+
function toTextRange(node) {
|
|
2772
|
+
return {
|
|
2773
|
+
start: node.start,
|
|
2774
|
+
end: node.end
|
|
2775
|
+
};
|
|
2630
2776
|
}
|
|
2631
2777
|
|
|
2632
2778
|
exports.generateCodeFrame = compilerCore.generateCodeFrame;
|