@shijiu/jsview-vue 0.9.254 → 0.9.267
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/dom/bin/package.json +11 -11
- package/dom/browser-root-style.css +21 -21
- package/loader/jsview-main.js +41 -41
- package/loader/jsview.config.default.js +37 -37
- package/loader/jsview.default.config.js +37 -37
- package/package.json +1 -5
- package/samples/AdvanceMetroWidget/App.vue +122 -122
- package/samples/AdvanceMetroWidget/Frame.vue +100 -100
- package/samples/AdvanceMetroWidget/Item.vue +57 -57
- package/samples/AdvanceMetroWidget/data.js +136 -136
- package/samples/AnimPicture/App.vue +223 -223
- package/samples/Basic/App.vue +128 -128
- package/samples/Basic/components/TitleBar.vue +28 -28
- package/samples/Basic/components/anim/AnimGroup.vue +67 -67
- package/samples/Basic/components/anim/AnimKeyframeBasic.vue +101 -101
- package/samples/Basic/components/anim/AnimKeyframeComposite.vue +52 -52
- package/samples/Basic/components/anim/AnimTransition.vue +116 -116
- package/samples/Basic/components/div/DivBackground.vue +14 -14
- package/samples/Basic/components/div/DivClip.vue +80 -80
- package/samples/Basic/components/div/DivCssScoped.vue +26 -26
- package/samples/Basic/components/div/DivCssVar.vue +49 -49
- package/samples/Basic/components/div/DivGroup1.vue +32 -32
- package/samples/Basic/components/div/DivGroup2.vue +40 -40
- package/samples/Basic/components/div/DivLayout.vue +11 -11
- package/samples/Basic/components/div/DivRadius.vue +46 -46
- package/samples/Basic/components/text/TextAlign.vue +47 -47
- package/samples/Basic/components/text/TextFontStyle.vue +57 -57
- package/samples/Basic/components/text/TextGroup.vue +31 -31
- package/samples/Basic/components/text/TextOverflow.vue +77 -77
- package/samples/BasicFocusControl/App.vue +124 -124
- package/samples/BasicFocusControl/components/BaseBlock.vue +50 -50
- package/samples/BasicFocusControl/components/MainArea.vue +97 -97
- package/samples/BasicFocusControl/components/MainAreaLeftBlock.vue +20 -20
- package/samples/BasicFocusControl/components/MainAreaRightBlock.vue +29 -29
- package/samples/BasicFocusControl/components/SideBar.vue +72 -72
- package/samples/BasicFocusControl/components/SideBarBlock.vue +29 -29
- package/samples/ClassNameDemo/App.vue +119 -119
- package/samples/ClassNameDemo/components/ContentItem.vue +252 -252
- package/samples/ClassNameDemo/components/LoadingView.vue +43 -43
- package/samples/ClassNameDemo/components/TitleView.vue +24 -24
- package/samples/ClassNameDemo/data.js +24 -24
- package/samples/ColorSpace/App.vue +134 -134
- package/samples/DemoHomepage/App.vue +31 -31
- package/samples/DemoHomepage/components/BodyFrame.vue +81 -81
- package/samples/DemoHomepage/components/Dialog.vue +93 -93
- package/samples/DemoHomepage/components/Item.vue +76 -76
- package/samples/DemoHomepage/components/TabFrame.vue +86 -86
- package/samples/DemoHomepage/router.js +132 -132
- package/samples/DemoHomepage/views/Homepage.vue +186 -186
- package/samples/FlipCard/App.vue +80 -80
- package/samples/FlipCard/FlipCard.vue +123 -123
- package/samples/FlipCard/data.js +12 -12
- package/samples/FlowMultiWidget/App.vue +90 -90
- package/samples/FlowMultiWidget/components/Block.vue +106 -106
- package/samples/FlowMultiWidget/components/FlowPage.vue +59 -59
- package/samples/FlowMultiWidget/components/Item.vue +102 -102
- package/samples/FlowMultiWidget/components/MenuItem.vue +71 -71
- package/samples/FlowMultiWidget/components/MyMenu.vue +89 -89
- package/samples/FlowMultiWidget/data.js +446 -446
- package/samples/HashHistory/App.vue +124 -124
- package/samples/HashHistory/components/HorizontalButtonList.vue +113 -113
- package/samples/HashHistory/components/Item.vue +73 -73
- package/samples/HashHistory/router.js +29 -29
- package/samples/HashHistory/views/BasePage.vue +18 -18
- package/samples/HashHistory/views/MainPage.vue +67 -67
- package/samples/HashHistory/views/SubPage.vue +78 -78
- package/samples/HashHistory/views/SubPageFirst.vue +9 -9
- package/samples/HashHistory/views/SubPageSecond.vue +9 -9
- package/samples/LongImage/App.vue +96 -96
- package/samples/LongImage/Button.vue +153 -153
- package/samples/LongImage/LongImageScroll.vue +126 -126
- package/samples/LongImage/Scroll.vue +15 -15
- package/samples/LongText/App.vue +111 -111
- package/samples/LongText/Button.vue +153 -153
- package/samples/LongText/LongTextScroll.vue +224 -224
- package/samples/LongText/Scroll.vue +15 -15
- package/samples/Preload/App.vue +145 -145
- package/samples/Preload/data.js +22 -22
- package/samples/Preload/preloadItem.vue +21 -21
- package/samples/QrcodeDemo/App.vue +72 -72
- package/samples/SimpleWidgetDemo/App.vue +203 -203
- package/samples/SimpleWidgetDemo/Item.vue +82 -82
- package/samples/SimpleWidgetDemo/components/ContentItem.vue +411 -411
- package/samples/SimpleWidgetDemo/components/MyTab.vue +116 -116
- package/samples/SimpleWidgetDemo/data.js +110 -110
- package/samples/SprayView/App.vue +269 -269
- package/samples/SpriteImage/App.vue +174 -174
- package/samples/SpriteImage/images/egg_break.json +116 -116
- package/samples/TextBox/App.vue +178 -178
- package/samples/TextBox/RenderCenter.vue +108 -108
- package/samples/TextBox/RenderLeft.vue +108 -108
- package/samples/TextBox/RenderOneLine.vue +119 -119
- package/samples/TextBox/RenderRight.vue +106 -106
- package/samples/TextShadowDemo/App.vue +97 -97
- package/samples/TextureSize/App.vue +141 -141
- package/samples/ThrowMoveDemo/AccelerateDemo.vue +117 -117
- package/samples/ThrowMoveDemo/App.vue +113 -113
- package/samples/ThrowMoveDemo/LRParabolicDemo.vue +115 -115
- package/samples/ThrowMoveDemo/TargetDemo.vue +116 -116
- package/samples/ThrowMoveDemo/UDParabolicDemo.vue +121 -121
- package/samples/TransitPage/App.vue +40 -40
- package/samples/VideoDemo/App.vue +137 -137
- package/samples/VideoDemo/components/Button.vue +68 -68
- package/samples/VideoDemo/components/Controllor.vue +195 -195
- package/samples/VideoDemo/components/VideoFrame.vue +152 -152
- package/scripts/common.js +57 -115
- package/scripts/jsview-install-local-packages.js +73 -73
- package/scripts/jsview-post-build.js +127 -127
- package/scripts/jsview-post-install.js +78 -78
- package/scripts/jsview-run-android.js +64 -64
- package/utils/JsViewEngineWidget/bin/index.js +1 -1
- package/utils/JsViewEngineWidget/bin/package.json +11 -11
- package/utils/JsViewVueTools/JsvHashHistory.js +111 -111
- package/utils/JsViewVueTools/JsvRuntimeBridge.js +417 -417
- package/utils/JsViewVueWidget/BrowserDebugWidget/BrowserPreload.vue +80 -80
- package/utils/JsViewVueWidget/BrowserDebugWidget/BrowserQrcode.vue +147 -147
- package/utils/JsViewVueWidget/BrowserDebugWidget/BrowserSpray.vue +54 -54
- package/utils/JsViewVueWidget/BrowserDebugWidget/JsvApic/ApicDataBase.js +28 -28
- package/utils/JsViewVueWidget/BrowserDebugWidget/JsvApic/BrowserApic.vue +123 -123
- package/utils/JsViewVueWidget/BrowserDebugWidget/JsvApic/GifData.js +83 -83
- package/utils/JsViewVueWidget/BrowserDebugWidget/JsvApic/LoopToolBase.js +25 -25
- package/utils/JsViewVueWidget/BrowserDebugWidget/JsvApic/NormalLoopTool.js +61 -61
- package/utils/JsViewVueWidget/BrowserDebugWidget/JsvApic/PartLoopTool.js +119 -119
- package/utils/JsViewVueWidget/BrowserDebugWidget/JsvApic/Viewer.js +106 -106
- package/utils/JsViewVueWidget/BrowserDebugWidget/JsvApic/WebpData.js +141 -141
- package/utils/JsViewVueWidget/BrowserDebugWidget/WidgetLoader.js +20 -20
- package/utils/JsViewVueWidget/JsvActorMove/ActorControlBase.js +204 -204
- package/utils/JsViewVueWidget/JsvActorMove/JsvActorMove.vue +63 -63
- package/utils/JsViewVueWidget/JsvActorMove/JsvActorMoveControl.js +426 -426
- package/utils/JsViewVueWidget/JsvActorMove/index.js +12 -12
- package/utils/JsViewVueWidget/JsvApic/JsvApic.vue +178 -178
- package/utils/JsViewVueWidget/JsvApic/index.js +17 -17
- package/utils/JsViewVueWidget/JsvMarquee.vue +196 -196
- package/utils/JsViewVueWidget/JsvNinePatch.vue +76 -76
- package/utils/JsViewVueWidget/JsvPreload/JsvPreload.vue +350 -350
- package/utils/JsViewVueWidget/JsvPreload/index.js +21 -21
- package/utils/JsViewVueWidget/JsvQrcode/JsvQrcode.vue +140 -140
- package/utils/JsViewVueWidget/JsvQrcode/index.js +18 -18
- package/utils/JsViewVueWidget/JsvSpray/JsvSpray.vue +139 -139
- package/utils/JsViewVueWidget/JsvSpray/index.js +14 -14
- package/utils/JsViewVueWidget/JsvSpriteAnim/JsvSpriteAnim.vue +447 -447
- package/utils/JsViewVueWidget/JsvSpriteAnim/SpriteController.js +56 -56
- package/utils/JsViewVueWidget/JsvSpriteAnim/index.js +6 -6
- package/utils/JsViewVueWidget/JsvSwiper/Indicator.vue +34 -34
- package/utils/JsViewVueWidget/JsvSwiper/JsvSwiper.vue +494 -494
- package/utils/JsViewVueWidget/JsvSwiper/index.js +9 -9
- package/utils/JsViewVueWidget/JsvSwiper3D/Indicator.vue +34 -34
- package/utils/JsViewVueWidget/JsvSwiper3D/JsvSwiper.vue +403 -403
- package/utils/JsViewVueWidget/JsvSwiper3D/index.js +9 -9
- package/utils/JsViewVueWidget/JsvTextBox.vue +110 -110
- package/utils/JsViewVueWidget/JsvVideo.vue +35 -35
- package/patches/node_modules/@babel/preset-env/lib/available-plugins.js +0 -219
- package/patches/node_modules/@vue/cli-plugin-typescript/index.js +0 -100
- package/patches/node_modules/@vue/cli-service/lib/commands/serve.js +0 -395
- package/patches/node_modules/@vue/cli-service/lib/config/app.js +0 -272
- package/patches/node_modules/@vue/cli-service/lib/config/assets.js +0 -70
- package/patches/node_modules/@vue/cli-service/lib/config/base.js +0 -212
- package/patches/node_modules/@vue/compiler-sfc/dist/compiler-sfc.cjs.js +0 -2566
- package/patches/node_modules/@vue/compiler-sfc/dist/jsview-css-to-js.js +0 -274
- package/patches/node_modules/@vue/runtime-dom/dist/runtime-dom.esm-bundler.js +0 -1596
- package/patches/node_modules/postcss-js/objectifier.js +0 -90
- package/patches/node_modules/vue-loader/dist/resolveScript.js +0 -70
- package/scripts/deploy-fast-pack.js +0 -17
- package/scripts/deploy-fast-publish.js +0 -44
- package/scripts/deploy-git-commit-empty.js +0 -21
- package/scripts/deploy-prepare.js +0 -56
- package/scripts/make-js.sh +0 -181
- package/vetur.config.js +0 -5
|
@@ -1,2566 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
-
|
|
5
|
-
var CompilerDOM = require('@vue/compiler-dom');
|
|
6
|
-
var sourceMap = require('source-map');
|
|
7
|
-
var hash = require('hash-sum');
|
|
8
|
-
var path = require('path');
|
|
9
|
-
var compilerCore = require('@vue/compiler-core');
|
|
10
|
-
var url = require('url');
|
|
11
|
-
var shared = require('@vue/shared');
|
|
12
|
-
var CompilerSSR = require('@vue/compiler-ssr');
|
|
13
|
-
var postcss = require('postcss');
|
|
14
|
-
var selectorParser = require('postcss-selector-parser');
|
|
15
|
-
var merge = require('merge-source-map');
|
|
16
|
-
var MagicString = require('magic-string');
|
|
17
|
-
var parser = require('@babel/parser');
|
|
18
|
-
var estreeWalker = require('estree-walker');
|
|
19
|
-
var refTransform = require('@vue/ref-transform');
|
|
20
|
-
var jsvCssToJs = require("./jsview-css-to-js"); // QCode Added
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e['default'] : e; }
|
|
24
|
-
|
|
25
|
-
function _interopNamespace(e) {
|
|
26
|
-
if (e && e.__esModule) return e;
|
|
27
|
-
var n = Object.create(null);
|
|
28
|
-
if (e) {
|
|
29
|
-
Object.keys(e).forEach(function (k) {
|
|
30
|
-
n[k] = e[k];
|
|
31
|
-
});
|
|
32
|
-
}
|
|
33
|
-
n['default'] = e;
|
|
34
|
-
return Object.freeze(n);
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
var CompilerDOM__namespace = /*#__PURE__*/_interopNamespace(CompilerDOM);
|
|
38
|
-
var hash__default = /*#__PURE__*/_interopDefaultLegacy(hash);
|
|
39
|
-
var path__default = /*#__PURE__*/_interopDefaultLegacy(path);
|
|
40
|
-
var CompilerSSR__namespace = /*#__PURE__*/_interopNamespace(CompilerSSR);
|
|
41
|
-
var postcss__default = /*#__PURE__*/_interopDefaultLegacy(postcss);
|
|
42
|
-
var selectorParser__default = /*#__PURE__*/_interopDefaultLegacy(selectorParser);
|
|
43
|
-
var merge__default = /*#__PURE__*/_interopDefaultLegacy(merge);
|
|
44
|
-
var MagicString__default = /*#__PURE__*/_interopDefaultLegacy(MagicString);
|
|
45
|
-
|
|
46
|
-
const CSS_VARS_HELPER = `useCssVars`;
|
|
47
|
-
const cssVarRE = /\bv-bind\(\s*(?:'([^']+)'|"([^"]+)"|([^'"][^)]*))\s*\)/g;
|
|
48
|
-
function genCssVarsFromList(vars, id, isProd) {
|
|
49
|
-
return `{\n ${vars
|
|
50
|
-
.map(key => `"${genVarName(id, key, isProd)}": (${key})`)
|
|
51
|
-
.join(',\n ')}\n}`;
|
|
52
|
-
}
|
|
53
|
-
function genVarName(id, raw, isProd) {
|
|
54
|
-
if (isProd) {
|
|
55
|
-
return hash__default(id + raw);
|
|
56
|
-
}
|
|
57
|
-
else {
|
|
58
|
-
return `${id}-${raw.replace(/([^\w-])/g, '_')}`;
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
function parseCssVars(sfc) {
|
|
62
|
-
const vars = [];
|
|
63
|
-
sfc.styles.forEach(style => {
|
|
64
|
-
let match;
|
|
65
|
-
// ignore v-bind() in comments /* ... */
|
|
66
|
-
const content = style.content.replace(/\/\*([\s\S]*?)\*\//g, '');
|
|
67
|
-
while ((match = cssVarRE.exec(content))) {
|
|
68
|
-
const variable = match[1] || match[2] || match[3];
|
|
69
|
-
if (!vars.includes(variable)) {
|
|
70
|
-
vars.push(variable);
|
|
71
|
-
}
|
|
72
|
-
}
|
|
73
|
-
});
|
|
74
|
-
return vars;
|
|
75
|
-
}
|
|
76
|
-
const cssVarsPlugin = opts => {
|
|
77
|
-
const { id, isProd } = opts;
|
|
78
|
-
return {
|
|
79
|
-
postcssPlugin: 'vue-sfc-vars',
|
|
80
|
-
Declaration(decl) {
|
|
81
|
-
// rewrite CSS variables
|
|
82
|
-
if (cssVarRE.test(decl.value)) {
|
|
83
|
-
decl.value = decl.value.replace(cssVarRE, (_, $1, $2, $3) => {
|
|
84
|
-
return `var(--${genVarName(id, $1 || $2 || $3, isProd)})`;
|
|
85
|
-
});
|
|
86
|
-
}
|
|
87
|
-
}
|
|
88
|
-
};
|
|
89
|
-
};
|
|
90
|
-
cssVarsPlugin.postcss = true;
|
|
91
|
-
function genCssVarsCode(vars, bindings, id, isProd) {
|
|
92
|
-
const varsExp = genCssVarsFromList(vars, id, isProd);
|
|
93
|
-
const exp = CompilerDOM.createSimpleExpression(varsExp, false);
|
|
94
|
-
const context = CompilerDOM.createTransformContext(CompilerDOM.createRoot([]), {
|
|
95
|
-
prefixIdentifiers: true,
|
|
96
|
-
inline: true,
|
|
97
|
-
bindingMetadata: bindings.__isScriptSetup === false ? undefined : bindings
|
|
98
|
-
});
|
|
99
|
-
const transformed = CompilerDOM.processExpression(exp, context);
|
|
100
|
-
const transformedString = transformed.type === 4 /* SIMPLE_EXPRESSION */
|
|
101
|
-
? transformed.content
|
|
102
|
-
: transformed.children
|
|
103
|
-
.map(c => {
|
|
104
|
-
return typeof c === 'string'
|
|
105
|
-
? c
|
|
106
|
-
: c.content;
|
|
107
|
-
})
|
|
108
|
-
.join('');
|
|
109
|
-
return `_${CSS_VARS_HELPER}(_ctx => (${transformedString}))`;
|
|
110
|
-
}
|
|
111
|
-
// <script setup> already gets the calls injected as part of the transform
|
|
112
|
-
// this is only for single normal <script>
|
|
113
|
-
function genNormalScriptCssVarsCode(cssVars, bindings, id, isProd) {
|
|
114
|
-
return (`\nimport { ${CSS_VARS_HELPER} as _${CSS_VARS_HELPER} } from 'vue'\n` +
|
|
115
|
-
`const __injectCSSVars__ = () => {\n${genCssVarsCode(cssVars, bindings, id, isProd)}}\n` +
|
|
116
|
-
`const __setup__ = __default__.setup\n` +
|
|
117
|
-
`__default__.setup = __setup__\n` +
|
|
118
|
-
` ? (props, ctx) => { __injectCSSVars__();return __setup__(props, ctx) }\n` +
|
|
119
|
-
` : __injectCSSVars__\n`);
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
function createCache(size = 500) {
|
|
123
|
-
return new (require('lru-cache'))(size);
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
const sourceToSFC = createCache();
|
|
127
|
-
function parse(source, { sourceMap = true, filename = 'anonymous.vue', sourceRoot = '', pad = false, ignoreEmpty = true, compiler = CompilerDOM__namespace } = {}) {
|
|
128
|
-
const sourceKey = source + sourceMap + filename + sourceRoot + pad + compiler.parse;
|
|
129
|
-
const cache = sourceToSFC.get(sourceKey);
|
|
130
|
-
if (cache) {
|
|
131
|
-
return cache;
|
|
132
|
-
}
|
|
133
|
-
const descriptor = {
|
|
134
|
-
filename,
|
|
135
|
-
source,
|
|
136
|
-
template: null,
|
|
137
|
-
script: null,
|
|
138
|
-
scriptSetup: null,
|
|
139
|
-
styles: [],
|
|
140
|
-
customBlocks: [],
|
|
141
|
-
cssVars: [],
|
|
142
|
-
slotted: false
|
|
143
|
-
};
|
|
144
|
-
const errors = [];
|
|
145
|
-
const ast = compiler.parse(source, {
|
|
146
|
-
// there are no components at SFC parsing level
|
|
147
|
-
isNativeTag: () => true,
|
|
148
|
-
// preserve all whitespaces
|
|
149
|
-
isPreTag: () => true,
|
|
150
|
-
getTextMode: ({ tag, props }, parent) => {
|
|
151
|
-
// all top level elements except <template> are parsed as raw text
|
|
152
|
-
// containers
|
|
153
|
-
if ((!parent && tag !== 'template') ||
|
|
154
|
-
// <template lang="xxx"> should also be treated as raw text
|
|
155
|
-
(tag === 'template' &&
|
|
156
|
-
props.some(p => p.type === 6 /* ATTRIBUTE */ &&
|
|
157
|
-
p.name === 'lang' &&
|
|
158
|
-
p.value &&
|
|
159
|
-
p.value.content &&
|
|
160
|
-
p.value.content !== 'html'))) {
|
|
161
|
-
return 2 /* RAWTEXT */;
|
|
162
|
-
}
|
|
163
|
-
else {
|
|
164
|
-
return 0 /* DATA */;
|
|
165
|
-
}
|
|
166
|
-
},
|
|
167
|
-
onError: e => {
|
|
168
|
-
errors.push(e);
|
|
169
|
-
}
|
|
170
|
-
});
|
|
171
|
-
ast.children.forEach(node => {
|
|
172
|
-
if (node.type !== 1 /* ELEMENT */) {
|
|
173
|
-
return;
|
|
174
|
-
}
|
|
175
|
-
// we only want to keep the nodes that are not empty (when the tag is not a template)
|
|
176
|
-
if (ignoreEmpty &&
|
|
177
|
-
node.tag !== 'template' &&
|
|
178
|
-
isEmpty(node) &&
|
|
179
|
-
!hasSrc(node)) {
|
|
180
|
-
return;
|
|
181
|
-
}
|
|
182
|
-
switch (node.tag) {
|
|
183
|
-
case 'template':
|
|
184
|
-
if (!descriptor.template) {
|
|
185
|
-
const templateBlock = (descriptor.template = createBlock(node, source, false));
|
|
186
|
-
templateBlock.ast = node;
|
|
187
|
-
// warn against 2.x <template functional>
|
|
188
|
-
if (templateBlock.attrs.functional) {
|
|
189
|
-
const err = new SyntaxError(`<template functional> is no longer supported in Vue 3, since ` +
|
|
190
|
-
`functional components no longer have significant performance ` +
|
|
191
|
-
`difference from stateful ones. Just use a normal <template> ` +
|
|
192
|
-
`instead.`);
|
|
193
|
-
err.loc = node.props.find(p => p.name === 'functional').loc;
|
|
194
|
-
errors.push(err);
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
else {
|
|
198
|
-
errors.push(createDuplicateBlockError(node));
|
|
199
|
-
}
|
|
200
|
-
break;
|
|
201
|
-
case 'script':
|
|
202
|
-
const scriptBlock = createBlock(node, source, pad);
|
|
203
|
-
const isSetup = !!scriptBlock.attrs.setup;
|
|
204
|
-
if (isSetup && !descriptor.scriptSetup) {
|
|
205
|
-
descriptor.scriptSetup = scriptBlock;
|
|
206
|
-
break;
|
|
207
|
-
}
|
|
208
|
-
if (!isSetup && !descriptor.script) {
|
|
209
|
-
descriptor.script = scriptBlock;
|
|
210
|
-
break;
|
|
211
|
-
}
|
|
212
|
-
errors.push(createDuplicateBlockError(node, isSetup));
|
|
213
|
-
break;
|
|
214
|
-
case 'style':
|
|
215
|
-
const styleBlock = createBlock(node, source, pad);
|
|
216
|
-
if (styleBlock.attrs.vars) {
|
|
217
|
-
errors.push(new SyntaxError(`<style vars> has been replaced by a new proposal: ` +
|
|
218
|
-
`https://github.com/vuejs/rfcs/pull/231`));
|
|
219
|
-
}
|
|
220
|
-
descriptor.styles.push(styleBlock);
|
|
221
|
-
break;
|
|
222
|
-
default:
|
|
223
|
-
descriptor.customBlocks.push(createBlock(node, source, pad));
|
|
224
|
-
break;
|
|
225
|
-
}
|
|
226
|
-
});
|
|
227
|
-
if (descriptor.scriptSetup) {
|
|
228
|
-
if (descriptor.scriptSetup.src) {
|
|
229
|
-
errors.push(new SyntaxError(`<script setup> cannot use the "src" attribute because ` +
|
|
230
|
-
`its syntax will be ambiguous outside of the component.`));
|
|
231
|
-
descriptor.scriptSetup = null;
|
|
232
|
-
}
|
|
233
|
-
if (descriptor.script && descriptor.script.src) {
|
|
234
|
-
errors.push(new SyntaxError(`<script> cannot use the "src" attribute when <script setup> is ` +
|
|
235
|
-
`also present because they must be processed together.`));
|
|
236
|
-
descriptor.script = null;
|
|
237
|
-
}
|
|
238
|
-
}
|
|
239
|
-
if (sourceMap) {
|
|
240
|
-
const genMap = (block) => {
|
|
241
|
-
if (block && !block.src) {
|
|
242
|
-
block.map = generateSourceMap(filename, source, block.content, sourceRoot, !pad || block.type === 'template' ? block.loc.start.line - 1 : 0);
|
|
243
|
-
}
|
|
244
|
-
};
|
|
245
|
-
genMap(descriptor.template);
|
|
246
|
-
genMap(descriptor.script);
|
|
247
|
-
descriptor.styles.forEach(genMap);
|
|
248
|
-
descriptor.customBlocks.forEach(genMap);
|
|
249
|
-
}
|
|
250
|
-
// parse CSS vars
|
|
251
|
-
descriptor.cssVars = parseCssVars(descriptor);
|
|
252
|
-
// check if the SFC uses :slotted
|
|
253
|
-
const slottedRE = /(?:::v-|:)slotted\(/;
|
|
254
|
-
descriptor.slotted = descriptor.styles.some(s => s.scoped && slottedRE.test(s.content));
|
|
255
|
-
jsvCssToJs.ensureSfcDescriptor(descriptor); // QCode Added
|
|
256
|
-
const result = {
|
|
257
|
-
descriptor,
|
|
258
|
-
errors
|
|
259
|
-
};
|
|
260
|
-
sourceToSFC.set(sourceKey, result);
|
|
261
|
-
return result;
|
|
262
|
-
}
|
|
263
|
-
function createDuplicateBlockError(node, isScriptSetup = false) {
|
|
264
|
-
const err = new SyntaxError(`Single file component can contain only one <${node.tag}${isScriptSetup ? ` setup` : ``}> element`);
|
|
265
|
-
err.loc = node.loc;
|
|
266
|
-
return err;
|
|
267
|
-
}
|
|
268
|
-
function createBlock(node, source, pad) {
|
|
269
|
-
const type = node.tag;
|
|
270
|
-
let { start, end } = node.loc;
|
|
271
|
-
let content = '';
|
|
272
|
-
if (node.children.length) {
|
|
273
|
-
start = node.children[0].loc.start;
|
|
274
|
-
end = node.children[node.children.length - 1].loc.end;
|
|
275
|
-
content = source.slice(start.offset, end.offset);
|
|
276
|
-
}
|
|
277
|
-
else {
|
|
278
|
-
const offset = node.loc.source.indexOf(`</`);
|
|
279
|
-
if (offset > -1) {
|
|
280
|
-
start = {
|
|
281
|
-
line: start.line,
|
|
282
|
-
column: start.column + offset,
|
|
283
|
-
offset: start.offset + offset
|
|
284
|
-
};
|
|
285
|
-
}
|
|
286
|
-
end = Object.assign({}, start);
|
|
287
|
-
}
|
|
288
|
-
const loc = {
|
|
289
|
-
source: content,
|
|
290
|
-
start,
|
|
291
|
-
end
|
|
292
|
-
};
|
|
293
|
-
const attrs = {};
|
|
294
|
-
const block = {
|
|
295
|
-
type,
|
|
296
|
-
content,
|
|
297
|
-
loc,
|
|
298
|
-
attrs
|
|
299
|
-
};
|
|
300
|
-
if (pad) {
|
|
301
|
-
block.content = padContent(source, block, pad) + block.content;
|
|
302
|
-
}
|
|
303
|
-
node.props.forEach(p => {
|
|
304
|
-
if (p.type === 6 /* ATTRIBUTE */) {
|
|
305
|
-
attrs[p.name] = p.value ? p.value.content || true : true;
|
|
306
|
-
if (p.name === 'lang') {
|
|
307
|
-
block.lang = p.value && p.value.content;
|
|
308
|
-
}
|
|
309
|
-
else if (p.name === 'src') {
|
|
310
|
-
block.src = p.value && p.value.content;
|
|
311
|
-
}
|
|
312
|
-
else if (type === 'style') {
|
|
313
|
-
if (p.name === 'scoped') {
|
|
314
|
-
block.scoped = true;
|
|
315
|
-
}
|
|
316
|
-
else if (p.name === 'module') {
|
|
317
|
-
block.module = attrs[p.name];
|
|
318
|
-
}
|
|
319
|
-
}
|
|
320
|
-
else if (type === 'script' && p.name === 'setup') {
|
|
321
|
-
block.setup = attrs.setup;
|
|
322
|
-
}
|
|
323
|
-
}
|
|
324
|
-
});
|
|
325
|
-
return block;
|
|
326
|
-
}
|
|
327
|
-
const splitRE = /\r?\n/g;
|
|
328
|
-
const emptyRE = /^(?:\/\/)?\s*$/;
|
|
329
|
-
const replaceRE = /./g;
|
|
330
|
-
function generateSourceMap(filename, source, generated, sourceRoot, lineOffset) {
|
|
331
|
-
const map = new sourceMap.SourceMapGenerator({
|
|
332
|
-
file: filename.replace(/\\/g, '/'),
|
|
333
|
-
sourceRoot: sourceRoot.replace(/\\/g, '/')
|
|
334
|
-
});
|
|
335
|
-
map.setSourceContent(filename, source);
|
|
336
|
-
generated.split(splitRE).forEach((line, index) => {
|
|
337
|
-
if (!emptyRE.test(line)) {
|
|
338
|
-
const originalLine = index + 1 + lineOffset;
|
|
339
|
-
const generatedLine = index + 1;
|
|
340
|
-
for (let i = 0; i < line.length; i++) {
|
|
341
|
-
if (!/\s/.test(line[i])) {
|
|
342
|
-
map.addMapping({
|
|
343
|
-
source: filename,
|
|
344
|
-
original: {
|
|
345
|
-
line: originalLine,
|
|
346
|
-
column: i
|
|
347
|
-
},
|
|
348
|
-
generated: {
|
|
349
|
-
line: generatedLine,
|
|
350
|
-
column: i
|
|
351
|
-
}
|
|
352
|
-
});
|
|
353
|
-
}
|
|
354
|
-
}
|
|
355
|
-
}
|
|
356
|
-
});
|
|
357
|
-
return JSON.parse(map.toString());
|
|
358
|
-
}
|
|
359
|
-
function padContent(content, block, pad) {
|
|
360
|
-
content = content.slice(0, block.loc.start.offset);
|
|
361
|
-
if (pad === 'space') {
|
|
362
|
-
return content.replace(replaceRE, ' ');
|
|
363
|
-
}
|
|
364
|
-
else {
|
|
365
|
-
const offset = content.split(splitRE).length;
|
|
366
|
-
const padChar = block.type === 'script' && !block.lang ? '//\n' : '\n';
|
|
367
|
-
return Array(offset).join(padChar);
|
|
368
|
-
}
|
|
369
|
-
}
|
|
370
|
-
function hasSrc(node) {
|
|
371
|
-
return node.props.some(p => {
|
|
372
|
-
if (p.type !== 6 /* ATTRIBUTE */) {
|
|
373
|
-
return false;
|
|
374
|
-
}
|
|
375
|
-
return p.name === 'src';
|
|
376
|
-
});
|
|
377
|
-
}
|
|
378
|
-
/**
|
|
379
|
-
* Returns true if the node has no children
|
|
380
|
-
* once the empty text nodes (trimmed content) have been filtered out.
|
|
381
|
-
*/
|
|
382
|
-
function isEmpty(node) {
|
|
383
|
-
return (node.children.filter(child => child.type !== 2 /* TEXT */ || child.content.trim() !== '').length === 0);
|
|
384
|
-
}
|
|
385
|
-
|
|
386
|
-
function isRelativeUrl(url) {
|
|
387
|
-
const firstChar = url.charAt(0);
|
|
388
|
-
return firstChar === '.' || firstChar === '~' || firstChar === '@';
|
|
389
|
-
}
|
|
390
|
-
const externalRE = /^https?:\/\//;
|
|
391
|
-
function isExternalUrl(url) {
|
|
392
|
-
return externalRE.test(url);
|
|
393
|
-
}
|
|
394
|
-
const dataUrlRE = /^\s*data:/i;
|
|
395
|
-
function isDataUrl(url) {
|
|
396
|
-
return dataUrlRE.test(url);
|
|
397
|
-
}
|
|
398
|
-
/**
|
|
399
|
-
* Parses string url into URL object.
|
|
400
|
-
*/
|
|
401
|
-
function parseUrl(url) {
|
|
402
|
-
const firstChar = url.charAt(0);
|
|
403
|
-
if (firstChar === '~') {
|
|
404
|
-
const secondChar = url.charAt(1);
|
|
405
|
-
url = url.slice(secondChar === '/' ? 2 : 1);
|
|
406
|
-
}
|
|
407
|
-
return parseUriParts(url);
|
|
408
|
-
}
|
|
409
|
-
/**
|
|
410
|
-
* vuejs/component-compiler-utils#22 Support uri fragment in transformed require
|
|
411
|
-
* @param urlString an url as a string
|
|
412
|
-
*/
|
|
413
|
-
function parseUriParts(urlString) {
|
|
414
|
-
// A TypeError is thrown if urlString is not a string
|
|
415
|
-
// @see https://nodejs.org/api/url.html#url_url_parse_urlstring_parsequerystring_slashesdenotehost
|
|
416
|
-
return url.parse(shared.isString(urlString) ? urlString : '', false, true);
|
|
417
|
-
}
|
|
418
|
-
|
|
419
|
-
const defaultAssetUrlOptions = {
|
|
420
|
-
base: null,
|
|
421
|
-
includeAbsolute: false,
|
|
422
|
-
tags: {
|
|
423
|
-
video: ['src', 'poster'],
|
|
424
|
-
source: ['src'],
|
|
425
|
-
img: ['src'],
|
|
426
|
-
image: ['xlink:href', 'href'],
|
|
427
|
-
use: ['xlink:href', 'href']
|
|
428
|
-
}
|
|
429
|
-
};
|
|
430
|
-
const normalizeOptions = (options) => {
|
|
431
|
-
if (Object.keys(options).some(key => shared.isArray(options[key]))) {
|
|
432
|
-
// legacy option format which directly passes in tags config
|
|
433
|
-
return Object.assign(Object.assign({}, defaultAssetUrlOptions), { tags: options });
|
|
434
|
-
}
|
|
435
|
-
return Object.assign(Object.assign({}, defaultAssetUrlOptions), options);
|
|
436
|
-
};
|
|
437
|
-
const createAssetUrlTransformWithOptions = (options) => {
|
|
438
|
-
return (node, context) => transformAssetUrl(node, context, options);
|
|
439
|
-
};
|
|
440
|
-
/**
|
|
441
|
-
* A `@vue/compiler-core` plugin that transforms relative asset urls into
|
|
442
|
-
* either imports or absolute urls.
|
|
443
|
-
*
|
|
444
|
-
* ``` js
|
|
445
|
-
* // Before
|
|
446
|
-
* createVNode('img', { src: './logo.png' })
|
|
447
|
-
*
|
|
448
|
-
* // After
|
|
449
|
-
* import _imports_0 from './logo.png'
|
|
450
|
-
* createVNode('img', { src: _imports_0 })
|
|
451
|
-
* ```
|
|
452
|
-
*/
|
|
453
|
-
const transformAssetUrl = (node, context, options = defaultAssetUrlOptions) => {
|
|
454
|
-
if (node.type === 1 /* ELEMENT */) {
|
|
455
|
-
if (!node.props.length) {
|
|
456
|
-
return;
|
|
457
|
-
}
|
|
458
|
-
const tags = options.tags || defaultAssetUrlOptions.tags;
|
|
459
|
-
const attrs = tags[node.tag];
|
|
460
|
-
const wildCardAttrs = tags['*'];
|
|
461
|
-
if (!attrs && !wildCardAttrs) {
|
|
462
|
-
return;
|
|
463
|
-
}
|
|
464
|
-
const assetAttrs = (attrs || []).concat(wildCardAttrs || []);
|
|
465
|
-
node.props.forEach((attr, index) => {
|
|
466
|
-
if (attr.type !== 6 /* ATTRIBUTE */ ||
|
|
467
|
-
!assetAttrs.includes(attr.name) ||
|
|
468
|
-
!attr.value ||
|
|
469
|
-
isExternalUrl(attr.value.content) ||
|
|
470
|
-
isDataUrl(attr.value.content) ||
|
|
471
|
-
attr.value.content[0] === '#' ||
|
|
472
|
-
(!options.includeAbsolute && !isRelativeUrl(attr.value.content))) {
|
|
473
|
-
return;
|
|
474
|
-
}
|
|
475
|
-
const url = parseUrl(attr.value.content);
|
|
476
|
-
if (options.base && attr.value.content[0] === '.') {
|
|
477
|
-
// explicit base - directly rewrite relative urls into absolute url
|
|
478
|
-
// to avoid generating extra imports
|
|
479
|
-
// Allow for full hostnames provided in options.base
|
|
480
|
-
const base = parseUrl(options.base);
|
|
481
|
-
const protocol = base.protocol || '';
|
|
482
|
-
const host = base.host ? protocol + '//' + base.host : '';
|
|
483
|
-
const basePath = base.path || '/';
|
|
484
|
-
// when packaged in the browser, path will be using the posix-
|
|
485
|
-
// only version provided by rollup-plugin-node-builtins.
|
|
486
|
-
attr.value.content =
|
|
487
|
-
host +
|
|
488
|
-
(path__default.posix || path__default).join(basePath, url.path + (url.hash || ''));
|
|
489
|
-
return;
|
|
490
|
-
}
|
|
491
|
-
// otherwise, transform the url into an import.
|
|
492
|
-
// this assumes a bundler will resolve the import into the correct
|
|
493
|
-
// absolute url (e.g. webpack file-loader)
|
|
494
|
-
const exp = getImportsExpressionExp(url.path, url.hash, attr.loc, context);
|
|
495
|
-
node.props[index] = {
|
|
496
|
-
type: 7 /* DIRECTIVE */,
|
|
497
|
-
name: 'bind',
|
|
498
|
-
arg: compilerCore.createSimpleExpression(attr.name, true, attr.loc),
|
|
499
|
-
exp,
|
|
500
|
-
modifiers: [],
|
|
501
|
-
loc: attr.loc
|
|
502
|
-
};
|
|
503
|
-
});
|
|
504
|
-
}
|
|
505
|
-
};
|
|
506
|
-
function getImportsExpressionExp(path, hash, loc, context) {
|
|
507
|
-
if (path) {
|
|
508
|
-
const existing = context.imports.find(i => i.path === path);
|
|
509
|
-
if (existing) {
|
|
510
|
-
return existing.exp;
|
|
511
|
-
}
|
|
512
|
-
const name = `_imports_${context.imports.length}`;
|
|
513
|
-
const exp = compilerCore.createSimpleExpression(name, false, loc, 2 /* CAN_HOIST */);
|
|
514
|
-
context.imports.push({ exp, path });
|
|
515
|
-
if (hash && path) {
|
|
516
|
-
return context.hoist(compilerCore.createSimpleExpression(`${name} + '${hash}'`, false, loc, 2 /* CAN_HOIST */));
|
|
517
|
-
}
|
|
518
|
-
else {
|
|
519
|
-
return exp;
|
|
520
|
-
}
|
|
521
|
-
}
|
|
522
|
-
else {
|
|
523
|
-
return compilerCore.createSimpleExpression(`''`, false, loc, 2 /* CAN_HOIST */);
|
|
524
|
-
}
|
|
525
|
-
}
|
|
526
|
-
|
|
527
|
-
const srcsetTags = ['img', 'source'];
|
|
528
|
-
// http://w3c.github.io/html/semantics-embedded-content.html#ref-for-image-candidate-string-5
|
|
529
|
-
const escapedSpaceCharacters = /( |\\t|\\n|\\f|\\r)+/g;
|
|
530
|
-
const createSrcsetTransformWithOptions = (options) => {
|
|
531
|
-
return (node, context) => transformSrcset(node, context, options);
|
|
532
|
-
};
|
|
533
|
-
const transformSrcset = (node, context, options = defaultAssetUrlOptions) => {
|
|
534
|
-
if (node.type === 1 /* ELEMENT */) {
|
|
535
|
-
if (srcsetTags.includes(node.tag) && node.props.length) {
|
|
536
|
-
node.props.forEach((attr, index) => {
|
|
537
|
-
if (attr.name === 'srcset' && attr.type === 6 /* ATTRIBUTE */) {
|
|
538
|
-
if (!attr.value)
|
|
539
|
-
return;
|
|
540
|
-
const value = attr.value.content;
|
|
541
|
-
if (!value)
|
|
542
|
-
return;
|
|
543
|
-
const imageCandidates = value.split(',').map(s => {
|
|
544
|
-
// The attribute value arrives here with all whitespace, except
|
|
545
|
-
// normal spaces, represented by escape sequences
|
|
546
|
-
const [url, descriptor] = s
|
|
547
|
-
.replace(escapedSpaceCharacters, ' ')
|
|
548
|
-
.trim()
|
|
549
|
-
.split(' ', 2);
|
|
550
|
-
return { url, descriptor };
|
|
551
|
-
});
|
|
552
|
-
// data urls contains comma after the ecoding so we need to re-merge
|
|
553
|
-
// them
|
|
554
|
-
for (let i = 0; i < imageCandidates.length; i++) {
|
|
555
|
-
const { url } = imageCandidates[i];
|
|
556
|
-
if (isDataUrl(url)) {
|
|
557
|
-
imageCandidates[i + 1].url =
|
|
558
|
-
url + ',' + imageCandidates[i + 1].url;
|
|
559
|
-
imageCandidates.splice(i, 1);
|
|
560
|
-
}
|
|
561
|
-
}
|
|
562
|
-
const hasQualifiedUrl = imageCandidates.some(({ url }) => {
|
|
563
|
-
return (!isExternalUrl(url) &&
|
|
564
|
-
!isDataUrl(url) &&
|
|
565
|
-
(options.includeAbsolute || isRelativeUrl(url)));
|
|
566
|
-
});
|
|
567
|
-
// When srcset does not contain any qualified URLs, skip transforming
|
|
568
|
-
if (!hasQualifiedUrl) {
|
|
569
|
-
return;
|
|
570
|
-
}
|
|
571
|
-
if (options.base) {
|
|
572
|
-
const base = options.base;
|
|
573
|
-
const set = [];
|
|
574
|
-
imageCandidates.forEach(({ url, descriptor }) => {
|
|
575
|
-
descriptor = descriptor ? ` ${descriptor}` : ``;
|
|
576
|
-
if (isRelativeUrl(url)) {
|
|
577
|
-
set.push((path__default.posix || path__default).join(base, url) + descriptor);
|
|
578
|
-
}
|
|
579
|
-
else {
|
|
580
|
-
set.push(url + descriptor);
|
|
581
|
-
}
|
|
582
|
-
});
|
|
583
|
-
attr.value.content = set.join(', ');
|
|
584
|
-
return;
|
|
585
|
-
}
|
|
586
|
-
const compoundExpression = compilerCore.createCompoundExpression([], attr.loc);
|
|
587
|
-
imageCandidates.forEach(({ url, descriptor }, index) => {
|
|
588
|
-
if (!isExternalUrl(url) &&
|
|
589
|
-
!isDataUrl(url) &&
|
|
590
|
-
(options.includeAbsolute || isRelativeUrl(url))) {
|
|
591
|
-
const { path } = parseUrl(url);
|
|
592
|
-
let exp;
|
|
593
|
-
if (path) {
|
|
594
|
-
const existingImportsIndex = context.imports.findIndex(i => i.path === path);
|
|
595
|
-
if (existingImportsIndex > -1) {
|
|
596
|
-
exp = compilerCore.createSimpleExpression(`_imports_${existingImportsIndex}`, false, attr.loc, 2 /* CAN_HOIST */);
|
|
597
|
-
}
|
|
598
|
-
else {
|
|
599
|
-
exp = compilerCore.createSimpleExpression(`_imports_${context.imports.length}`, false, attr.loc, 2 /* CAN_HOIST */);
|
|
600
|
-
context.imports.push({ exp, path });
|
|
601
|
-
}
|
|
602
|
-
compoundExpression.children.push(exp);
|
|
603
|
-
}
|
|
604
|
-
}
|
|
605
|
-
else {
|
|
606
|
-
const exp = compilerCore.createSimpleExpression(`"${url}"`, false, attr.loc, 2 /* CAN_HOIST */);
|
|
607
|
-
compoundExpression.children.push(exp);
|
|
608
|
-
}
|
|
609
|
-
const isNotLast = imageCandidates.length - 1 > index;
|
|
610
|
-
if (descriptor && isNotLast) {
|
|
611
|
-
compoundExpression.children.push(` + ' ${descriptor}, ' + `);
|
|
612
|
-
}
|
|
613
|
-
else if (descriptor) {
|
|
614
|
-
compoundExpression.children.push(` + ' ${descriptor}'`);
|
|
615
|
-
}
|
|
616
|
-
else if (isNotLast) {
|
|
617
|
-
compoundExpression.children.push(` + ', ' + `);
|
|
618
|
-
}
|
|
619
|
-
});
|
|
620
|
-
const hoisted = context.hoist(compoundExpression);
|
|
621
|
-
hoisted.constType = 2 /* CAN_HOIST */;
|
|
622
|
-
node.props[index] = {
|
|
623
|
-
type: 7 /* DIRECTIVE */,
|
|
624
|
-
name: 'bind',
|
|
625
|
-
arg: compilerCore.createSimpleExpression('srcset', true, attr.loc),
|
|
626
|
-
exp: hoisted,
|
|
627
|
-
modifiers: [],
|
|
628
|
-
loc: attr.loc
|
|
629
|
-
};
|
|
630
|
-
}
|
|
631
|
-
});
|
|
632
|
-
}
|
|
633
|
-
}
|
|
634
|
-
};
|
|
635
|
-
|
|
636
|
-
const hasWarned = {};
|
|
637
|
-
function warnOnce(msg) {
|
|
638
|
-
const isNodeProd = typeof process !== 'undefined' && process.env.NODE_ENV === 'production';
|
|
639
|
-
if (!isNodeProd && !false && !hasWarned[msg]) {
|
|
640
|
-
hasWarned[msg] = true;
|
|
641
|
-
warn(msg);
|
|
642
|
-
}
|
|
643
|
-
}
|
|
644
|
-
function warn(msg) {
|
|
645
|
-
console.warn(`\x1b[1m\x1b[33m[@vue/compiler-sfc]\x1b[0m\x1b[33m ${msg}\x1b[0m\n`);
|
|
646
|
-
}
|
|
647
|
-
|
|
648
|
-
function preprocess({ source, filename, preprocessOptions }, preprocessor) {
|
|
649
|
-
// Consolidate exposes a callback based API, but the callback is in fact
|
|
650
|
-
// called synchronously for most templating engines. In our case, we have to
|
|
651
|
-
// expose a synchronous API so that it is usable in Jest transforms (which
|
|
652
|
-
// have to be sync because they are applied via Node.js require hooks)
|
|
653
|
-
let res = '';
|
|
654
|
-
let err = null;
|
|
655
|
-
preprocessor.render(source, Object.assign({ filename }, preprocessOptions), (_err, _res) => {
|
|
656
|
-
if (_err)
|
|
657
|
-
err = _err;
|
|
658
|
-
res = _res;
|
|
659
|
-
});
|
|
660
|
-
if (err)
|
|
661
|
-
throw err;
|
|
662
|
-
return res;
|
|
663
|
-
}
|
|
664
|
-
function compileTemplate(options) {
|
|
665
|
-
const { preprocessLang, preprocessCustomRequire } = options;
|
|
666
|
-
const preprocessor = preprocessLang
|
|
667
|
-
? preprocessCustomRequire
|
|
668
|
-
? preprocessCustomRequire(preprocessLang)
|
|
669
|
-
: require('consolidate')[preprocessLang]
|
|
670
|
-
: false;
|
|
671
|
-
if (preprocessor) {
|
|
672
|
-
try {
|
|
673
|
-
return doCompileTemplate(Object.assign(Object.assign({}, options), { source: preprocess(options, preprocessor) }));
|
|
674
|
-
}
|
|
675
|
-
catch (e) {
|
|
676
|
-
return {
|
|
677
|
-
code: `export default function render() {}`,
|
|
678
|
-
source: options.source,
|
|
679
|
-
tips: [],
|
|
680
|
-
errors: [e]
|
|
681
|
-
};
|
|
682
|
-
}
|
|
683
|
-
}
|
|
684
|
-
else if (preprocessLang) {
|
|
685
|
-
return {
|
|
686
|
-
code: `export default function render() {}`,
|
|
687
|
-
source: options.source,
|
|
688
|
-
tips: [
|
|
689
|
-
`Component ${options.filename} uses lang ${preprocessLang} for template. Please install the language preprocessor.`
|
|
690
|
-
],
|
|
691
|
-
errors: [
|
|
692
|
-
`Component ${options.filename} uses lang ${preprocessLang} for template, however it is not installed.`
|
|
693
|
-
]
|
|
694
|
-
};
|
|
695
|
-
}
|
|
696
|
-
else {
|
|
697
|
-
return doCompileTemplate(options);
|
|
698
|
-
}
|
|
699
|
-
}
|
|
700
|
-
function doCompileTemplate({ filename, id, scoped, slotted, inMap, source, ssr = false, ssrCssVars, isProd = false, compiler = ssr ? CompilerSSR__namespace : CompilerDOM__namespace, compilerOptions = {}, transformAssetUrls }) {
|
|
701
|
-
const errors = [];
|
|
702
|
-
const warnings = [];
|
|
703
|
-
let nodeTransforms = [];
|
|
704
|
-
if (shared.isObject(transformAssetUrls)) {
|
|
705
|
-
const assetOptions = normalizeOptions(transformAssetUrls);
|
|
706
|
-
nodeTransforms = [
|
|
707
|
-
createAssetUrlTransformWithOptions(assetOptions),
|
|
708
|
-
createSrcsetTransformWithOptions(assetOptions)
|
|
709
|
-
];
|
|
710
|
-
}
|
|
711
|
-
else if (transformAssetUrls !== false) {
|
|
712
|
-
nodeTransforms = [transformAssetUrl, transformSrcset];
|
|
713
|
-
}
|
|
714
|
-
if (ssr && !ssrCssVars) {
|
|
715
|
-
warnOnce(`compileTemplate is called with \`ssr: true\` but no ` +
|
|
716
|
-
`corresponding \`cssVars\` option.\`.`);
|
|
717
|
-
}
|
|
718
|
-
if (!id) {
|
|
719
|
-
warnOnce(`compileTemplate now requires the \`id\` option.\`.`);
|
|
720
|
-
id = '';
|
|
721
|
-
}
|
|
722
|
-
const shortId = id.replace(/^data-v-/, '');
|
|
723
|
-
const longId = `data-v-${shortId}`;
|
|
724
|
-
let { code, ast, preamble, map } = compiler.compile(source, Object.assign(Object.assign({ mode: 'module', prefixIdentifiers: true, hoistStatic: false /* QCode Modified */, cacheHandlers: true, ssrCssVars: ssr && ssrCssVars && ssrCssVars.length
|
|
725
|
-
? genCssVarsFromList(ssrCssVars, shortId, isProd)
|
|
726
|
-
: '', scopeId: scoped ? longId : undefined, slotted }, compilerOptions), { nodeTransforms: nodeTransforms.concat(compilerOptions.nodeTransforms || []), filename, sourceMap: true, onError: e => errors.push(e), onWarn: w => warnings.push(w) }));
|
|
727
|
-
// inMap should be the map produced by ./parse.ts which is a simple line-only
|
|
728
|
-
// mapping. If it is present, we need to adjust the final map and errors to
|
|
729
|
-
// reflect the original line numbers.
|
|
730
|
-
if (inMap) {
|
|
731
|
-
if (map) {
|
|
732
|
-
map = mapLines(inMap, map);
|
|
733
|
-
}
|
|
734
|
-
if (errors.length) {
|
|
735
|
-
patchErrors(errors, source, inMap);
|
|
736
|
-
}
|
|
737
|
-
}
|
|
738
|
-
const tips = warnings.map(w => {
|
|
739
|
-
let msg = w.message;
|
|
740
|
-
if (w.loc) {
|
|
741
|
-
msg += `\n${shared.generateCodeFrame(source, w.loc.start.offset, w.loc.end.offset)}`;
|
|
742
|
-
}
|
|
743
|
-
return msg;
|
|
744
|
-
});
|
|
745
|
-
return { code, ast, preamble, source, errors, tips, map };
|
|
746
|
-
}
|
|
747
|
-
function mapLines(oldMap, newMap) {
|
|
748
|
-
if (!oldMap)
|
|
749
|
-
return newMap;
|
|
750
|
-
if (!newMap)
|
|
751
|
-
return oldMap;
|
|
752
|
-
const oldMapConsumer = new sourceMap.SourceMapConsumer(oldMap);
|
|
753
|
-
const newMapConsumer = new sourceMap.SourceMapConsumer(newMap);
|
|
754
|
-
const mergedMapGenerator = new sourceMap.SourceMapGenerator();
|
|
755
|
-
newMapConsumer.eachMapping(m => {
|
|
756
|
-
if (m.originalLine == null) {
|
|
757
|
-
return;
|
|
758
|
-
}
|
|
759
|
-
const origPosInOldMap = oldMapConsumer.originalPositionFor({
|
|
760
|
-
line: m.originalLine,
|
|
761
|
-
column: m.originalColumn
|
|
762
|
-
});
|
|
763
|
-
if (origPosInOldMap.source == null) {
|
|
764
|
-
return;
|
|
765
|
-
}
|
|
766
|
-
mergedMapGenerator.addMapping({
|
|
767
|
-
generated: {
|
|
768
|
-
line: m.generatedLine,
|
|
769
|
-
column: m.generatedColumn
|
|
770
|
-
},
|
|
771
|
-
original: {
|
|
772
|
-
line: origPosInOldMap.line,
|
|
773
|
-
// use current column, since the oldMap produced by @vue/compiler-sfc
|
|
774
|
-
// does not
|
|
775
|
-
column: m.originalColumn
|
|
776
|
-
},
|
|
777
|
-
source: origPosInOldMap.source,
|
|
778
|
-
name: origPosInOldMap.name
|
|
779
|
-
});
|
|
780
|
-
});
|
|
781
|
-
// source-map's type definition is incomplete
|
|
782
|
-
const generator = mergedMapGenerator;
|
|
783
|
-
oldMapConsumer.sources.forEach((sourceFile) => {
|
|
784
|
-
generator._sources.add(sourceFile);
|
|
785
|
-
const sourceContent = oldMapConsumer.sourceContentFor(sourceFile);
|
|
786
|
-
if (sourceContent != null) {
|
|
787
|
-
mergedMapGenerator.setSourceContent(sourceFile, sourceContent);
|
|
788
|
-
}
|
|
789
|
-
});
|
|
790
|
-
generator._sourceRoot = oldMap.sourceRoot;
|
|
791
|
-
generator._file = oldMap.file;
|
|
792
|
-
return generator.toJSON();
|
|
793
|
-
}
|
|
794
|
-
function patchErrors(errors, source, inMap) {
|
|
795
|
-
const originalSource = inMap.sourcesContent[0];
|
|
796
|
-
const offset = originalSource.indexOf(source);
|
|
797
|
-
const lineOffset = originalSource.slice(0, offset).split(/\r?\n/).length - 1;
|
|
798
|
-
errors.forEach(err => {
|
|
799
|
-
if (err.loc) {
|
|
800
|
-
err.loc.start.line += lineOffset;
|
|
801
|
-
err.loc.start.offset += offset;
|
|
802
|
-
if (err.loc.end !== err.loc.start) {
|
|
803
|
-
err.loc.end.line += lineOffset;
|
|
804
|
-
err.loc.end.offset += offset;
|
|
805
|
-
}
|
|
806
|
-
}
|
|
807
|
-
});
|
|
808
|
-
}
|
|
809
|
-
|
|
810
|
-
const trimPlugin = () => {
|
|
811
|
-
return {
|
|
812
|
-
postcssPlugin: 'vue-sfc-trim',
|
|
813
|
-
Once(root) {
|
|
814
|
-
root.walk(({ type, raws }) => {
|
|
815
|
-
if (type === 'rule' || type === 'atrule') {
|
|
816
|
-
if (raws.before)
|
|
817
|
-
raws.before = '\n';
|
|
818
|
-
if ('after' in raws && raws.after)
|
|
819
|
-
raws.after = '\n';
|
|
820
|
-
}
|
|
821
|
-
});
|
|
822
|
-
}
|
|
823
|
-
};
|
|
824
|
-
};
|
|
825
|
-
trimPlugin.postcss = true;
|
|
826
|
-
|
|
827
|
-
const animationNameRE = /^(-\w+-)?animation-name$/;
|
|
828
|
-
const animationRE = /^(-\w+-)?animation$/;
|
|
829
|
-
const scopedPlugin = (id = '') => {
|
|
830
|
-
const keyframes = Object.create(null);
|
|
831
|
-
const shortId = id.replace(/^data-v-/, '');
|
|
832
|
-
return {
|
|
833
|
-
postcssPlugin: 'vue-sfc-scoped',
|
|
834
|
-
Rule(rule) {
|
|
835
|
-
processRule(id, rule);
|
|
836
|
-
},
|
|
837
|
-
AtRule(node) {
|
|
838
|
-
if (/-?keyframes$/.test(node.name) &&
|
|
839
|
-
!node.params.endsWith(`-${shortId}`)) {
|
|
840
|
-
// register keyframes
|
|
841
|
-
keyframes[node.params] = node.params = node.params + '-' + shortId;
|
|
842
|
-
}
|
|
843
|
-
},
|
|
844
|
-
OnceExit(root) {
|
|
845
|
-
if (Object.keys(keyframes).length) {
|
|
846
|
-
// If keyframes are found in this <style>, find and rewrite animation names
|
|
847
|
-
// in declarations.
|
|
848
|
-
// Caveat: this only works for keyframes and animation rules in the same
|
|
849
|
-
// <style> element.
|
|
850
|
-
// individual animation-name declaration
|
|
851
|
-
root.walkDecls(decl => {
|
|
852
|
-
if (animationNameRE.test(decl.prop)) {
|
|
853
|
-
decl.value = decl.value
|
|
854
|
-
.split(',')
|
|
855
|
-
.map(v => keyframes[v.trim()] || v.trim())
|
|
856
|
-
.join(',');
|
|
857
|
-
}
|
|
858
|
-
// shorthand
|
|
859
|
-
if (animationRE.test(decl.prop)) {
|
|
860
|
-
decl.value = decl.value
|
|
861
|
-
.split(',')
|
|
862
|
-
.map(v => {
|
|
863
|
-
const vals = v.trim().split(/\s+/);
|
|
864
|
-
const i = vals.findIndex(val => keyframes[val]);
|
|
865
|
-
if (i !== -1) {
|
|
866
|
-
vals.splice(i, 1, keyframes[vals[i]]);
|
|
867
|
-
return vals.join(' ');
|
|
868
|
-
}
|
|
869
|
-
else {
|
|
870
|
-
return v;
|
|
871
|
-
}
|
|
872
|
-
})
|
|
873
|
-
.join(',');
|
|
874
|
-
}
|
|
875
|
-
});
|
|
876
|
-
}
|
|
877
|
-
}
|
|
878
|
-
};
|
|
879
|
-
};
|
|
880
|
-
const processedRules = new WeakSet();
|
|
881
|
-
function processRule(id, rule) {
|
|
882
|
-
if (processedRules.has(rule) ||
|
|
883
|
-
(rule.parent &&
|
|
884
|
-
rule.parent.type === 'atrule' &&
|
|
885
|
-
/-?keyframes$/.test(rule.parent.name))) {
|
|
886
|
-
return;
|
|
887
|
-
}
|
|
888
|
-
processedRules.add(rule);
|
|
889
|
-
rule.selector = selectorParser__default(selectorRoot => {
|
|
890
|
-
selectorRoot.each(selector => {
|
|
891
|
-
rewriteSelector(id, selector, selectorRoot);
|
|
892
|
-
});
|
|
893
|
-
}).processSync(rule.selector);
|
|
894
|
-
}
|
|
895
|
-
function rewriteSelector(id, selector, selectorRoot, slotted = false) {
|
|
896
|
-
let node = null;
|
|
897
|
-
let shouldInject = true;
|
|
898
|
-
// find the last child node to insert attribute selector
|
|
899
|
-
selector.each(n => {
|
|
900
|
-
// DEPRECATED ">>>" and "/deep/" combinator
|
|
901
|
-
if (n.type === 'combinator' &&
|
|
902
|
-
(n.value === '>>>' || n.value === '/deep/')) {
|
|
903
|
-
n.value = ' ';
|
|
904
|
-
n.spaces.before = n.spaces.after = '';
|
|
905
|
-
warn(`the >>> and /deep/ combinators have been deprecated. ` +
|
|
906
|
-
`Use :deep() instead.`);
|
|
907
|
-
return false;
|
|
908
|
-
}
|
|
909
|
-
if (n.type === 'pseudo') {
|
|
910
|
-
const { value } = n;
|
|
911
|
-
// deep: inject [id] attribute at the node before the ::v-deep
|
|
912
|
-
// combinator.
|
|
913
|
-
if (value === ':deep' || value === '::v-deep') {
|
|
914
|
-
if (n.nodes.length) {
|
|
915
|
-
// .foo ::v-deep(.bar) -> .foo[xxxxxxx] .bar
|
|
916
|
-
// replace the current node with ::v-deep's inner selector
|
|
917
|
-
let last = n;
|
|
918
|
-
n.nodes[0].each(ss => {
|
|
919
|
-
selector.insertAfter(last, ss);
|
|
920
|
-
last = ss;
|
|
921
|
-
});
|
|
922
|
-
// insert a space combinator before if it doesn't already have one
|
|
923
|
-
const prev = selector.at(selector.index(n) - 1);
|
|
924
|
-
if (!prev || !isSpaceCombinator(prev)) {
|
|
925
|
-
selector.insertAfter(n, selectorParser__default.combinator({
|
|
926
|
-
value: ' '
|
|
927
|
-
}));
|
|
928
|
-
}
|
|
929
|
-
selector.removeChild(n);
|
|
930
|
-
}
|
|
931
|
-
else {
|
|
932
|
-
// DEPRECATED usage
|
|
933
|
-
// .foo ::v-deep .bar -> .foo[xxxxxxx] .bar
|
|
934
|
-
warn(`::v-deep usage as a combinator has ` +
|
|
935
|
-
`been deprecated. Use :deep(<inner-selector>) instead.`);
|
|
936
|
-
const prev = selector.at(selector.index(n) - 1);
|
|
937
|
-
if (prev && isSpaceCombinator(prev)) {
|
|
938
|
-
selector.removeChild(prev);
|
|
939
|
-
}
|
|
940
|
-
selector.removeChild(n);
|
|
941
|
-
}
|
|
942
|
-
return false;
|
|
943
|
-
}
|
|
944
|
-
// slot: use selector inside `::v-slotted` and inject [id + '-s']
|
|
945
|
-
// instead.
|
|
946
|
-
// ::v-slotted(.foo) -> .foo[xxxxxxx-s]
|
|
947
|
-
if (value === ':slotted' || value === '::v-slotted') {
|
|
948
|
-
rewriteSelector(id, n.nodes[0], selectorRoot, true /* slotted */);
|
|
949
|
-
let last = n;
|
|
950
|
-
n.nodes[0].each(ss => {
|
|
951
|
-
selector.insertAfter(last, ss);
|
|
952
|
-
last = ss;
|
|
953
|
-
});
|
|
954
|
-
// selector.insertAfter(n, n.nodes[0])
|
|
955
|
-
selector.removeChild(n);
|
|
956
|
-
// since slotted attribute already scopes the selector there's no
|
|
957
|
-
// need for the non-slot attribute.
|
|
958
|
-
shouldInject = false;
|
|
959
|
-
return false;
|
|
960
|
-
}
|
|
961
|
-
// global: replace with inner selector and do not inject [id].
|
|
962
|
-
// ::v-global(.foo) -> .foo
|
|
963
|
-
if (value === ':global' || value === '::v-global') {
|
|
964
|
-
selectorRoot.insertAfter(selector, n.nodes[0]);
|
|
965
|
-
selectorRoot.removeChild(selector);
|
|
966
|
-
return false;
|
|
967
|
-
}
|
|
968
|
-
}
|
|
969
|
-
if (n.type !== 'pseudo' && n.type !== 'combinator') {
|
|
970
|
-
node = n;
|
|
971
|
-
}
|
|
972
|
-
});
|
|
973
|
-
if (node) {
|
|
974
|
-
node.spaces.after = '';
|
|
975
|
-
}
|
|
976
|
-
else {
|
|
977
|
-
// For deep selectors & standalone pseudo selectors,
|
|
978
|
-
// the attribute selectors are prepended rather than appended.
|
|
979
|
-
// So all leading spaces must be eliminated to avoid problems.
|
|
980
|
-
selector.first.spaces.before = '';
|
|
981
|
-
}
|
|
982
|
-
if (shouldInject) {
|
|
983
|
-
const idToAdd = slotted ? id + '-s' : id;
|
|
984
|
-
selector.insertAfter(
|
|
985
|
-
// If node is null it means we need to inject [id] at the start
|
|
986
|
-
// insertAfter can handle `null` here
|
|
987
|
-
node, selectorParser__default.attribute({
|
|
988
|
-
attribute: idToAdd,
|
|
989
|
-
value: idToAdd,
|
|
990
|
-
raws: {},
|
|
991
|
-
quoteMark: `"`
|
|
992
|
-
}));
|
|
993
|
-
}
|
|
994
|
-
}
|
|
995
|
-
function isSpaceCombinator(node) {
|
|
996
|
-
return node.type === 'combinator' && /^\s+$/.test(node.value);
|
|
997
|
-
}
|
|
998
|
-
scopedPlugin.postcss = true;
|
|
999
|
-
|
|
1000
|
-
// .scss/.sass processor
|
|
1001
|
-
const scss = (source, map, options, load = require) => {
|
|
1002
|
-
const nodeSass = load('sass');
|
|
1003
|
-
const finalOptions = Object.assign(Object.assign({}, options), { data: getSource(source, options.filename, options.additionalData), file: options.filename, outFile: options.filename, sourceMap: !!map });
|
|
1004
|
-
try {
|
|
1005
|
-
const result = nodeSass.renderSync(finalOptions);
|
|
1006
|
-
const dependencies = result.stats.includedFiles;
|
|
1007
|
-
if (map) {
|
|
1008
|
-
return {
|
|
1009
|
-
code: result.css.toString(),
|
|
1010
|
-
map: merge__default(map, JSON.parse(result.map.toString())),
|
|
1011
|
-
errors: [],
|
|
1012
|
-
dependencies
|
|
1013
|
-
};
|
|
1014
|
-
}
|
|
1015
|
-
return { code: result.css.toString(), errors: [], dependencies };
|
|
1016
|
-
}
|
|
1017
|
-
catch (e) {
|
|
1018
|
-
return { code: '', errors: [e], dependencies: [] };
|
|
1019
|
-
}
|
|
1020
|
-
};
|
|
1021
|
-
const sass = (source, map, options, load) => scss(source, map, Object.assign(Object.assign({}, options), { indentedSyntax: true }), load);
|
|
1022
|
-
// .less
|
|
1023
|
-
const less = (source, map, options, load = require) => {
|
|
1024
|
-
const nodeLess = load('less');
|
|
1025
|
-
let result;
|
|
1026
|
-
let error = null;
|
|
1027
|
-
nodeLess.render(getSource(source, options.filename, options.additionalData), Object.assign(Object.assign({}, options), { syncImport: true }), (err, output) => {
|
|
1028
|
-
error = err;
|
|
1029
|
-
result = output;
|
|
1030
|
-
});
|
|
1031
|
-
if (error)
|
|
1032
|
-
return { code: '', errors: [error], dependencies: [] };
|
|
1033
|
-
const dependencies = result.imports;
|
|
1034
|
-
if (map) {
|
|
1035
|
-
return {
|
|
1036
|
-
code: result.css.toString(),
|
|
1037
|
-
map: merge__default(map, result.map),
|
|
1038
|
-
errors: [],
|
|
1039
|
-
dependencies: dependencies
|
|
1040
|
-
};
|
|
1041
|
-
}
|
|
1042
|
-
return {
|
|
1043
|
-
code: result.css.toString(),
|
|
1044
|
-
errors: [],
|
|
1045
|
-
dependencies: dependencies
|
|
1046
|
-
};
|
|
1047
|
-
};
|
|
1048
|
-
// .styl
|
|
1049
|
-
const styl = (source, map, options, load = require) => {
|
|
1050
|
-
const nodeStylus = load('stylus');
|
|
1051
|
-
try {
|
|
1052
|
-
const ref = nodeStylus(source);
|
|
1053
|
-
Object.keys(options).forEach(key => ref.set(key, options[key]));
|
|
1054
|
-
if (map)
|
|
1055
|
-
ref.set('sourcemap', { inline: false, comment: false });
|
|
1056
|
-
const result = ref.render();
|
|
1057
|
-
const dependencies = ref.deps();
|
|
1058
|
-
if (map) {
|
|
1059
|
-
return {
|
|
1060
|
-
code: result,
|
|
1061
|
-
map: merge__default(map, ref.sourcemap),
|
|
1062
|
-
errors: [],
|
|
1063
|
-
dependencies
|
|
1064
|
-
};
|
|
1065
|
-
}
|
|
1066
|
-
return { code: result, errors: [], dependencies };
|
|
1067
|
-
}
|
|
1068
|
-
catch (e) {
|
|
1069
|
-
return { code: '', errors: [e], dependencies: [] };
|
|
1070
|
-
}
|
|
1071
|
-
};
|
|
1072
|
-
function getSource(source, filename, additionalData) {
|
|
1073
|
-
if (!additionalData)
|
|
1074
|
-
return source;
|
|
1075
|
-
if (shared.isFunction(additionalData)) {
|
|
1076
|
-
return additionalData(source, filename);
|
|
1077
|
-
}
|
|
1078
|
-
return additionalData + source;
|
|
1079
|
-
}
|
|
1080
|
-
const processors = {
|
|
1081
|
-
less,
|
|
1082
|
-
sass,
|
|
1083
|
-
scss,
|
|
1084
|
-
styl,
|
|
1085
|
-
stylus: styl
|
|
1086
|
-
};
|
|
1087
|
-
|
|
1088
|
-
function compileStyle(options) {
|
|
1089
|
-
return doCompileStyle(Object.assign(Object.assign({}, options), { isAsync: false }));
|
|
1090
|
-
}
|
|
1091
|
-
function compileStyleAsync(options) {
|
|
1092
|
-
return doCompileStyle(Object.assign(Object.assign({}, options), { isAsync: true }));
|
|
1093
|
-
}
|
|
1094
|
-
function doCompileStyle(options) {
|
|
1095
|
-
const { filename, id, scoped = false, trim = true, isProd = false, modules = false, modulesOptions = {}, preprocessLang, postcssOptions, postcssPlugins } = options;
|
|
1096
|
-
const preprocessor = preprocessLang && processors[preprocessLang];
|
|
1097
|
-
const preProcessedSource = preprocessor && preprocess$1(options, preprocessor);
|
|
1098
|
-
const map = preProcessedSource
|
|
1099
|
-
? preProcessedSource.map
|
|
1100
|
-
: options.inMap || options.map;
|
|
1101
|
-
const source = preProcessedSource ? preProcessedSource.code : options.source;
|
|
1102
|
-
const shortId = id.replace(/^data-v-/, '');
|
|
1103
|
-
const longId = `data-v-${shortId}`;
|
|
1104
|
-
const plugins = (postcssPlugins || []).slice();
|
|
1105
|
-
plugins.unshift(cssVarsPlugin({ id: shortId, isProd }));
|
|
1106
|
-
if (trim) {
|
|
1107
|
-
plugins.push(trimPlugin());
|
|
1108
|
-
}
|
|
1109
|
-
if (scoped) {
|
|
1110
|
-
plugins.push(scopedPlugin(longId));
|
|
1111
|
-
}
|
|
1112
|
-
let cssModules;
|
|
1113
|
-
if (modules) {
|
|
1114
|
-
if (!options.isAsync) {
|
|
1115
|
-
throw new Error('[@vue/compiler-sfc] `modules` option can only be used with compileStyleAsync().');
|
|
1116
|
-
}
|
|
1117
|
-
plugins.push(require('postcss-modules')(Object.assign(Object.assign({}, modulesOptions), { getJSON: (_cssFileName, json) => {
|
|
1118
|
-
cssModules = json;
|
|
1119
|
-
} })));
|
|
1120
|
-
}
|
|
1121
|
-
const postCSSOptions = Object.assign(Object.assign({}, postcssOptions), { to: filename, from: filename });
|
|
1122
|
-
if (map) {
|
|
1123
|
-
postCSSOptions.map = {
|
|
1124
|
-
inline: false,
|
|
1125
|
-
annotation: false,
|
|
1126
|
-
prev: map
|
|
1127
|
-
};
|
|
1128
|
-
}
|
|
1129
|
-
let result;
|
|
1130
|
-
let code;
|
|
1131
|
-
let outMap;
|
|
1132
|
-
// stylus output include plain css. so need remove the repeat item
|
|
1133
|
-
const dependencies = new Set(preProcessedSource ? preProcessedSource.dependencies : []);
|
|
1134
|
-
// sass has filename self when provided filename option
|
|
1135
|
-
dependencies.delete(filename);
|
|
1136
|
-
const errors = [];
|
|
1137
|
-
if (preProcessedSource && preProcessedSource.errors.length) {
|
|
1138
|
-
errors.push(...preProcessedSource.errors);
|
|
1139
|
-
}
|
|
1140
|
-
const recordPlainCssDependencies = (messages) => {
|
|
1141
|
-
messages.forEach(msg => {
|
|
1142
|
-
if (msg.type === 'dependency') {
|
|
1143
|
-
// postcss output path is absolute position path
|
|
1144
|
-
dependencies.add(msg.file);
|
|
1145
|
-
}
|
|
1146
|
-
});
|
|
1147
|
-
return dependencies;
|
|
1148
|
-
};
|
|
1149
|
-
try {
|
|
1150
|
-
result = postcss__default(plugins).process(source, postCSSOptions);
|
|
1151
|
-
// In async mode, return a promise.
|
|
1152
|
-
if (options.isAsync) {
|
|
1153
|
-
return result
|
|
1154
|
-
.then(result => ({
|
|
1155
|
-
code: result.css || '',
|
|
1156
|
-
map: result.map && result.map.toJSON(),
|
|
1157
|
-
errors,
|
|
1158
|
-
modules: cssModules,
|
|
1159
|
-
rawResult: result,
|
|
1160
|
-
dependencies: recordPlainCssDependencies(result.messages)
|
|
1161
|
-
}))
|
|
1162
|
-
.catch(error => ({
|
|
1163
|
-
code: '',
|
|
1164
|
-
map: undefined,
|
|
1165
|
-
errors: [...errors, error],
|
|
1166
|
-
rawResult: undefined,
|
|
1167
|
-
dependencies
|
|
1168
|
-
}));
|
|
1169
|
-
}
|
|
1170
|
-
recordPlainCssDependencies(result.messages);
|
|
1171
|
-
// force synchronous transform (we know we only have sync plugins)
|
|
1172
|
-
code = result.css;
|
|
1173
|
-
outMap = result.map;
|
|
1174
|
-
}
|
|
1175
|
-
catch (e) {
|
|
1176
|
-
errors.push(e);
|
|
1177
|
-
}
|
|
1178
|
-
return {
|
|
1179
|
-
code: code || ``,
|
|
1180
|
-
map: outMap && outMap.toJSON(),
|
|
1181
|
-
errors,
|
|
1182
|
-
rawResult: result,
|
|
1183
|
-
dependencies
|
|
1184
|
-
};
|
|
1185
|
-
}
|
|
1186
|
-
function preprocess$1(options, preprocessor) {
|
|
1187
|
-
return preprocessor(options.source, options.inMap || options.map, Object.assign({ filename: options.filename }, options.preprocessOptions), options.preprocessCustomRequire);
|
|
1188
|
-
}
|
|
1189
|
-
|
|
1190
|
-
const defaultExportRE = /((?:^|\n|;)\s*)export(\s*)default/;
|
|
1191
|
-
const namedDefaultExportRE = /((?:^|\n|;)\s*)export(.+)as(\s*)default/s;
|
|
1192
|
-
const exportDefaultClassRE = /((?:^|\n|;)\s*)export\s+default\s+class\s+([\w$]+)/;
|
|
1193
|
-
/**
|
|
1194
|
-
* Utility for rewriting `export default` in a script block into a variable
|
|
1195
|
-
* declaration so that we can inject things into it
|
|
1196
|
-
*/
|
|
1197
|
-
function rewriteDefault(input, as, parserPlugins) {
|
|
1198
|
-
if (!hasDefaultExport(input)) {
|
|
1199
|
-
return input + `\nconst ${as} = {}`;
|
|
1200
|
-
}
|
|
1201
|
-
let replaced;
|
|
1202
|
-
const classMatch = input.match(exportDefaultClassRE);
|
|
1203
|
-
if (classMatch) {
|
|
1204
|
-
replaced =
|
|
1205
|
-
input.replace(exportDefaultClassRE, '$1class $2') +
|
|
1206
|
-
`\nconst ${as} = ${classMatch[2]}`;
|
|
1207
|
-
}
|
|
1208
|
-
else {
|
|
1209
|
-
replaced = input.replace(defaultExportRE, `$1const ${as} =`);
|
|
1210
|
-
}
|
|
1211
|
-
if (!hasDefaultExport(replaced)) {
|
|
1212
|
-
return replaced;
|
|
1213
|
-
}
|
|
1214
|
-
// if the script somehow still contains `default export`, it probably has
|
|
1215
|
-
// multi-line comments or template strings. fallback to a full parse.
|
|
1216
|
-
const s = new MagicString__default(input);
|
|
1217
|
-
const ast = parser.parse(input, {
|
|
1218
|
-
sourceType: 'module',
|
|
1219
|
-
plugins: parserPlugins
|
|
1220
|
-
}).program.body;
|
|
1221
|
-
ast.forEach(node => {
|
|
1222
|
-
if (node.type === 'ExportDefaultDeclaration') {
|
|
1223
|
-
s.overwrite(node.start, node.declaration.start, `const ${as} = `);
|
|
1224
|
-
}
|
|
1225
|
-
if (node.type === 'ExportNamedDeclaration') {
|
|
1226
|
-
node.specifiers.forEach(specifier => {
|
|
1227
|
-
if (specifier.type === 'ExportSpecifier' &&
|
|
1228
|
-
specifier.exported.type === 'Identifier' &&
|
|
1229
|
-
specifier.exported.name === 'default') {
|
|
1230
|
-
const end = specifier.end;
|
|
1231
|
-
s.overwrite(specifier.start, input.charAt(end) === ',' ? end + 1 : end, ``);
|
|
1232
|
-
s.append(`\nconst ${as} = ${specifier.local.name}`);
|
|
1233
|
-
}
|
|
1234
|
-
});
|
|
1235
|
-
}
|
|
1236
|
-
});
|
|
1237
|
-
return s.toString();
|
|
1238
|
-
}
|
|
1239
|
-
function hasDefaultExport(input) {
|
|
1240
|
-
return defaultExportRE.test(input) || namedDefaultExportRE.test(input);
|
|
1241
|
-
}
|
|
1242
|
-
|
|
1243
|
-
// Special compiler macros
|
|
1244
|
-
const DEFINE_PROPS = 'defineProps';
|
|
1245
|
-
const DEFINE_EMITS = 'defineEmits';
|
|
1246
|
-
const DEFINE_EXPOSE = 'defineExpose';
|
|
1247
|
-
const WITH_DEFAULTS = 'withDefaults';
|
|
1248
|
-
const isBuiltInDir = shared.makeMap(`once,memo,if,else,else-if,slot,text,html,on,bind,model,show,cloak,is`);
|
|
1249
|
-
/**
|
|
1250
|
-
* Compile `<script setup>`
|
|
1251
|
-
* It requires the whole SFC descriptor because we need to handle and merge
|
|
1252
|
-
* normal `<script>` + `<script setup>` if both are present.
|
|
1253
|
-
*/
|
|
1254
|
-
function compileScript(sfc, options) {
|
|
1255
|
-
let { script, scriptSetup, source, filename } = sfc;
|
|
1256
|
-
// feature flags
|
|
1257
|
-
const enableRefTransform = !!options.refSugar || !!options.refTransform;
|
|
1258
|
-
let refBindings;
|
|
1259
|
-
// for backwards compat
|
|
1260
|
-
if (!options) {
|
|
1261
|
-
options = { id: '' };
|
|
1262
|
-
}
|
|
1263
|
-
if (!options.id) {
|
|
1264
|
-
warnOnce(`compileScript now requires passing the \`id\` option.\n` +
|
|
1265
|
-
`Upgrade your vite or vue-loader version for compatibility with ` +
|
|
1266
|
-
`the latest experimental proposals.`);
|
|
1267
|
-
}
|
|
1268
|
-
const scopeId = options.id ? options.id.replace(/^data-v-/, '') : '';
|
|
1269
|
-
const cssVars = sfc.cssVars;
|
|
1270
|
-
const scriptLang = script && script.lang;
|
|
1271
|
-
const scriptSetupLang = scriptSetup && scriptSetup.lang;
|
|
1272
|
-
const isTS = scriptLang === 'ts' ||
|
|
1273
|
-
scriptLang === 'tsx' ||
|
|
1274
|
-
scriptSetupLang === 'ts' ||
|
|
1275
|
-
scriptSetupLang === 'tsx';
|
|
1276
|
-
const plugins = [...shared.babelParserDefaultPlugins];
|
|
1277
|
-
if (!isTS || scriptLang === 'tsx' || scriptSetupLang === 'tsx') {
|
|
1278
|
-
plugins.push('jsx');
|
|
1279
|
-
}
|
|
1280
|
-
if (options.babelParserPlugins)
|
|
1281
|
-
plugins.push(...options.babelParserPlugins);
|
|
1282
|
-
if (isTS)
|
|
1283
|
-
plugins.push('typescript', 'decorators-legacy');
|
|
1284
|
-
if (!scriptSetup) {
|
|
1285
|
-
if (!script) {
|
|
1286
|
-
throw new Error(`[@vue/compiler-sfc] SFC contains no <script> tags.`);
|
|
1287
|
-
}
|
|
1288
|
-
if (scriptLang && !isTS && scriptLang !== 'jsx') {
|
|
1289
|
-
// do not process non js/ts script blocks
|
|
1290
|
-
return script;
|
|
1291
|
-
}
|
|
1292
|
-
try {
|
|
1293
|
-
let content = script.content;
|
|
1294
|
-
let map = script.map;
|
|
1295
|
-
const scriptAst = parser.parse(content, {
|
|
1296
|
-
plugins,
|
|
1297
|
-
sourceType: 'module'
|
|
1298
|
-
}).program;
|
|
1299
|
-
const bindings = analyzeScriptBindings(scriptAst.body);
|
|
1300
|
-
if (enableRefTransform && refTransform.shouldTransform(content)) {
|
|
1301
|
-
const s = new MagicString__default(source);
|
|
1302
|
-
const startOffset = script.loc.start.offset;
|
|
1303
|
-
const endOffset = script.loc.end.offset;
|
|
1304
|
-
const { importedHelpers } = refTransform.transformAST(scriptAst, s, startOffset);
|
|
1305
|
-
if (importedHelpers.length) {
|
|
1306
|
-
s.prepend(`import { ${importedHelpers
|
|
1307
|
-
.map(h => `${h} as _${h}`)
|
|
1308
|
-
.join(', ')} } from 'vue'\n`);
|
|
1309
|
-
}
|
|
1310
|
-
s.remove(0, startOffset);
|
|
1311
|
-
s.remove(endOffset, source.length);
|
|
1312
|
-
content = s.toString();
|
|
1313
|
-
map = s.generateMap({
|
|
1314
|
-
source: filename,
|
|
1315
|
-
hires: true,
|
|
1316
|
-
includeContent: true
|
|
1317
|
-
});
|
|
1318
|
-
}
|
|
1319
|
-
if (cssVars.length) {
|
|
1320
|
-
content = rewriteDefault(content, `__default__`, plugins);
|
|
1321
|
-
content += genNormalScriptCssVarsCode(cssVars, bindings, scopeId, !!options.isProd);
|
|
1322
|
-
content += `\nexport default __default__`;
|
|
1323
|
-
}
|
|
1324
|
-
content += jsvCssToJs.compileCssToJs(sfc, options); // QCode Added
|
|
1325
|
-
return Object.assign(Object.assign({}, script), { content,
|
|
1326
|
-
map,
|
|
1327
|
-
bindings, scriptAst: scriptAst.body });
|
|
1328
|
-
}
|
|
1329
|
-
catch (e) {
|
|
1330
|
-
// silently fallback if parse fails since user may be using custom
|
|
1331
|
-
// babel syntax
|
|
1332
|
-
return script;
|
|
1333
|
-
}
|
|
1334
|
-
}
|
|
1335
|
-
if (script && scriptLang !== scriptSetupLang) {
|
|
1336
|
-
throw new Error(`[@vue/compiler-sfc] <script> and <script setup> must have the same ` +
|
|
1337
|
-
`language type.`);
|
|
1338
|
-
}
|
|
1339
|
-
if (scriptSetupLang && !isTS && scriptSetupLang !== 'jsx') {
|
|
1340
|
-
// do not process non js/ts script blocks
|
|
1341
|
-
return scriptSetup;
|
|
1342
|
-
}
|
|
1343
|
-
// metadata that needs to be returned
|
|
1344
|
-
const bindingMetadata = {};
|
|
1345
|
-
const defaultTempVar = `__default__`;
|
|
1346
|
-
const helperImports = new Set();
|
|
1347
|
-
const userImports = Object.create(null);
|
|
1348
|
-
const userImportAlias = Object.create(null);
|
|
1349
|
-
const setupBindings = Object.create(null);
|
|
1350
|
-
let defaultExport;
|
|
1351
|
-
let hasDefinePropsCall = false;
|
|
1352
|
-
let hasDefineEmitCall = false;
|
|
1353
|
-
let hasDefineExposeCall = false;
|
|
1354
|
-
let propsRuntimeDecl;
|
|
1355
|
-
let propsRuntimeDefaults;
|
|
1356
|
-
let propsTypeDecl;
|
|
1357
|
-
let propsTypeDeclRaw;
|
|
1358
|
-
let propsIdentifier;
|
|
1359
|
-
let emitsRuntimeDecl;
|
|
1360
|
-
let emitsTypeDecl;
|
|
1361
|
-
let emitsTypeDeclRaw;
|
|
1362
|
-
let emitIdentifier;
|
|
1363
|
-
let hasAwait = false;
|
|
1364
|
-
let hasInlinedSsrRenderFn = false;
|
|
1365
|
-
// props/emits declared via types
|
|
1366
|
-
const typeDeclaredProps = {};
|
|
1367
|
-
const typeDeclaredEmits = new Set();
|
|
1368
|
-
// record declared types for runtime props type generation
|
|
1369
|
-
const declaredTypes = {};
|
|
1370
|
-
// magic-string state
|
|
1371
|
-
const s = new MagicString__default(source);
|
|
1372
|
-
const startOffset = scriptSetup.loc.start.offset;
|
|
1373
|
-
const endOffset = scriptSetup.loc.end.offset;
|
|
1374
|
-
const scriptStartOffset = script && script.loc.start.offset;
|
|
1375
|
-
const scriptEndOffset = script && script.loc.end.offset;
|
|
1376
|
-
function helper(key) {
|
|
1377
|
-
helperImports.add(key);
|
|
1378
|
-
return `_${key}`;
|
|
1379
|
-
}
|
|
1380
|
-
function parse(input, options, offset) {
|
|
1381
|
-
try {
|
|
1382
|
-
return parser.parse(input, options).program;
|
|
1383
|
-
}
|
|
1384
|
-
catch (e) {
|
|
1385
|
-
e.message = `[@vue/compiler-sfc] ${e.message}\n\n${sfc.filename}\n${shared.generateCodeFrame(source, e.pos + offset, e.pos + offset + 1)}`;
|
|
1386
|
-
throw e;
|
|
1387
|
-
}
|
|
1388
|
-
}
|
|
1389
|
-
function error(msg, node, end = node.end + startOffset) {
|
|
1390
|
-
throw new Error(`[@vue/compiler-sfc] ${msg}\n\n${sfc.filename}\n${shared.generateCodeFrame(source, node.start + startOffset, end)}`);
|
|
1391
|
-
}
|
|
1392
|
-
function registerUserImport(source, local, imported, isType, isFromSetup) {
|
|
1393
|
-
if (source === 'vue' && imported) {
|
|
1394
|
-
userImportAlias[imported] = local;
|
|
1395
|
-
}
|
|
1396
|
-
let isUsedInTemplate = true;
|
|
1397
|
-
if (isTS && sfc.template && !sfc.template.src && !sfc.template.lang) {
|
|
1398
|
-
isUsedInTemplate = new RegExp(
|
|
1399
|
-
// #4274 escape $ since it's a special char in regex
|
|
1400
|
-
// (and is the only regex special char that is valid in identifiers)
|
|
1401
|
-
`[^\\w$_]${local.replace(/\$/g, '\\$')}[^\\w$_]`).test(resolveTemplateUsageCheckString(sfc));
|
|
1402
|
-
}
|
|
1403
|
-
userImports[local] = {
|
|
1404
|
-
isType,
|
|
1405
|
-
imported: imported || 'default',
|
|
1406
|
-
source,
|
|
1407
|
-
isFromSetup,
|
|
1408
|
-
isUsedInTemplate
|
|
1409
|
-
};
|
|
1410
|
-
}
|
|
1411
|
-
function processDefineProps(node) {
|
|
1412
|
-
if (!isCallOf(node, DEFINE_PROPS)) {
|
|
1413
|
-
return false;
|
|
1414
|
-
}
|
|
1415
|
-
if (hasDefinePropsCall) {
|
|
1416
|
-
error(`duplicate ${DEFINE_PROPS}() call`, node);
|
|
1417
|
-
}
|
|
1418
|
-
hasDefinePropsCall = true;
|
|
1419
|
-
propsRuntimeDecl = node.arguments[0];
|
|
1420
|
-
// call has type parameters - infer runtime types from it
|
|
1421
|
-
if (node.typeParameters) {
|
|
1422
|
-
if (propsRuntimeDecl) {
|
|
1423
|
-
error(`${DEFINE_PROPS}() cannot accept both type and non-type arguments ` +
|
|
1424
|
-
`at the same time. Use one or the other.`, node);
|
|
1425
|
-
}
|
|
1426
|
-
propsTypeDeclRaw = node.typeParameters.params[0];
|
|
1427
|
-
propsTypeDecl = resolveQualifiedType(propsTypeDeclRaw, node => node.type === 'TSTypeLiteral');
|
|
1428
|
-
if (!propsTypeDecl) {
|
|
1429
|
-
error(`type argument passed to ${DEFINE_PROPS}() must be a literal type, ` +
|
|
1430
|
-
`or a reference to an interface or literal type.`, propsTypeDeclRaw);
|
|
1431
|
-
}
|
|
1432
|
-
}
|
|
1433
|
-
return true;
|
|
1434
|
-
}
|
|
1435
|
-
function processWithDefaults(node) {
|
|
1436
|
-
if (!isCallOf(node, WITH_DEFAULTS)) {
|
|
1437
|
-
return false;
|
|
1438
|
-
}
|
|
1439
|
-
if (processDefineProps(node.arguments[0])) {
|
|
1440
|
-
if (propsRuntimeDecl) {
|
|
1441
|
-
error(`${WITH_DEFAULTS} can only be used with type-based ` +
|
|
1442
|
-
`${DEFINE_PROPS} declaration.`, node);
|
|
1443
|
-
}
|
|
1444
|
-
propsRuntimeDefaults = node.arguments[1];
|
|
1445
|
-
if (!propsRuntimeDefaults ||
|
|
1446
|
-
propsRuntimeDefaults.type !== 'ObjectExpression') {
|
|
1447
|
-
error(`The 2nd argument of ${WITH_DEFAULTS} must be an object literal.`, propsRuntimeDefaults || node);
|
|
1448
|
-
}
|
|
1449
|
-
}
|
|
1450
|
-
else {
|
|
1451
|
-
error(`${WITH_DEFAULTS}' first argument must be a ${DEFINE_PROPS} call.`, node.arguments[0] || node);
|
|
1452
|
-
}
|
|
1453
|
-
return true;
|
|
1454
|
-
}
|
|
1455
|
-
function processDefineEmits(node) {
|
|
1456
|
-
if (!isCallOf(node, DEFINE_EMITS)) {
|
|
1457
|
-
return false;
|
|
1458
|
-
}
|
|
1459
|
-
if (hasDefineEmitCall) {
|
|
1460
|
-
error(`duplicate ${DEFINE_EMITS}() call`, node);
|
|
1461
|
-
}
|
|
1462
|
-
hasDefineEmitCall = true;
|
|
1463
|
-
emitsRuntimeDecl = node.arguments[0];
|
|
1464
|
-
if (node.typeParameters) {
|
|
1465
|
-
if (emitsRuntimeDecl) {
|
|
1466
|
-
error(`${DEFINE_EMITS}() cannot accept both type and non-type arguments ` +
|
|
1467
|
-
`at the same time. Use one or the other.`, node);
|
|
1468
|
-
}
|
|
1469
|
-
emitsTypeDeclRaw = node.typeParameters.params[0];
|
|
1470
|
-
emitsTypeDecl = resolveQualifiedType(emitsTypeDeclRaw, node => node.type === 'TSFunctionType' || node.type === 'TSTypeLiteral');
|
|
1471
|
-
if (!emitsTypeDecl) {
|
|
1472
|
-
error(`type argument passed to ${DEFINE_EMITS}() must be a function type, ` +
|
|
1473
|
-
`a literal type with call signatures, or a reference to the above types.`, emitsTypeDeclRaw);
|
|
1474
|
-
}
|
|
1475
|
-
}
|
|
1476
|
-
return true;
|
|
1477
|
-
}
|
|
1478
|
-
function resolveQualifiedType(node, qualifier) {
|
|
1479
|
-
if (qualifier(node)) {
|
|
1480
|
-
return node;
|
|
1481
|
-
}
|
|
1482
|
-
if (node.type === 'TSTypeReference' &&
|
|
1483
|
-
node.typeName.type === 'Identifier') {
|
|
1484
|
-
const refName = node.typeName.name;
|
|
1485
|
-
const isQualifiedType = (node) => {
|
|
1486
|
-
if (node.type === 'TSInterfaceDeclaration' &&
|
|
1487
|
-
node.id.name === refName) {
|
|
1488
|
-
return node.body;
|
|
1489
|
-
}
|
|
1490
|
-
else if (node.type === 'TSTypeAliasDeclaration' &&
|
|
1491
|
-
node.id.name === refName &&
|
|
1492
|
-
qualifier(node.typeAnnotation)) {
|
|
1493
|
-
return node.typeAnnotation;
|
|
1494
|
-
}
|
|
1495
|
-
else if (node.type === 'ExportNamedDeclaration' && node.declaration) {
|
|
1496
|
-
return isQualifiedType(node.declaration);
|
|
1497
|
-
}
|
|
1498
|
-
};
|
|
1499
|
-
for (const node of scriptSetupAst.body) {
|
|
1500
|
-
const qualified = isQualifiedType(node);
|
|
1501
|
-
if (qualified) {
|
|
1502
|
-
return qualified;
|
|
1503
|
-
}
|
|
1504
|
-
}
|
|
1505
|
-
}
|
|
1506
|
-
}
|
|
1507
|
-
function processDefineExpose(node) {
|
|
1508
|
-
if (isCallOf(node, DEFINE_EXPOSE)) {
|
|
1509
|
-
if (hasDefineExposeCall) {
|
|
1510
|
-
error(`duplicate ${DEFINE_EXPOSE}() call`, node);
|
|
1511
|
-
}
|
|
1512
|
-
hasDefineExposeCall = true;
|
|
1513
|
-
return true;
|
|
1514
|
-
}
|
|
1515
|
-
return false;
|
|
1516
|
-
}
|
|
1517
|
-
function checkInvalidScopeReference(node, method) {
|
|
1518
|
-
if (!node)
|
|
1519
|
-
return;
|
|
1520
|
-
CompilerDOM.walkIdentifiers(node, id => {
|
|
1521
|
-
if (setupBindings[id.name]) {
|
|
1522
|
-
error(`\`${method}()\` in <script setup> cannot reference locally ` +
|
|
1523
|
-
`declared variables because it will be hoisted outside of the ` +
|
|
1524
|
-
`setup() function. If your component options requires initialization ` +
|
|
1525
|
-
`in the module scope, use a separate normal <script> to export ` +
|
|
1526
|
-
`the options instead.`, id);
|
|
1527
|
-
}
|
|
1528
|
-
});
|
|
1529
|
-
}
|
|
1530
|
-
/**
|
|
1531
|
-
* await foo()
|
|
1532
|
-
* -->
|
|
1533
|
-
* (([__temp, __restore] = withAsyncContext(() => foo())),__temp=await __temp,__restore(),__temp)
|
|
1534
|
-
*/
|
|
1535
|
-
function processAwait(node, isStatement) {
|
|
1536
|
-
s.overwrite(node.start + startOffset, node.argument.start + startOffset, `${isStatement ? `;` : ``}(([__temp,__restore]=${helper(`withAsyncContext`)}(()=>(`);
|
|
1537
|
-
s.appendLeft(node.end + startOffset, `))),__temp=await __temp,__restore()${isStatement ? `` : `,__temp`})`);
|
|
1538
|
-
}
|
|
1539
|
-
/**
|
|
1540
|
-
* check defaults. If the default object is an object literal with only
|
|
1541
|
-
* static properties, we can directly generate more optimzied default
|
|
1542
|
-
* decalrations. Otherwise we will have to fallback to runtime merging.
|
|
1543
|
-
*/
|
|
1544
|
-
function checkStaticDefaults() {
|
|
1545
|
-
return (propsRuntimeDefaults &&
|
|
1546
|
-
propsRuntimeDefaults.type === 'ObjectExpression' &&
|
|
1547
|
-
propsRuntimeDefaults.properties.every(node => (node.type === 'ObjectProperty' && !node.computed) ||
|
|
1548
|
-
node.type === 'ObjectMethod'));
|
|
1549
|
-
}
|
|
1550
|
-
function genRuntimeProps(props) {
|
|
1551
|
-
const keys = Object.keys(props);
|
|
1552
|
-
if (!keys.length) {
|
|
1553
|
-
return ``;
|
|
1554
|
-
}
|
|
1555
|
-
const hasStaticDefaults = checkStaticDefaults();
|
|
1556
|
-
const scriptSetupSource = scriptSetup.content;
|
|
1557
|
-
let propsDecls = `{
|
|
1558
|
-
${keys
|
|
1559
|
-
.map(key => {
|
|
1560
|
-
let defaultString;
|
|
1561
|
-
if (hasStaticDefaults) {
|
|
1562
|
-
const prop = propsRuntimeDefaults.properties.find((node) => node.key.name === key);
|
|
1563
|
-
if (prop) {
|
|
1564
|
-
if (prop.type === 'ObjectProperty') {
|
|
1565
|
-
// prop has corresponding static default value
|
|
1566
|
-
defaultString = `default: ${scriptSetupSource.slice(prop.value.start, prop.value.end)}`;
|
|
1567
|
-
}
|
|
1568
|
-
else {
|
|
1569
|
-
defaultString = `default() ${scriptSetupSource.slice(prop.body.start, prop.body.end)}`;
|
|
1570
|
-
}
|
|
1571
|
-
}
|
|
1572
|
-
}
|
|
1573
|
-
{
|
|
1574
|
-
const { type, required } = props[key];
|
|
1575
|
-
return `${key}: { type: ${toRuntimeTypeString(type)}, required: ${required}${defaultString ? `, ${defaultString}` : ``} }`;
|
|
1576
|
-
}
|
|
1577
|
-
})
|
|
1578
|
-
.join(',\n ')}\n }`;
|
|
1579
|
-
if (propsRuntimeDefaults && !hasStaticDefaults) {
|
|
1580
|
-
propsDecls = `${helper('mergeDefaults')}(${propsDecls}, ${source.slice(propsRuntimeDefaults.start + startOffset, propsRuntimeDefaults.end + startOffset)})`;
|
|
1581
|
-
}
|
|
1582
|
-
return `\n props: ${propsDecls},`;
|
|
1583
|
-
}
|
|
1584
|
-
function genSetupPropsType(node) {
|
|
1585
|
-
const scriptSetupSource = scriptSetup.content;
|
|
1586
|
-
if (checkStaticDefaults()) {
|
|
1587
|
-
// if withDefaults() is used, we need to remove the optional flags
|
|
1588
|
-
// on props that have default values
|
|
1589
|
-
let res = `{ `;
|
|
1590
|
-
const members = node.type === 'TSTypeLiteral' ? node.members : node.body;
|
|
1591
|
-
for (const m of members) {
|
|
1592
|
-
if ((m.type === 'TSPropertySignature' ||
|
|
1593
|
-
m.type === 'TSMethodSignature') &&
|
|
1594
|
-
m.typeAnnotation &&
|
|
1595
|
-
m.key.type === 'Identifier') {
|
|
1596
|
-
if (propsRuntimeDefaults.properties.some((p) => p.key.name === m.key.name)) {
|
|
1597
|
-
res +=
|
|
1598
|
-
m.key.name +
|
|
1599
|
-
(m.type === 'TSMethodSignature' ? '()' : '') +
|
|
1600
|
-
scriptSetupSource.slice(m.typeAnnotation.start, m.typeAnnotation.end) +
|
|
1601
|
-
', ';
|
|
1602
|
-
}
|
|
1603
|
-
else {
|
|
1604
|
-
res += scriptSetupSource.slice(m.start, m.end) + `, `;
|
|
1605
|
-
}
|
|
1606
|
-
}
|
|
1607
|
-
}
|
|
1608
|
-
return (res.length ? res.slice(0, -2) : res) + ` }`;
|
|
1609
|
-
}
|
|
1610
|
-
else {
|
|
1611
|
-
return scriptSetupSource.slice(node.start, node.end);
|
|
1612
|
-
}
|
|
1613
|
-
}
|
|
1614
|
-
// 1. process normal <script> first if it exists
|
|
1615
|
-
let scriptAst;
|
|
1616
|
-
if (script) {
|
|
1617
|
-
// import dedupe between <script> and <script setup>
|
|
1618
|
-
scriptAst = parse(script.content, {
|
|
1619
|
-
plugins,
|
|
1620
|
-
sourceType: 'module'
|
|
1621
|
-
}, scriptStartOffset);
|
|
1622
|
-
for (const node of scriptAst.body) {
|
|
1623
|
-
if (node.type === 'ImportDeclaration') {
|
|
1624
|
-
// record imports for dedupe
|
|
1625
|
-
for (const specifier of node.specifiers) {
|
|
1626
|
-
const imported = specifier.type === 'ImportSpecifier' &&
|
|
1627
|
-
specifier.imported.type === 'Identifier' &&
|
|
1628
|
-
specifier.imported.name;
|
|
1629
|
-
registerUserImport(node.source.value, specifier.local.name, imported, node.importKind === 'type', false);
|
|
1630
|
-
}
|
|
1631
|
-
}
|
|
1632
|
-
else if (node.type === 'ExportDefaultDeclaration') {
|
|
1633
|
-
// export default
|
|
1634
|
-
defaultExport = node;
|
|
1635
|
-
const start = node.start + scriptStartOffset;
|
|
1636
|
-
const end = node.declaration.start + scriptStartOffset;
|
|
1637
|
-
s.overwrite(start, end, `const ${defaultTempVar} = `);
|
|
1638
|
-
}
|
|
1639
|
-
else if (node.type === 'ExportNamedDeclaration' && node.specifiers) {
|
|
1640
|
-
const defaultSpecifier = node.specifiers.find(s => s.exported.type === 'Identifier' && s.exported.name === 'default');
|
|
1641
|
-
if (defaultSpecifier) {
|
|
1642
|
-
defaultExport = node;
|
|
1643
|
-
// 1. remove specifier
|
|
1644
|
-
if (node.specifiers.length > 1) {
|
|
1645
|
-
s.remove(defaultSpecifier.start + scriptStartOffset, defaultSpecifier.end + scriptStartOffset);
|
|
1646
|
-
}
|
|
1647
|
-
else {
|
|
1648
|
-
s.remove(node.start + scriptStartOffset, node.end + scriptStartOffset);
|
|
1649
|
-
}
|
|
1650
|
-
if (node.source) {
|
|
1651
|
-
// export { x as default } from './x'
|
|
1652
|
-
// rewrite to `import { x as __default__ } from './x'` and
|
|
1653
|
-
// add to top
|
|
1654
|
-
s.prepend(`import { ${defaultSpecifier.local.name} as ${defaultTempVar} } from '${node.source.value}'\n`);
|
|
1655
|
-
}
|
|
1656
|
-
else {
|
|
1657
|
-
// export { x as default }
|
|
1658
|
-
// rewrite to `const __default__ = x` and move to end
|
|
1659
|
-
s.append(`\nconst ${defaultTempVar} = ${defaultSpecifier.local.name}\n`);
|
|
1660
|
-
}
|
|
1661
|
-
}
|
|
1662
|
-
}
|
|
1663
|
-
else if ((node.type === 'VariableDeclaration' ||
|
|
1664
|
-
node.type === 'FunctionDeclaration' ||
|
|
1665
|
-
node.type === 'ClassDeclaration') &&
|
|
1666
|
-
!node.declare) {
|
|
1667
|
-
walkDeclaration(node, setupBindings, userImportAlias);
|
|
1668
|
-
}
|
|
1669
|
-
}
|
|
1670
|
-
// apply ref transform
|
|
1671
|
-
if (enableRefTransform && refTransform.shouldTransform(script.content)) {
|
|
1672
|
-
const { rootVars, importedHelpers } = refTransform.transformAST(scriptAst, s, scriptStartOffset);
|
|
1673
|
-
refBindings = rootVars;
|
|
1674
|
-
for (const h of importedHelpers) {
|
|
1675
|
-
helperImports.add(h);
|
|
1676
|
-
}
|
|
1677
|
-
}
|
|
1678
|
-
}
|
|
1679
|
-
// 2. parse <script setup> and walk over top level statements
|
|
1680
|
-
const scriptSetupAst = parse(scriptSetup.content, {
|
|
1681
|
-
plugins: [
|
|
1682
|
-
...plugins,
|
|
1683
|
-
// allow top level await but only inside <script setup>
|
|
1684
|
-
'topLevelAwait'
|
|
1685
|
-
],
|
|
1686
|
-
sourceType: 'module'
|
|
1687
|
-
}, startOffset);
|
|
1688
|
-
for (const node of scriptSetupAst.body) {
|
|
1689
|
-
const start = node.start + startOffset;
|
|
1690
|
-
let end = node.end + startOffset;
|
|
1691
|
-
// locate comment
|
|
1692
|
-
if (node.trailingComments && node.trailingComments.length > 0) {
|
|
1693
|
-
const lastCommentNode = node.trailingComments[node.trailingComments.length - 1];
|
|
1694
|
-
end = lastCommentNode.end + startOffset;
|
|
1695
|
-
}
|
|
1696
|
-
// locate the end of whitespace between this statement and the next
|
|
1697
|
-
while (end <= source.length) {
|
|
1698
|
-
if (!/\s/.test(source.charAt(end))) {
|
|
1699
|
-
break;
|
|
1700
|
-
}
|
|
1701
|
-
end++;
|
|
1702
|
-
}
|
|
1703
|
-
// (Dropped) `ref: x` bindings
|
|
1704
|
-
if (node.type === 'LabeledStatement' &&
|
|
1705
|
-
node.label.name === 'ref' &&
|
|
1706
|
-
node.body.type === 'ExpressionStatement') {
|
|
1707
|
-
error(`ref sugar using the label syntax was an experimental proposal and ` +
|
|
1708
|
-
`has been dropped based on community feedback. Please check out ` +
|
|
1709
|
-
`the new proposal at https://github.com/vuejs/rfcs/discussions/369`, node);
|
|
1710
|
-
}
|
|
1711
|
-
if (node.type === 'ImportDeclaration') {
|
|
1712
|
-
// import declarations are moved to top
|
|
1713
|
-
s.move(start, end, 0);
|
|
1714
|
-
// dedupe imports
|
|
1715
|
-
let removed = 0;
|
|
1716
|
-
const removeSpecifier = (i) => {
|
|
1717
|
-
const removeLeft = i > removed;
|
|
1718
|
-
removed++;
|
|
1719
|
-
const current = node.specifiers[i];
|
|
1720
|
-
const next = node.specifiers[i + 1];
|
|
1721
|
-
s.remove(removeLeft
|
|
1722
|
-
? node.specifiers[i - 1].end + startOffset
|
|
1723
|
-
: current.start + startOffset, next && !removeLeft
|
|
1724
|
-
? next.start + startOffset
|
|
1725
|
-
: current.end + startOffset);
|
|
1726
|
-
};
|
|
1727
|
-
for (let i = 0; i < node.specifiers.length; i++) {
|
|
1728
|
-
const specifier = node.specifiers[i];
|
|
1729
|
-
const local = specifier.local.name;
|
|
1730
|
-
const imported = specifier.type === 'ImportSpecifier' &&
|
|
1731
|
-
specifier.imported.type === 'Identifier' &&
|
|
1732
|
-
specifier.imported.name;
|
|
1733
|
-
const source = node.source.value;
|
|
1734
|
-
const existing = userImports[local];
|
|
1735
|
-
if (source === 'vue' &&
|
|
1736
|
-
(imported === DEFINE_PROPS ||
|
|
1737
|
-
imported === DEFINE_EMITS ||
|
|
1738
|
-
imported === DEFINE_EXPOSE)) {
|
|
1739
|
-
warnOnce(`\`${imported}\` is a compiler macro and no longer needs to be imported.`);
|
|
1740
|
-
removeSpecifier(i);
|
|
1741
|
-
}
|
|
1742
|
-
else if (existing) {
|
|
1743
|
-
if (existing.source === source && existing.imported === imported) {
|
|
1744
|
-
// already imported in <script setup>, dedupe
|
|
1745
|
-
removeSpecifier(i);
|
|
1746
|
-
}
|
|
1747
|
-
else {
|
|
1748
|
-
error(`different imports aliased to same local name.`, specifier);
|
|
1749
|
-
}
|
|
1750
|
-
}
|
|
1751
|
-
else {
|
|
1752
|
-
registerUserImport(source, local, imported, node.importKind === 'type', true);
|
|
1753
|
-
}
|
|
1754
|
-
}
|
|
1755
|
-
if (node.specifiers.length && removed === node.specifiers.length) {
|
|
1756
|
-
s.remove(node.start + startOffset, node.end + startOffset);
|
|
1757
|
-
}
|
|
1758
|
-
}
|
|
1759
|
-
if (node.type === 'ExpressionStatement') {
|
|
1760
|
-
// process `defineProps` and `defineEmit(s)` calls
|
|
1761
|
-
if (processDefineProps(node.expression) ||
|
|
1762
|
-
processDefineEmits(node.expression) ||
|
|
1763
|
-
processWithDefaults(node.expression)) {
|
|
1764
|
-
s.remove(node.start + startOffset, node.end + startOffset);
|
|
1765
|
-
}
|
|
1766
|
-
else if (processDefineExpose(node.expression)) {
|
|
1767
|
-
// defineExpose({}) -> expose({})
|
|
1768
|
-
const callee = node.expression.callee;
|
|
1769
|
-
s.overwrite(callee.start + startOffset, callee.end + startOffset, 'expose');
|
|
1770
|
-
}
|
|
1771
|
-
}
|
|
1772
|
-
if (node.type === 'VariableDeclaration' && !node.declare) {
|
|
1773
|
-
const total = node.declarations.length;
|
|
1774
|
-
let left = total;
|
|
1775
|
-
for (let i = 0; i < total; i++) {
|
|
1776
|
-
const decl = node.declarations[i];
|
|
1777
|
-
if (decl.init) {
|
|
1778
|
-
// defineProps / defineEmits
|
|
1779
|
-
const isDefineProps = processDefineProps(decl.init) || processWithDefaults(decl.init);
|
|
1780
|
-
if (isDefineProps) {
|
|
1781
|
-
propsIdentifier = scriptSetup.content.slice(decl.id.start, decl.id.end);
|
|
1782
|
-
}
|
|
1783
|
-
const isDefineEmits = processDefineEmits(decl.init);
|
|
1784
|
-
if (isDefineEmits) {
|
|
1785
|
-
emitIdentifier = scriptSetup.content.slice(decl.id.start, decl.id.end);
|
|
1786
|
-
}
|
|
1787
|
-
if (isDefineProps || isDefineEmits) {
|
|
1788
|
-
if (left === 1) {
|
|
1789
|
-
s.remove(node.start + startOffset, node.end + startOffset);
|
|
1790
|
-
}
|
|
1791
|
-
else {
|
|
1792
|
-
let start = decl.start + startOffset;
|
|
1793
|
-
let end = decl.end + startOffset;
|
|
1794
|
-
if (i < total - 1) {
|
|
1795
|
-
// not the last one, locate the start of the next
|
|
1796
|
-
end = node.declarations[i + 1].start + startOffset;
|
|
1797
|
-
}
|
|
1798
|
-
else {
|
|
1799
|
-
// last one, locate the end of the prev
|
|
1800
|
-
start = node.declarations[i - 1].end + startOffset;
|
|
1801
|
-
}
|
|
1802
|
-
s.remove(start, end);
|
|
1803
|
-
left--;
|
|
1804
|
-
}
|
|
1805
|
-
}
|
|
1806
|
-
}
|
|
1807
|
-
}
|
|
1808
|
-
}
|
|
1809
|
-
// walk decalrations to record declared bindings
|
|
1810
|
-
if ((node.type === 'VariableDeclaration' ||
|
|
1811
|
-
node.type === 'FunctionDeclaration' ||
|
|
1812
|
-
node.type === 'ClassDeclaration') &&
|
|
1813
|
-
!node.declare) {
|
|
1814
|
-
walkDeclaration(node, setupBindings, userImportAlias);
|
|
1815
|
-
}
|
|
1816
|
-
// walk statements & named exports / variable declarations for top level
|
|
1817
|
-
// await
|
|
1818
|
-
if ((node.type === 'VariableDeclaration' && !node.declare) ||
|
|
1819
|
-
node.type.endsWith('Statement')) {
|
|
1820
|
-
estreeWalker.walk(node, {
|
|
1821
|
-
enter(child, parent) {
|
|
1822
|
-
if (CompilerDOM.isFunctionType(child)) {
|
|
1823
|
-
this.skip();
|
|
1824
|
-
}
|
|
1825
|
-
if (child.type === 'AwaitExpression') {
|
|
1826
|
-
hasAwait = true;
|
|
1827
|
-
processAwait(child, parent.type === 'ExpressionStatement');
|
|
1828
|
-
}
|
|
1829
|
-
}
|
|
1830
|
-
});
|
|
1831
|
-
}
|
|
1832
|
-
if ((node.type === 'ExportNamedDeclaration' && node.exportKind !== 'type') ||
|
|
1833
|
-
node.type === 'ExportAllDeclaration' ||
|
|
1834
|
-
node.type === 'ExportDefaultDeclaration') {
|
|
1835
|
-
error(`<script setup> cannot contain ES module exports. ` +
|
|
1836
|
-
`If you are using a previous version of <script setup>, please ` +
|
|
1837
|
-
`consult the updated RFC at https://github.com/vuejs/rfcs/pull/227.`, node);
|
|
1838
|
-
}
|
|
1839
|
-
if (isTS) {
|
|
1840
|
-
// runtime enum
|
|
1841
|
-
if (node.type === 'TSEnumDeclaration') {
|
|
1842
|
-
registerBinding(setupBindings, node.id, "setup-const" /* SETUP_CONST */);
|
|
1843
|
-
}
|
|
1844
|
-
// move all Type declarations to outer scope
|
|
1845
|
-
if (node.type.startsWith('TS') ||
|
|
1846
|
-
(node.type === 'ExportNamedDeclaration' &&
|
|
1847
|
-
node.exportKind === 'type') ||
|
|
1848
|
-
(node.type === 'VariableDeclaration' && node.declare)) {
|
|
1849
|
-
recordType(node, declaredTypes);
|
|
1850
|
-
s.move(start, end, 0);
|
|
1851
|
-
}
|
|
1852
|
-
}
|
|
1853
|
-
}
|
|
1854
|
-
// 3. Apply ref sugar transform
|
|
1855
|
-
if (enableRefTransform && refTransform.shouldTransform(scriptSetup.content)) {
|
|
1856
|
-
const { rootVars, importedHelpers } = refTransform.transformAST(scriptSetupAst, s, startOffset, refBindings);
|
|
1857
|
-
refBindings = refBindings ? [...refBindings, ...rootVars] : rootVars;
|
|
1858
|
-
for (const h of importedHelpers) {
|
|
1859
|
-
helperImports.add(h);
|
|
1860
|
-
}
|
|
1861
|
-
}
|
|
1862
|
-
// 4. extract runtime props/emits code from setup context type
|
|
1863
|
-
if (propsTypeDecl) {
|
|
1864
|
-
extractRuntimeProps(propsTypeDecl, typeDeclaredProps, declaredTypes);
|
|
1865
|
-
}
|
|
1866
|
-
if (emitsTypeDecl) {
|
|
1867
|
-
extractRuntimeEmits(emitsTypeDecl, typeDeclaredEmits);
|
|
1868
|
-
}
|
|
1869
|
-
// 5. check useOptions args to make sure it doesn't reference setup scope
|
|
1870
|
-
// variables
|
|
1871
|
-
checkInvalidScopeReference(propsRuntimeDecl, DEFINE_PROPS);
|
|
1872
|
-
checkInvalidScopeReference(propsRuntimeDefaults, DEFINE_PROPS);
|
|
1873
|
-
checkInvalidScopeReference(emitsRuntimeDecl, DEFINE_PROPS);
|
|
1874
|
-
// 6. remove non-script content
|
|
1875
|
-
if (script) {
|
|
1876
|
-
if (startOffset < scriptStartOffset) {
|
|
1877
|
-
// <script setup> before <script>
|
|
1878
|
-
s.remove(0, startOffset);
|
|
1879
|
-
s.remove(endOffset, scriptStartOffset);
|
|
1880
|
-
s.remove(scriptEndOffset, source.length);
|
|
1881
|
-
}
|
|
1882
|
-
else {
|
|
1883
|
-
// <script> before <script setup>
|
|
1884
|
-
s.remove(0, scriptStartOffset);
|
|
1885
|
-
s.remove(scriptEndOffset, startOffset);
|
|
1886
|
-
s.remove(endOffset, source.length);
|
|
1887
|
-
}
|
|
1888
|
-
}
|
|
1889
|
-
else {
|
|
1890
|
-
// only <script setup>
|
|
1891
|
-
s.remove(0, startOffset);
|
|
1892
|
-
s.remove(endOffset, source.length);
|
|
1893
|
-
}
|
|
1894
|
-
// 7. analyze binding metadata
|
|
1895
|
-
if (scriptAst) {
|
|
1896
|
-
Object.assign(bindingMetadata, analyzeScriptBindings(scriptAst.body));
|
|
1897
|
-
}
|
|
1898
|
-
if (propsRuntimeDecl) {
|
|
1899
|
-
for (const key of getObjectOrArrayExpressionKeys(propsRuntimeDecl)) {
|
|
1900
|
-
bindingMetadata[key] = "props" /* PROPS */;
|
|
1901
|
-
}
|
|
1902
|
-
}
|
|
1903
|
-
for (const key in typeDeclaredProps) {
|
|
1904
|
-
bindingMetadata[key] = "props" /* PROPS */;
|
|
1905
|
-
}
|
|
1906
|
-
for (const [key, { isType, imported, source }] of Object.entries(userImports)) {
|
|
1907
|
-
if (isType)
|
|
1908
|
-
continue;
|
|
1909
|
-
bindingMetadata[key] =
|
|
1910
|
-
(imported === 'default' && source.endsWith('.vue')) || source === 'vue'
|
|
1911
|
-
? "setup-const" /* SETUP_CONST */
|
|
1912
|
-
: "setup-maybe-ref" /* SETUP_MAYBE_REF */;
|
|
1913
|
-
}
|
|
1914
|
-
for (const key in setupBindings) {
|
|
1915
|
-
bindingMetadata[key] = setupBindings[key];
|
|
1916
|
-
}
|
|
1917
|
-
// known ref bindings
|
|
1918
|
-
if (refBindings) {
|
|
1919
|
-
for (const key of refBindings) {
|
|
1920
|
-
bindingMetadata[key] = "setup-ref" /* SETUP_REF */;
|
|
1921
|
-
}
|
|
1922
|
-
}
|
|
1923
|
-
// 8. inject `useCssVars` calls
|
|
1924
|
-
if (cssVars.length) {
|
|
1925
|
-
helperImports.add(CSS_VARS_HELPER);
|
|
1926
|
-
helperImports.add('unref');
|
|
1927
|
-
s.prependRight(startOffset, `\n${genCssVarsCode(cssVars, bindingMetadata, scopeId, !!options.isProd)}\n`);
|
|
1928
|
-
}
|
|
1929
|
-
// 9. finalize setup() argument signature
|
|
1930
|
-
let args = `__props`;
|
|
1931
|
-
if (propsTypeDecl) {
|
|
1932
|
-
// mark as any and only cast on assignment
|
|
1933
|
-
// since the user defined complex types may be incompatible with the
|
|
1934
|
-
// inferred type from generated runtime declarations
|
|
1935
|
-
args += `: any`;
|
|
1936
|
-
}
|
|
1937
|
-
// inject user assignment of props
|
|
1938
|
-
// we use a default __props so that template expressions referencing props
|
|
1939
|
-
// can use it directly
|
|
1940
|
-
if (propsIdentifier) {
|
|
1941
|
-
s.prependRight(startOffset, `\nconst ${propsIdentifier} = __props${propsTypeDecl ? ` as ${genSetupPropsType(propsTypeDecl)}` : ``}`);
|
|
1942
|
-
}
|
|
1943
|
-
// inject temp variables for async context preservation
|
|
1944
|
-
if (hasAwait) {
|
|
1945
|
-
const any = isTS ? `: any` : ``;
|
|
1946
|
-
s.prependRight(startOffset, `\nlet __temp${any}, __restore${any}\n`);
|
|
1947
|
-
}
|
|
1948
|
-
const destructureElements = hasDefineExposeCall || !options.inlineTemplate ? [`expose`] : [];
|
|
1949
|
-
if (emitIdentifier) {
|
|
1950
|
-
destructureElements.push(emitIdentifier === `emit` ? `emit` : `emit: ${emitIdentifier}`);
|
|
1951
|
-
}
|
|
1952
|
-
if (destructureElements.length) {
|
|
1953
|
-
args += `, { ${destructureElements.join(', ')} }`;
|
|
1954
|
-
if (emitsTypeDecl) {
|
|
1955
|
-
args += `: { emit: (${scriptSetup.content.slice(emitsTypeDecl.start, emitsTypeDecl.end)}), expose: any, slots: any, attrs: any }`;
|
|
1956
|
-
}
|
|
1957
|
-
}
|
|
1958
|
-
// 10. generate return statement
|
|
1959
|
-
let returned;
|
|
1960
|
-
if (options.inlineTemplate) {
|
|
1961
|
-
if (sfc.template && !sfc.template.src) {
|
|
1962
|
-
if (options.templateOptions && options.templateOptions.ssr) {
|
|
1963
|
-
hasInlinedSsrRenderFn = true;
|
|
1964
|
-
}
|
|
1965
|
-
// inline render function mode - we are going to compile the template and
|
|
1966
|
-
// inline it right here
|
|
1967
|
-
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 &&
|
|
1968
|
-
options.templateOptions.compilerOptions)), { inline: true, isTS,
|
|
1969
|
-
bindingMetadata }) }));
|
|
1970
|
-
if (tips.length) {
|
|
1971
|
-
tips.forEach(warnOnce);
|
|
1972
|
-
}
|
|
1973
|
-
const err = errors[0];
|
|
1974
|
-
if (typeof err === 'string') {
|
|
1975
|
-
throw new Error(err);
|
|
1976
|
-
}
|
|
1977
|
-
else if (err) {
|
|
1978
|
-
if (err.loc) {
|
|
1979
|
-
err.message +=
|
|
1980
|
-
`\n\n` +
|
|
1981
|
-
sfc.filename +
|
|
1982
|
-
'\n' +
|
|
1983
|
-
shared.generateCodeFrame(source, err.loc.start.offset, err.loc.end.offset) +
|
|
1984
|
-
`\n`;
|
|
1985
|
-
}
|
|
1986
|
-
throw err;
|
|
1987
|
-
}
|
|
1988
|
-
if (preamble) {
|
|
1989
|
-
s.prepend(preamble);
|
|
1990
|
-
}
|
|
1991
|
-
// avoid duplicated unref import
|
|
1992
|
-
// as this may get injected by the render function preamble OR the
|
|
1993
|
-
// css vars codegen
|
|
1994
|
-
if (ast && ast.helpers.includes(CompilerDOM.UNREF)) {
|
|
1995
|
-
helperImports.delete('unref');
|
|
1996
|
-
}
|
|
1997
|
-
returned = code;
|
|
1998
|
-
}
|
|
1999
|
-
else {
|
|
2000
|
-
returned = `() => {}`;
|
|
2001
|
-
}
|
|
2002
|
-
}
|
|
2003
|
-
else {
|
|
2004
|
-
// return bindings from setup
|
|
2005
|
-
const allBindings = Object.assign({}, setupBindings);
|
|
2006
|
-
for (const key in userImports) {
|
|
2007
|
-
if (!userImports[key].isType && userImports[key].isUsedInTemplate) {
|
|
2008
|
-
allBindings[key] = true;
|
|
2009
|
-
}
|
|
2010
|
-
}
|
|
2011
|
-
returned = `{ ${Object.keys(allBindings).join(', ')} }`;
|
|
2012
|
-
}
|
|
2013
|
-
if (!options.inlineTemplate && !false) {
|
|
2014
|
-
// in non-inline mode, the `__isScriptSetup: true` flag is used by
|
|
2015
|
-
// componentPublicInstance proxy to allow properties that start with $ or _
|
|
2016
|
-
s.appendRight(endOffset, `\nconst __returned__ = ${returned}\n` +
|
|
2017
|
-
`Object.defineProperty(__returned__, '__isScriptSetup', { enumerable: false, value: true })\n` +
|
|
2018
|
-
`return __returned__` +
|
|
2019
|
-
`\n}\n\n`);
|
|
2020
|
-
}
|
|
2021
|
-
else {
|
|
2022
|
-
s.appendRight(endOffset, `\nreturn ${returned}\n}\n\n`);
|
|
2023
|
-
}
|
|
2024
|
-
// 11. finalize default export
|
|
2025
|
-
let runtimeOptions = ``;
|
|
2026
|
-
if (hasInlinedSsrRenderFn) {
|
|
2027
|
-
runtimeOptions += `\n __ssrInlineRender: true,`;
|
|
2028
|
-
}
|
|
2029
|
-
if (propsRuntimeDecl) {
|
|
2030
|
-
runtimeOptions += `\n props: ${scriptSetup.content
|
|
2031
|
-
.slice(propsRuntimeDecl.start, propsRuntimeDecl.end)
|
|
2032
|
-
.trim()},`;
|
|
2033
|
-
}
|
|
2034
|
-
else if (propsTypeDecl) {
|
|
2035
|
-
runtimeOptions += genRuntimeProps(typeDeclaredProps);
|
|
2036
|
-
}
|
|
2037
|
-
if (emitsRuntimeDecl) {
|
|
2038
|
-
runtimeOptions += `\n emits: ${scriptSetup.content
|
|
2039
|
-
.slice(emitsRuntimeDecl.start, emitsRuntimeDecl.end)
|
|
2040
|
-
.trim()},`;
|
|
2041
|
-
}
|
|
2042
|
-
else if (emitsTypeDecl) {
|
|
2043
|
-
runtimeOptions += genRuntimeEmits(typeDeclaredEmits);
|
|
2044
|
-
}
|
|
2045
|
-
// <script setup> components are closed by default. If the user did not
|
|
2046
|
-
// explicitly call `defineExpose`, call expose() with no args.
|
|
2047
|
-
const exposeCall = hasDefineExposeCall || options.inlineTemplate ? `` : ` expose()\n`;
|
|
2048
|
-
if (isTS) {
|
|
2049
|
-
// for TS, make sure the exported type is still valid type with
|
|
2050
|
-
// correct props information
|
|
2051
|
-
// we have to use object spread for types to be merged properly
|
|
2052
|
-
// user's TS setting should compile it down to proper targets
|
|
2053
|
-
const def = defaultExport ? `\n ...${defaultTempVar},` : ``;
|
|
2054
|
-
// wrap setup code with function.
|
|
2055
|
-
// export the content of <script setup> as a named export, `setup`.
|
|
2056
|
-
// this allows `import { setup } from '*.vue'` for testing purposes.
|
|
2057
|
-
if (defaultExport) {
|
|
2058
|
-
s.prependLeft(startOffset, `\n${hasAwait ? `async ` : ``}function setup(${args}) {\n`);
|
|
2059
|
-
s.append(`\nexport default /*#__PURE__*/${helper(`defineComponent`)}({${def}${runtimeOptions}\n setup})`);
|
|
2060
|
-
}
|
|
2061
|
-
else {
|
|
2062
|
-
s.prependLeft(startOffset, `\nexport default /*#__PURE__*/${helper(`defineComponent`)}({${def}${runtimeOptions}\n ${hasAwait ? `async ` : ``}setup(${args}) {\n${exposeCall}`);
|
|
2063
|
-
s.appendRight(endOffset, `})`);
|
|
2064
|
-
}
|
|
2065
|
-
}
|
|
2066
|
-
else {
|
|
2067
|
-
if (defaultExport) {
|
|
2068
|
-
// can't rely on spread operator in non ts mode
|
|
2069
|
-
s.prependLeft(startOffset, `\n${hasAwait ? `async ` : ``}function setup(${args}) {\n`);
|
|
2070
|
-
s.append(`\nexport default /*#__PURE__*/ Object.assign(${defaultTempVar}, {${runtimeOptions}\n setup\n})\n`);
|
|
2071
|
-
}
|
|
2072
|
-
else {
|
|
2073
|
-
s.prependLeft(startOffset, `\nexport default {${runtimeOptions}\n ` +
|
|
2074
|
-
`${hasAwait ? `async ` : ``}setup(${args}) {\n${exposeCall}`);
|
|
2075
|
-
s.appendRight(endOffset, `}`);
|
|
2076
|
-
}
|
|
2077
|
-
}
|
|
2078
|
-
// 12. finalize Vue helper imports
|
|
2079
|
-
if (helperImports.size > 0) {
|
|
2080
|
-
s.prepend(`import { ${[...helperImports]
|
|
2081
|
-
.map(h => `${h} as _${h}`)
|
|
2082
|
-
.join(', ')} } from 'vue'\n`);
|
|
2083
|
-
}
|
|
2084
|
-
s.trim();
|
|
2085
|
-
s.append(jsvCssToJs.compileCssToJs(sfc, options)); // QCode Added
|
|
2086
|
-
return Object.assign(Object.assign({}, scriptSetup), { bindings: bindingMetadata, content: s.toString(), map: s.generateMap({
|
|
2087
|
-
source: filename,
|
|
2088
|
-
hires: true,
|
|
2089
|
-
includeContent: true
|
|
2090
|
-
}), scriptAst: scriptAst === null || scriptAst === void 0 ? void 0 : scriptAst.body, scriptSetupAst: scriptSetupAst === null || scriptSetupAst === void 0 ? void 0 : scriptSetupAst.body });
|
|
2091
|
-
}
|
|
2092
|
-
function registerBinding(bindings, node, type) {
|
|
2093
|
-
bindings[node.name] = type;
|
|
2094
|
-
}
|
|
2095
|
-
function walkDeclaration(node, bindings, userImportAlias) {
|
|
2096
|
-
if (node.type === 'VariableDeclaration') {
|
|
2097
|
-
const isConst = node.kind === 'const';
|
|
2098
|
-
// export const foo = ...
|
|
2099
|
-
for (const { id, init } of node.declarations) {
|
|
2100
|
-
const isDefineCall = !!(isConst &&
|
|
2101
|
-
isCallOf(init, c => c === DEFINE_PROPS || c === DEFINE_EMITS || c === WITH_DEFAULTS));
|
|
2102
|
-
if (id.type === 'Identifier') {
|
|
2103
|
-
let bindingType;
|
|
2104
|
-
const userReactiveBinding = userImportAlias['reactive'] || 'reactive';
|
|
2105
|
-
if (isCallOf(init, userReactiveBinding)) {
|
|
2106
|
-
// treat reactive() calls as let since it's meant to be mutable
|
|
2107
|
-
bindingType = "setup-let" /* SETUP_LET */;
|
|
2108
|
-
}
|
|
2109
|
-
else if (
|
|
2110
|
-
// if a declaration is a const literal, we can mark it so that
|
|
2111
|
-
// the generated render fn code doesn't need to unref() it
|
|
2112
|
-
isDefineCall ||
|
|
2113
|
-
(isConst && canNeverBeRef(init, userReactiveBinding))) {
|
|
2114
|
-
bindingType = "setup-const" /* SETUP_CONST */;
|
|
2115
|
-
}
|
|
2116
|
-
else if (isConst) {
|
|
2117
|
-
if (isCallOf(init, userImportAlias['ref'] || 'ref')) {
|
|
2118
|
-
bindingType = "setup-ref" /* SETUP_REF */;
|
|
2119
|
-
}
|
|
2120
|
-
else {
|
|
2121
|
-
bindingType = "setup-maybe-ref" /* SETUP_MAYBE_REF */;
|
|
2122
|
-
}
|
|
2123
|
-
}
|
|
2124
|
-
else {
|
|
2125
|
-
bindingType = "setup-let" /* SETUP_LET */;
|
|
2126
|
-
}
|
|
2127
|
-
registerBinding(bindings, id, bindingType);
|
|
2128
|
-
}
|
|
2129
|
-
else if (id.type === 'ObjectPattern') {
|
|
2130
|
-
walkObjectPattern(id, bindings, isConst, isDefineCall);
|
|
2131
|
-
}
|
|
2132
|
-
else if (id.type === 'ArrayPattern') {
|
|
2133
|
-
walkArrayPattern(id, bindings, isConst, isDefineCall);
|
|
2134
|
-
}
|
|
2135
|
-
}
|
|
2136
|
-
}
|
|
2137
|
-
else if (node.type === 'FunctionDeclaration' ||
|
|
2138
|
-
node.type === 'ClassDeclaration') {
|
|
2139
|
-
// export function foo() {} / export class Foo {}
|
|
2140
|
-
// export declarations must be named.
|
|
2141
|
-
bindings[node.id.name] = "setup-const" /* SETUP_CONST */;
|
|
2142
|
-
}
|
|
2143
|
-
}
|
|
2144
|
-
function walkObjectPattern(node, bindings, isConst, isDefineCall = false) {
|
|
2145
|
-
for (const p of node.properties) {
|
|
2146
|
-
if (p.type === 'ObjectProperty') {
|
|
2147
|
-
// key can only be Identifier in ObjectPattern
|
|
2148
|
-
if (p.key.type === 'Identifier') {
|
|
2149
|
-
if (p.key === p.value) {
|
|
2150
|
-
// const { x } = ...
|
|
2151
|
-
const type = isDefineCall
|
|
2152
|
-
? "setup-const" /* SETUP_CONST */
|
|
2153
|
-
: isConst
|
|
2154
|
-
? "setup-maybe-ref" /* SETUP_MAYBE_REF */
|
|
2155
|
-
: "setup-let" /* SETUP_LET */;
|
|
2156
|
-
registerBinding(bindings, p.key, type);
|
|
2157
|
-
}
|
|
2158
|
-
else {
|
|
2159
|
-
walkPattern(p.value, bindings, isConst, isDefineCall);
|
|
2160
|
-
}
|
|
2161
|
-
}
|
|
2162
|
-
}
|
|
2163
|
-
else {
|
|
2164
|
-
// ...rest
|
|
2165
|
-
// argument can only be identifer when destructuring
|
|
2166
|
-
const type = isConst ? "setup-const" /* SETUP_CONST */ : "setup-let" /* SETUP_LET */;
|
|
2167
|
-
registerBinding(bindings, p.argument, type);
|
|
2168
|
-
}
|
|
2169
|
-
}
|
|
2170
|
-
}
|
|
2171
|
-
function walkArrayPattern(node, bindings, isConst, isDefineCall = false) {
|
|
2172
|
-
for (const e of node.elements) {
|
|
2173
|
-
e && walkPattern(e, bindings, isConst, isDefineCall);
|
|
2174
|
-
}
|
|
2175
|
-
}
|
|
2176
|
-
function walkPattern(node, bindings, isConst, isDefineCall = false) {
|
|
2177
|
-
if (node.type === 'Identifier') {
|
|
2178
|
-
const type = isDefineCall
|
|
2179
|
-
? "setup-const" /* SETUP_CONST */
|
|
2180
|
-
: isConst
|
|
2181
|
-
? "setup-maybe-ref" /* SETUP_MAYBE_REF */
|
|
2182
|
-
: "setup-let" /* SETUP_LET */;
|
|
2183
|
-
registerBinding(bindings, node, type);
|
|
2184
|
-
}
|
|
2185
|
-
else if (node.type === 'RestElement') {
|
|
2186
|
-
// argument can only be identifer when destructuring
|
|
2187
|
-
const type = isConst ? "setup-const" /* SETUP_CONST */ : "setup-let" /* SETUP_LET */;
|
|
2188
|
-
registerBinding(bindings, node.argument, type);
|
|
2189
|
-
}
|
|
2190
|
-
else if (node.type === 'ObjectPattern') {
|
|
2191
|
-
walkObjectPattern(node, bindings, isConst);
|
|
2192
|
-
}
|
|
2193
|
-
else if (node.type === 'ArrayPattern') {
|
|
2194
|
-
walkArrayPattern(node, bindings, isConst);
|
|
2195
|
-
}
|
|
2196
|
-
else if (node.type === 'AssignmentPattern') {
|
|
2197
|
-
if (node.left.type === 'Identifier') {
|
|
2198
|
-
const type = isDefineCall
|
|
2199
|
-
? "setup-const" /* SETUP_CONST */
|
|
2200
|
-
: isConst
|
|
2201
|
-
? "setup-maybe-ref" /* SETUP_MAYBE_REF */
|
|
2202
|
-
: "setup-let" /* SETUP_LET */;
|
|
2203
|
-
registerBinding(bindings, node.left, type);
|
|
2204
|
-
}
|
|
2205
|
-
else {
|
|
2206
|
-
walkPattern(node.left, bindings, isConst);
|
|
2207
|
-
}
|
|
2208
|
-
}
|
|
2209
|
-
}
|
|
2210
|
-
function recordType(node, declaredTypes) {
|
|
2211
|
-
if (node.type === 'TSInterfaceDeclaration') {
|
|
2212
|
-
declaredTypes[node.id.name] = [`Object`];
|
|
2213
|
-
}
|
|
2214
|
-
else if (node.type === 'TSTypeAliasDeclaration') {
|
|
2215
|
-
declaredTypes[node.id.name] = inferRuntimeType(node.typeAnnotation, declaredTypes);
|
|
2216
|
-
}
|
|
2217
|
-
else if (node.type === 'ExportNamedDeclaration' && node.declaration) {
|
|
2218
|
-
recordType(node.declaration, declaredTypes);
|
|
2219
|
-
}
|
|
2220
|
-
}
|
|
2221
|
-
function extractRuntimeProps(node, props, declaredTypes) {
|
|
2222
|
-
const members = node.type === 'TSTypeLiteral' ? node.members : node.body;
|
|
2223
|
-
for (const m of members) {
|
|
2224
|
-
if ((m.type === 'TSPropertySignature' || m.type === 'TSMethodSignature') &&
|
|
2225
|
-
m.key.type === 'Identifier') {
|
|
2226
|
-
let type;
|
|
2227
|
-
{
|
|
2228
|
-
if (m.type === 'TSMethodSignature') {
|
|
2229
|
-
type = ['Function'];
|
|
2230
|
-
}
|
|
2231
|
-
else if (m.typeAnnotation) {
|
|
2232
|
-
type = inferRuntimeType(m.typeAnnotation.typeAnnotation, declaredTypes);
|
|
2233
|
-
}
|
|
2234
|
-
}
|
|
2235
|
-
props[m.key.name] = {
|
|
2236
|
-
key: m.key.name,
|
|
2237
|
-
required: !m.optional,
|
|
2238
|
-
type: type || [`null`]
|
|
2239
|
-
};
|
|
2240
|
-
}
|
|
2241
|
-
}
|
|
2242
|
-
}
|
|
2243
|
-
function inferRuntimeType(node, declaredTypes) {
|
|
2244
|
-
switch (node.type) {
|
|
2245
|
-
case 'TSStringKeyword':
|
|
2246
|
-
return ['String'];
|
|
2247
|
-
case 'TSNumberKeyword':
|
|
2248
|
-
return ['Number'];
|
|
2249
|
-
case 'TSBooleanKeyword':
|
|
2250
|
-
return ['Boolean'];
|
|
2251
|
-
case 'TSObjectKeyword':
|
|
2252
|
-
return ['Object'];
|
|
2253
|
-
case 'TSTypeLiteral':
|
|
2254
|
-
// TODO (nice to have) generate runtime property validation
|
|
2255
|
-
return ['Object'];
|
|
2256
|
-
case 'TSFunctionType':
|
|
2257
|
-
return ['Function'];
|
|
2258
|
-
case 'TSArrayType':
|
|
2259
|
-
case 'TSTupleType':
|
|
2260
|
-
// TODO (nice to have) generate runtime element type/length checks
|
|
2261
|
-
return ['Array'];
|
|
2262
|
-
case 'TSLiteralType':
|
|
2263
|
-
switch (node.literal.type) {
|
|
2264
|
-
case 'StringLiteral':
|
|
2265
|
-
return ['String'];
|
|
2266
|
-
case 'BooleanLiteral':
|
|
2267
|
-
return ['Boolean'];
|
|
2268
|
-
case 'NumericLiteral':
|
|
2269
|
-
case 'BigIntLiteral':
|
|
2270
|
-
return ['Number'];
|
|
2271
|
-
default:
|
|
2272
|
-
return [`null`];
|
|
2273
|
-
}
|
|
2274
|
-
case 'TSTypeReference':
|
|
2275
|
-
if (node.typeName.type === 'Identifier') {
|
|
2276
|
-
if (declaredTypes[node.typeName.name]) {
|
|
2277
|
-
return declaredTypes[node.typeName.name];
|
|
2278
|
-
}
|
|
2279
|
-
switch (node.typeName.name) {
|
|
2280
|
-
case 'Array':
|
|
2281
|
-
case 'Function':
|
|
2282
|
-
case 'Object':
|
|
2283
|
-
case 'Set':
|
|
2284
|
-
case 'Map':
|
|
2285
|
-
case 'WeakSet':
|
|
2286
|
-
case 'WeakMap':
|
|
2287
|
-
return [node.typeName.name];
|
|
2288
|
-
case 'Record':
|
|
2289
|
-
case 'Partial':
|
|
2290
|
-
case 'Readonly':
|
|
2291
|
-
case 'Pick':
|
|
2292
|
-
case 'Omit':
|
|
2293
|
-
case 'Exclude':
|
|
2294
|
-
case 'Extract':
|
|
2295
|
-
case 'Required':
|
|
2296
|
-
case 'InstanceType':
|
|
2297
|
-
return ['Object'];
|
|
2298
|
-
}
|
|
2299
|
-
}
|
|
2300
|
-
return [`null`];
|
|
2301
|
-
case 'TSParenthesizedType':
|
|
2302
|
-
return inferRuntimeType(node.typeAnnotation, declaredTypes);
|
|
2303
|
-
case 'TSUnionType':
|
|
2304
|
-
return [
|
|
2305
|
-
...new Set([].concat(...node.types.map(t => inferRuntimeType(t, declaredTypes))))
|
|
2306
|
-
];
|
|
2307
|
-
case 'TSIntersectionType':
|
|
2308
|
-
return ['Object'];
|
|
2309
|
-
default:
|
|
2310
|
-
return [`null`]; // no runtime check
|
|
2311
|
-
}
|
|
2312
|
-
}
|
|
2313
|
-
function toRuntimeTypeString(types) {
|
|
2314
|
-
return types.length > 1 ? `[${types.join(', ')}]` : types[0];
|
|
2315
|
-
}
|
|
2316
|
-
function extractRuntimeEmits(node, emits) {
|
|
2317
|
-
if (node.type === 'TSTypeLiteral' || node.type === 'TSInterfaceBody') {
|
|
2318
|
-
const members = node.type === 'TSTypeLiteral' ? node.members : node.body;
|
|
2319
|
-
for (let t of members) {
|
|
2320
|
-
if (t.type === 'TSCallSignatureDeclaration') {
|
|
2321
|
-
extractEventNames(t.parameters[0], emits);
|
|
2322
|
-
}
|
|
2323
|
-
}
|
|
2324
|
-
return;
|
|
2325
|
-
}
|
|
2326
|
-
else {
|
|
2327
|
-
extractEventNames(node.parameters[0], emits);
|
|
2328
|
-
}
|
|
2329
|
-
}
|
|
2330
|
-
function extractEventNames(eventName, emits) {
|
|
2331
|
-
if (eventName.type === 'Identifier' &&
|
|
2332
|
-
eventName.typeAnnotation &&
|
|
2333
|
-
eventName.typeAnnotation.type === 'TSTypeAnnotation') {
|
|
2334
|
-
const typeNode = eventName.typeAnnotation.typeAnnotation;
|
|
2335
|
-
if (typeNode.type === 'TSLiteralType') {
|
|
2336
|
-
if (typeNode.literal.type !== 'UnaryExpression') {
|
|
2337
|
-
emits.add(String(typeNode.literal.value));
|
|
2338
|
-
}
|
|
2339
|
-
}
|
|
2340
|
-
else if (typeNode.type === 'TSUnionType') {
|
|
2341
|
-
for (const t of typeNode.types) {
|
|
2342
|
-
if (t.type === 'TSLiteralType' &&
|
|
2343
|
-
t.literal.type !== 'UnaryExpression') {
|
|
2344
|
-
emits.add(String(t.literal.value));
|
|
2345
|
-
}
|
|
2346
|
-
}
|
|
2347
|
-
}
|
|
2348
|
-
}
|
|
2349
|
-
}
|
|
2350
|
-
function genRuntimeEmits(emits) {
|
|
2351
|
-
return emits.size
|
|
2352
|
-
? `\n emits: [${Array.from(emits)
|
|
2353
|
-
.map(p => JSON.stringify(p))
|
|
2354
|
-
.join(', ')}],`
|
|
2355
|
-
: ``;
|
|
2356
|
-
}
|
|
2357
|
-
function isCallOf(node, test) {
|
|
2358
|
-
return !!(node &&
|
|
2359
|
-
node.type === 'CallExpression' &&
|
|
2360
|
-
node.callee.type === 'Identifier' &&
|
|
2361
|
-
(typeof test === 'string'
|
|
2362
|
-
? node.callee.name === test
|
|
2363
|
-
: test(node.callee.name)));
|
|
2364
|
-
}
|
|
2365
|
-
function canNeverBeRef(node, userReactiveImport) {
|
|
2366
|
-
if (isCallOf(node, userReactiveImport)) {
|
|
2367
|
-
return true;
|
|
2368
|
-
}
|
|
2369
|
-
switch (node.type) {
|
|
2370
|
-
case 'UnaryExpression':
|
|
2371
|
-
case 'BinaryExpression':
|
|
2372
|
-
case 'ArrayExpression':
|
|
2373
|
-
case 'ObjectExpression':
|
|
2374
|
-
case 'FunctionExpression':
|
|
2375
|
-
case 'ArrowFunctionExpression':
|
|
2376
|
-
case 'UpdateExpression':
|
|
2377
|
-
case 'ClassExpression':
|
|
2378
|
-
case 'TaggedTemplateExpression':
|
|
2379
|
-
return true;
|
|
2380
|
-
case 'SequenceExpression':
|
|
2381
|
-
return canNeverBeRef(node.expressions[node.expressions.length - 1], userReactiveImport);
|
|
2382
|
-
default:
|
|
2383
|
-
if (node.type.endsWith('Literal')) {
|
|
2384
|
-
return true;
|
|
2385
|
-
}
|
|
2386
|
-
return false;
|
|
2387
|
-
}
|
|
2388
|
-
}
|
|
2389
|
-
/**
|
|
2390
|
-
* Analyze bindings in normal `<script>`
|
|
2391
|
-
* Note that `compileScriptSetup` already analyzes bindings as part of its
|
|
2392
|
-
* compilation process so this should only be used on single `<script>` SFCs.
|
|
2393
|
-
*/
|
|
2394
|
-
function analyzeScriptBindings(ast) {
|
|
2395
|
-
for (const node of ast) {
|
|
2396
|
-
if (node.type === 'ExportDefaultDeclaration' &&
|
|
2397
|
-
node.declaration.type === 'ObjectExpression') {
|
|
2398
|
-
return analyzeBindingsFromOptions(node.declaration);
|
|
2399
|
-
}
|
|
2400
|
-
}
|
|
2401
|
-
return {};
|
|
2402
|
-
}
|
|
2403
|
-
function analyzeBindingsFromOptions(node) {
|
|
2404
|
-
const bindings = {};
|
|
2405
|
-
// #3270, #3275
|
|
2406
|
-
// mark non-script-setup so we don't resolve components/directives from these
|
|
2407
|
-
Object.defineProperty(bindings, '__isScriptSetup', {
|
|
2408
|
-
enumerable: false,
|
|
2409
|
-
value: false
|
|
2410
|
-
});
|
|
2411
|
-
for (const property of node.properties) {
|
|
2412
|
-
if (property.type === 'ObjectProperty' &&
|
|
2413
|
-
!property.computed &&
|
|
2414
|
-
property.key.type === 'Identifier') {
|
|
2415
|
-
// props
|
|
2416
|
-
if (property.key.name === 'props') {
|
|
2417
|
-
// props: ['foo']
|
|
2418
|
-
// props: { foo: ... }
|
|
2419
|
-
for (const key of getObjectOrArrayExpressionKeys(property.value)) {
|
|
2420
|
-
bindings[key] = "props" /* PROPS */;
|
|
2421
|
-
}
|
|
2422
|
-
}
|
|
2423
|
-
// inject
|
|
2424
|
-
else if (property.key.name === 'inject') {
|
|
2425
|
-
// inject: ['foo']
|
|
2426
|
-
// inject: { foo: {} }
|
|
2427
|
-
for (const key of getObjectOrArrayExpressionKeys(property.value)) {
|
|
2428
|
-
bindings[key] = "options" /* OPTIONS */;
|
|
2429
|
-
}
|
|
2430
|
-
}
|
|
2431
|
-
// computed & methods
|
|
2432
|
-
else if (property.value.type === 'ObjectExpression' &&
|
|
2433
|
-
(property.key.name === 'computed' || property.key.name === 'methods')) {
|
|
2434
|
-
// methods: { foo() {} }
|
|
2435
|
-
// computed: { foo() {} }
|
|
2436
|
-
for (const key of getObjectExpressionKeys(property.value)) {
|
|
2437
|
-
bindings[key] = "options" /* OPTIONS */;
|
|
2438
|
-
}
|
|
2439
|
-
}
|
|
2440
|
-
}
|
|
2441
|
-
// setup & data
|
|
2442
|
-
else if (property.type === 'ObjectMethod' &&
|
|
2443
|
-
property.key.type === 'Identifier' &&
|
|
2444
|
-
(property.key.name === 'setup' || property.key.name === 'data')) {
|
|
2445
|
-
for (const bodyItem of property.body.body) {
|
|
2446
|
-
// setup() {
|
|
2447
|
-
// return {
|
|
2448
|
-
// foo: null
|
|
2449
|
-
// }
|
|
2450
|
-
// }
|
|
2451
|
-
if (bodyItem.type === 'ReturnStatement' &&
|
|
2452
|
-
bodyItem.argument &&
|
|
2453
|
-
bodyItem.argument.type === 'ObjectExpression') {
|
|
2454
|
-
for (const key of getObjectExpressionKeys(bodyItem.argument)) {
|
|
2455
|
-
bindings[key] =
|
|
2456
|
-
property.key.name === 'setup'
|
|
2457
|
-
? "setup-maybe-ref" /* SETUP_MAYBE_REF */
|
|
2458
|
-
: "data" /* DATA */;
|
|
2459
|
-
}
|
|
2460
|
-
}
|
|
2461
|
-
}
|
|
2462
|
-
}
|
|
2463
|
-
}
|
|
2464
|
-
return bindings;
|
|
2465
|
-
}
|
|
2466
|
-
function getObjectExpressionKeys(node) {
|
|
2467
|
-
const keys = [];
|
|
2468
|
-
for (const prop of node.properties) {
|
|
2469
|
-
if ((prop.type === 'ObjectProperty' || prop.type === 'ObjectMethod') &&
|
|
2470
|
-
!prop.computed) {
|
|
2471
|
-
if (prop.key.type === 'Identifier') {
|
|
2472
|
-
keys.push(prop.key.name);
|
|
2473
|
-
}
|
|
2474
|
-
else if (prop.key.type === 'StringLiteral') {
|
|
2475
|
-
keys.push(prop.key.value);
|
|
2476
|
-
}
|
|
2477
|
-
}
|
|
2478
|
-
}
|
|
2479
|
-
return keys;
|
|
2480
|
-
}
|
|
2481
|
-
function getArrayExpressionKeys(node) {
|
|
2482
|
-
const keys = [];
|
|
2483
|
-
for (const element of node.elements) {
|
|
2484
|
-
if (element && element.type === 'StringLiteral') {
|
|
2485
|
-
keys.push(element.value);
|
|
2486
|
-
}
|
|
2487
|
-
}
|
|
2488
|
-
return keys;
|
|
2489
|
-
}
|
|
2490
|
-
function getObjectOrArrayExpressionKeys(value) {
|
|
2491
|
-
if (value.type === 'ArrayExpression') {
|
|
2492
|
-
return getArrayExpressionKeys(value);
|
|
2493
|
-
}
|
|
2494
|
-
if (value.type === 'ObjectExpression') {
|
|
2495
|
-
return getObjectExpressionKeys(value);
|
|
2496
|
-
}
|
|
2497
|
-
return [];
|
|
2498
|
-
}
|
|
2499
|
-
const templateUsageCheckCache = createCache();
|
|
2500
|
-
function resolveTemplateUsageCheckString(sfc) {
|
|
2501
|
-
const { content, ast } = sfc.template;
|
|
2502
|
-
const cached = templateUsageCheckCache.get(content);
|
|
2503
|
-
if (cached) {
|
|
2504
|
-
return cached;
|
|
2505
|
-
}
|
|
2506
|
-
let code = '';
|
|
2507
|
-
CompilerDOM.transform(CompilerDOM.createRoot([ast]), {
|
|
2508
|
-
nodeTransforms: [
|
|
2509
|
-
node => {
|
|
2510
|
-
if (node.type === 1 /* ELEMENT */) {
|
|
2511
|
-
if (!CompilerDOM.parserOptions.isNativeTag(node.tag) &&
|
|
2512
|
-
!CompilerDOM.parserOptions.isBuiltInComponent(node.tag)) {
|
|
2513
|
-
code += `,${shared.camelize(node.tag)},${shared.capitalize(shared.camelize(node.tag))}`;
|
|
2514
|
-
}
|
|
2515
|
-
for (let i = 0; i < node.props.length; i++) {
|
|
2516
|
-
const prop = node.props[i];
|
|
2517
|
-
if (prop.type === 7 /* DIRECTIVE */) {
|
|
2518
|
-
if (!isBuiltInDir(prop.name)) {
|
|
2519
|
-
code += `,v${shared.capitalize(shared.camelize(prop.name))}`;
|
|
2520
|
-
}
|
|
2521
|
-
if (prop.exp) {
|
|
2522
|
-
code += `,${stripStrings(prop.exp.content)}`;
|
|
2523
|
-
}
|
|
2524
|
-
}
|
|
2525
|
-
}
|
|
2526
|
-
}
|
|
2527
|
-
else if (node.type === 5 /* INTERPOLATION */) {
|
|
2528
|
-
code += `,${stripStrings(node.content.content)}`;
|
|
2529
|
-
}
|
|
2530
|
-
}
|
|
2531
|
-
]
|
|
2532
|
-
});
|
|
2533
|
-
code += ';';
|
|
2534
|
-
templateUsageCheckCache.set(content, code);
|
|
2535
|
-
return code;
|
|
2536
|
-
}
|
|
2537
|
-
function stripStrings(exp) {
|
|
2538
|
-
return exp
|
|
2539
|
-
.replace(/'[^']+'|"[^"]+"/g, '')
|
|
2540
|
-
.replace(/`[^`]+`/g, stripTemplateString);
|
|
2541
|
-
}
|
|
2542
|
-
function stripTemplateString(str) {
|
|
2543
|
-
const interpMatch = str.match(/\${[^}]+}/g);
|
|
2544
|
-
if (interpMatch) {
|
|
2545
|
-
return interpMatch.map(m => m.slice(2, -1)).join(',');
|
|
2546
|
-
}
|
|
2547
|
-
return '';
|
|
2548
|
-
}
|
|
2549
|
-
|
|
2550
|
-
exports.extractIdentifiers = compilerCore.extractIdentifiers;
|
|
2551
|
-
exports.generateCodeFrame = compilerCore.generateCodeFrame;
|
|
2552
|
-
exports.isInDestructureAssignment = compilerCore.isInDestructureAssignment;
|
|
2553
|
-
exports.isStaticProperty = compilerCore.isStaticProperty;
|
|
2554
|
-
exports.walkIdentifiers = compilerCore.walkIdentifiers;
|
|
2555
|
-
exports.MagicString = MagicString__default;
|
|
2556
|
-
exports.babelParse = parser.parse;
|
|
2557
|
-
exports.walk = estreeWalker.walk;
|
|
2558
|
-
exports.shouldTransformRef = refTransform.shouldTransform;
|
|
2559
|
-
exports.transformRef = refTransform.transform;
|
|
2560
|
-
exports.transformRefAST = refTransform.transformAST;
|
|
2561
|
-
exports.compileScript = compileScript;
|
|
2562
|
-
exports.compileStyle = compileStyle;
|
|
2563
|
-
exports.compileStyleAsync = compileStyleAsync;
|
|
2564
|
-
exports.compileTemplate = compileTemplate;
|
|
2565
|
-
exports.parse = parse;
|
|
2566
|
-
exports.rewriteDefault = rewriteDefault;
|