@mulanjs/mulanjs 1.0.1-dev.20260227091247 → 1.0.1-dev.20260227172006
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/compiler/ast-parser.d.ts +48 -0
- package/dist/compiler/ast-parser.js +266 -0
- package/dist/compiler/compiler.d.ts +9 -0
- package/dist/compiler/compiler.js +46 -3
- package/dist/compiler/dom-compiler.d.ts +7 -0
- package/dist/compiler/dom-compiler.js +95 -159
- package/dist/compiler/script-compiler.d.ts +11 -0
- package/dist/compiler/script-compiler.js +108 -116
- package/dist/compiler/sfc-parser.d.ts +21 -0
- package/dist/compiler/ssr-compiler.d.ts +7 -0
- package/dist/compiler/ssr-compiler.js +142 -0
- package/dist/compiler/style-compiler.d.ts +8 -0
- package/dist/compiler/template-compiler.d.ts +8 -0
- package/dist/compiler/template-compiler.js +11 -238
- package/dist/components/bloch-sphere.js +9 -3
- package/dist/components/infinity-list.js +7 -1
- package/dist/core/component.js +66 -15
- package/dist/core/hooks.js +53 -29
- package/dist/core/quantum.js +30 -17
- package/dist/core/query.js +11 -6
- package/dist/core/reactive.js +88 -7
- package/dist/core/renderer.js +9 -8
- package/dist/core/ssr.js +50 -0
- package/dist/core/surge.js +7 -2
- package/dist/core/vault.js +9 -5
- package/dist/index.js +63 -27
- package/dist/mulan.esm.js +1933 -1626
- package/dist/mulan.esm.js.map +1 -1
- package/dist/mulan.js +1890 -1590
- package/dist/mulan.js.map +1 -1
- package/dist/router/index.js +17 -10
- package/dist/security/sanitizer.js +5 -1
- package/dist/store/index.js +9 -5
- package/dist/types/ast-parser.d.ts +48 -0
- package/dist/types/compiler/ast-parser.d.ts +48 -0
- package/dist/types/compiler/compiler.d.ts +1 -0
- package/dist/types/compiler/ssr-compiler.d.ts +7 -0
- package/dist/types/compiler.d.ts +1 -0
- package/dist/types/components/bloch-sphere.d.ts +3 -1
- package/dist/types/components/infinity-list.d.ts +3 -1
- package/dist/types/core/component.d.ts +14 -0
- package/dist/types/core/reactive.d.ts +5 -1
- package/dist/types/core/renderer.d.ts +0 -1
- package/dist/types/core/ssr.d.ts +9 -0
- package/dist/types/index.d.ts +1 -0
- package/dist/types/ssr-compiler.d.ts +7 -0
- package/package.json +1 -1
- package/src/compiler/ast-parser.ts +310 -0
- package/src/compiler/compiler.ts +47 -2
- package/src/compiler/dom-compiler.ts +105 -167
- package/src/compiler/script-compiler.ts +117 -126
- package/src/compiler/ssr-compiler.ts +157 -0
- package/src/compiler/template-compiler.ts +11 -283
- package/src/loader/index.js +12 -19
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
export type NodeType = 'Element' | 'Text' | 'Interpolation';
|
|
2
|
+
export type Node = ElementNode | TextNode | InterpolationNode;
|
|
3
|
+
export interface BaseNode {
|
|
4
|
+
type: NodeType;
|
|
5
|
+
isStatic?: boolean;
|
|
6
|
+
}
|
|
7
|
+
export interface ElementNode extends BaseNode {
|
|
8
|
+
type: 'Element';
|
|
9
|
+
tag: string;
|
|
10
|
+
props: Record<string, string>;
|
|
11
|
+
children: Node[];
|
|
12
|
+
directives: {
|
|
13
|
+
vFor?: {
|
|
14
|
+
item: string;
|
|
15
|
+
list: string;
|
|
16
|
+
};
|
|
17
|
+
vIf?: string;
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
export interface TextNode extends BaseNode {
|
|
21
|
+
type: 'Text';
|
|
22
|
+
content: string;
|
|
23
|
+
}
|
|
24
|
+
export interface InterpolationNode extends BaseNode {
|
|
25
|
+
type: 'Interpolation';
|
|
26
|
+
content: string;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Decodes standard HTML entities.
|
|
30
|
+
*/
|
|
31
|
+
export declare function decodeEntities(str: string): string;
|
|
32
|
+
/**
|
|
33
|
+
* Unified MulanJS Template Parser
|
|
34
|
+
* Handles HTML tags, {{ }} interpolation, and is robust against raw < symbols in text.
|
|
35
|
+
*/
|
|
36
|
+
export declare function parse(template: string, errors: string[]): ElementNode;
|
|
37
|
+
export declare function markStatic(node: Node): boolean;
|
|
38
|
+
export declare function parseTag(content: string): {
|
|
39
|
+
tag: string;
|
|
40
|
+
props: Record<string, string>;
|
|
41
|
+
directives: {
|
|
42
|
+
vFor?: {
|
|
43
|
+
item: string;
|
|
44
|
+
list: string;
|
|
45
|
+
};
|
|
46
|
+
vIf?: string;
|
|
47
|
+
};
|
|
48
|
+
};
|
|
@@ -0,0 +1,266 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// --- AST Definitions ---
|
|
3
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
|
+
exports.parseTag = exports.markStatic = exports.parse = exports.decodeEntities = void 0;
|
|
5
|
+
/**
|
|
6
|
+
* Decodes standard HTML entities.
|
|
7
|
+
*/
|
|
8
|
+
function decodeEntities(str) {
|
|
9
|
+
return str
|
|
10
|
+
.replace(/</g, '<')
|
|
11
|
+
.replace(/>/g, '>')
|
|
12
|
+
.replace(/&/g, '&')
|
|
13
|
+
.replace(/"/g, '"')
|
|
14
|
+
.replace(/'/g, "'")
|
|
15
|
+
.replace(/ /g, '\u00A0');
|
|
16
|
+
}
|
|
17
|
+
exports.decodeEntities = decodeEntities;
|
|
18
|
+
/**
|
|
19
|
+
* Unified MulanJS Template Parser
|
|
20
|
+
* Handles HTML tags, {{ }} interpolation, and is robust against raw < symbols in text.
|
|
21
|
+
*/
|
|
22
|
+
function parse(template, errors) {
|
|
23
|
+
const root = {
|
|
24
|
+
type: 'Element',
|
|
25
|
+
tag: 'fragment',
|
|
26
|
+
props: {},
|
|
27
|
+
children: [],
|
|
28
|
+
directives: {}
|
|
29
|
+
};
|
|
30
|
+
const stack = [root];
|
|
31
|
+
let cursor = 0;
|
|
32
|
+
while (cursor < template.length) {
|
|
33
|
+
const char = template[cursor];
|
|
34
|
+
// 1. Comments
|
|
35
|
+
if (template.startsWith('<!--', cursor)) {
|
|
36
|
+
const end = template.indexOf('-->', cursor);
|
|
37
|
+
if (end === -1) {
|
|
38
|
+
errors.push('Unclosed HTML comment.');
|
|
39
|
+
break;
|
|
40
|
+
}
|
|
41
|
+
cursor = end + 3;
|
|
42
|
+
}
|
|
43
|
+
// 2. Tags (with lookahead check for robustness)
|
|
44
|
+
else if (char === '<' && /[\/a-zA-Z!]/.test(template[cursor + 1])) {
|
|
45
|
+
if (template[cursor + 1] === '/') {
|
|
46
|
+
// Closing Tag
|
|
47
|
+
const end = template.indexOf('>', cursor);
|
|
48
|
+
if (end === -1) {
|
|
49
|
+
errors.push('Unclosed closing tag.');
|
|
50
|
+
break;
|
|
51
|
+
}
|
|
52
|
+
const tagName = template.slice(cursor + 2, end).trim();
|
|
53
|
+
// Find matching element in stack to pop
|
|
54
|
+
if (stack.length > 1 && stack[stack.length - 1].tag === tagName) {
|
|
55
|
+
stack.pop();
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
errors.push(`Mismatched closing tag </${tagName}>.`);
|
|
59
|
+
}
|
|
60
|
+
cursor = end + 1;
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
// Opening Tag
|
|
64
|
+
const end = template.indexOf('>', cursor);
|
|
65
|
+
if (end === -1) {
|
|
66
|
+
errors.push('Unclosed opening tag.');
|
|
67
|
+
break;
|
|
68
|
+
}
|
|
69
|
+
const tagContent = template.slice(cursor + 1, end);
|
|
70
|
+
const { tag, props, directives } = parseTag(tagContent);
|
|
71
|
+
const isSelfClosing = tagContent.endsWith('/') || ['img', 'br', 'input', 'hr', 'link', 'meta'].includes(tag.toLowerCase());
|
|
72
|
+
const element = { type: 'Element', tag, props, children: [], directives };
|
|
73
|
+
stack[stack.length - 1].children.push(element);
|
|
74
|
+
if (!isSelfClosing) {
|
|
75
|
+
stack.push(element);
|
|
76
|
+
}
|
|
77
|
+
cursor = end + 1;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
// 3. Interpolation {{ }}
|
|
81
|
+
else if (template.startsWith('{{', cursor)) {
|
|
82
|
+
const end = template.indexOf('}}', cursor);
|
|
83
|
+
if (end === -1) {
|
|
84
|
+
errors.push('Unclosed interpolation {{ }}.');
|
|
85
|
+
break;
|
|
86
|
+
}
|
|
87
|
+
const content = template.slice(cursor + 2, end).trim();
|
|
88
|
+
stack[stack.length - 1].children.push({ type: 'Interpolation', content });
|
|
89
|
+
cursor = end + 2;
|
|
90
|
+
}
|
|
91
|
+
// 4. Native Template Literals ${ } (Protection)
|
|
92
|
+
else if (template.startsWith('${', cursor)) {
|
|
93
|
+
// Find end of ${ } while respecting nested braces
|
|
94
|
+
let innerCursor = cursor + 2;
|
|
95
|
+
let depth = 1;
|
|
96
|
+
while (innerCursor < template.length && depth > 0) {
|
|
97
|
+
if (template[innerCursor] === '{')
|
|
98
|
+
depth++;
|
|
99
|
+
if (template[innerCursor] === '}')
|
|
100
|
+
depth--;
|
|
101
|
+
innerCursor++;
|
|
102
|
+
}
|
|
103
|
+
const content = template.slice(cursor, innerCursor);
|
|
104
|
+
// Treat as text but this block is now "atomic" and won't be split by < checks
|
|
105
|
+
const lastChild = stack[stack.length - 1].children[stack[stack.length - 1].children.length - 1];
|
|
106
|
+
if (lastChild && lastChild.type === 'Text') {
|
|
107
|
+
lastChild.content += content;
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
stack[stack.length - 1].children.push({ type: 'Text', content });
|
|
111
|
+
}
|
|
112
|
+
cursor = innerCursor;
|
|
113
|
+
}
|
|
114
|
+
// 5. Text Nodes
|
|
115
|
+
else {
|
|
116
|
+
let nextTag = template.indexOf('<', cursor);
|
|
117
|
+
let nextInterp = template.indexOf('{{', cursor);
|
|
118
|
+
let nextNative = template.indexOf('${', cursor);
|
|
119
|
+
let end = template.length;
|
|
120
|
+
// Heuristic for nextTag: it must look like a tag start
|
|
121
|
+
while (nextTag !== -1) {
|
|
122
|
+
if (/[\/a-zA-Z!]/.test(template[nextTag + 1])) {
|
|
123
|
+
break;
|
|
124
|
+
}
|
|
125
|
+
nextTag = template.indexOf('<', nextTag + 1);
|
|
126
|
+
}
|
|
127
|
+
if (nextTag !== -1 && nextTag < end)
|
|
128
|
+
end = nextTag;
|
|
129
|
+
if (nextInterp !== -1 && nextInterp < end)
|
|
130
|
+
end = nextInterp;
|
|
131
|
+
if (nextNative !== -1 && nextNative < end)
|
|
132
|
+
end = nextNative;
|
|
133
|
+
const rawContent = template.slice(cursor, end);
|
|
134
|
+
const content = decodeEntities(rawContent);
|
|
135
|
+
if (content) {
|
|
136
|
+
const lastChild = stack[stack.length - 1].children[stack[stack.length - 1].children.length - 1];
|
|
137
|
+
if (lastChild && lastChild.type === 'Text') {
|
|
138
|
+
lastChild.content += content;
|
|
139
|
+
}
|
|
140
|
+
else {
|
|
141
|
+
stack[stack.length - 1].children.push({ type: 'Text', content });
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
cursor = end;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
markStatic(root);
|
|
148
|
+
return root;
|
|
149
|
+
}
|
|
150
|
+
exports.parse = parse;
|
|
151
|
+
function markStatic(node) {
|
|
152
|
+
if (node.type === 'Interpolation') {
|
|
153
|
+
node.isStatic = false;
|
|
154
|
+
return false;
|
|
155
|
+
}
|
|
156
|
+
if (node.type === 'Text') {
|
|
157
|
+
const text = node;
|
|
158
|
+
node.isStatic = !text.content.includes('${');
|
|
159
|
+
return node.isStatic;
|
|
160
|
+
}
|
|
161
|
+
if (node.type === 'Element') {
|
|
162
|
+
const element = node;
|
|
163
|
+
let isStatic = true;
|
|
164
|
+
// 1. Directives make it dynamic
|
|
165
|
+
if (element.directives.vIf || element.directives.vFor) {
|
|
166
|
+
isStatic = false;
|
|
167
|
+
}
|
|
168
|
+
// 2. Dynamic properties or event listeners make it dynamic
|
|
169
|
+
if (isStatic) {
|
|
170
|
+
for (const key in element.props) {
|
|
171
|
+
const val = element.props[key];
|
|
172
|
+
if (key.startsWith('@') || key.startsWith('v-on:') || key.startsWith('on') || key.startsWith(':') || key.startsWith('.')) {
|
|
173
|
+
isStatic = false;
|
|
174
|
+
break;
|
|
175
|
+
}
|
|
176
|
+
if (val.includes('${')) {
|
|
177
|
+
isStatic = false;
|
|
178
|
+
break;
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
// 3. Check all children. Every child must be static for the parent to be static.
|
|
183
|
+
// We still need to call markStatic on ALL children, so don't short-circuit the loop early.
|
|
184
|
+
for (const child of element.children) {
|
|
185
|
+
const childStatic = markStatic(child);
|
|
186
|
+
if (!childStatic) {
|
|
187
|
+
isStatic = false;
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
element.isStatic = isStatic;
|
|
191
|
+
return isStatic;
|
|
192
|
+
}
|
|
193
|
+
return false;
|
|
194
|
+
}
|
|
195
|
+
exports.markStatic = markStatic;
|
|
196
|
+
function parseTag(content) {
|
|
197
|
+
// 1. Extract tag name (first word, ignoring leading whitespace)
|
|
198
|
+
const tagMatch = content.trim().match(/^([a-zA-Z0-9:-]+)/);
|
|
199
|
+
const tag = tagMatch ? tagMatch[1] : '';
|
|
200
|
+
const props = {};
|
|
201
|
+
const directives = {};
|
|
202
|
+
// 2. Remove tag name from content to parse attributes
|
|
203
|
+
const attrStr = content.trim().slice(tag.length).trim();
|
|
204
|
+
let i = 0;
|
|
205
|
+
while (i < attrStr.length) {
|
|
206
|
+
if (/\s/.test(attrStr[i])) {
|
|
207
|
+
i++;
|
|
208
|
+
continue;
|
|
209
|
+
}
|
|
210
|
+
const keyStart = i;
|
|
211
|
+
while (i < attrStr.length && !/\s|=/.test(attrStr[i])) {
|
|
212
|
+
i++;
|
|
213
|
+
}
|
|
214
|
+
const key = attrStr.slice(keyStart, i);
|
|
215
|
+
let value = 'true';
|
|
216
|
+
let peek = i;
|
|
217
|
+
while (peek < attrStr.length && /\s/.test(attrStr[peek]))
|
|
218
|
+
peek++;
|
|
219
|
+
if (peek < attrStr.length && attrStr[peek] === '=') {
|
|
220
|
+
i = peek + 1;
|
|
221
|
+
while (i < attrStr.length && /\s/.test(attrStr[i]))
|
|
222
|
+
i++;
|
|
223
|
+
if (i < attrStr.length && (attrStr[i] === '"' || attrStr[i] === "'")) {
|
|
224
|
+
const quote = attrStr[i];
|
|
225
|
+
i++;
|
|
226
|
+
const valStart = i;
|
|
227
|
+
while (i < attrStr.length && attrStr[i] !== quote) {
|
|
228
|
+
if (attrStr[i] === '\\' && attrStr[i + 1] === quote) {
|
|
229
|
+
i += 2;
|
|
230
|
+
}
|
|
231
|
+
else {
|
|
232
|
+
i++;
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
value = attrStr.slice(valStart, i);
|
|
236
|
+
i++;
|
|
237
|
+
}
|
|
238
|
+
else {
|
|
239
|
+
const valStart = i;
|
|
240
|
+
while (i < attrStr.length && !/\s/.test(attrStr[i])) {
|
|
241
|
+
i++;
|
|
242
|
+
}
|
|
243
|
+
value = attrStr.slice(valStart, i);
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
if (key === 'v-if' || key === 'mu-if') {
|
|
247
|
+
directives.vIf = value;
|
|
248
|
+
}
|
|
249
|
+
else if (key === 'v-for' || key === 'mu-for') {
|
|
250
|
+
const parts = value.split(' in ');
|
|
251
|
+
if (parts.length < 2) {
|
|
252
|
+
directives.vFor = { item: '_item', list: '[]' };
|
|
253
|
+
}
|
|
254
|
+
else {
|
|
255
|
+
const item = parts[0];
|
|
256
|
+
const list = parts.slice(1).join(' in ');
|
|
257
|
+
directives.vFor = { item: item.trim(), list: list.trim() };
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
else if (key) {
|
|
261
|
+
props[key] = value;
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
return { tag, props, directives };
|
|
265
|
+
}
|
|
266
|
+
exports.parseTag = parseTag;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { CompilerOptions } from './script-compiler';
|
|
2
|
+
export interface CompileResult {
|
|
3
|
+
code: string;
|
|
4
|
+
css: string;
|
|
5
|
+
errors: string[];
|
|
6
|
+
map?: string;
|
|
7
|
+
}
|
|
8
|
+
export declare function compileSFC(source: string, filename: string, options?: CompilerOptions): Promise<CompileResult>;
|
|
9
|
+
export declare function compileSFCForSSR(source: string, filename: string, options?: CompilerOptions): Promise<CompileResult>;
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.compileSFC = void 0;
|
|
3
|
+
exports.compileSFCForSSR = exports.compileSFC = void 0;
|
|
4
4
|
const sfc_parser_1 = require("./sfc-parser");
|
|
5
5
|
const script_compiler_1 = require("./script-compiler");
|
|
6
6
|
const dom_compiler_1 = require("./dom-compiler");
|
|
7
7
|
const style_compiler_1 = require("./style-compiler");
|
|
8
|
+
const ssr_compiler_1 = require("./ssr-compiler");
|
|
8
9
|
const source_map_1 = require("source-map");
|
|
9
10
|
async function compileSFC(source, filename, options) {
|
|
10
11
|
// 1. Parse
|
|
@@ -17,9 +18,12 @@ async function compileSFC(source, filename, options) {
|
|
|
17
18
|
if (!scriptCode.includes('const __component__ =')) {
|
|
18
19
|
scriptCode = scriptCode.replace(/export\s+default/, 'const __component__ =');
|
|
19
20
|
}
|
|
21
|
+
if (!scriptCode.includes('const __component__ =')) {
|
|
22
|
+
scriptCode = scriptCode.replace('exports.default =', 'const __component__ =');
|
|
23
|
+
}
|
|
20
24
|
// 3. Style
|
|
21
25
|
const styleResult = (0, style_compiler_1.compileStyle)(descriptor, filename, options);
|
|
22
|
-
// 4. Template (Use the new No-VDOM compiler!)
|
|
26
|
+
// 4. Template (Use the new unified No-VDOM compiler!)
|
|
23
27
|
const templateResult = (0, dom_compiler_1.compileToDOM)(descriptor, scriptResult, styleResult.scopedId);
|
|
24
28
|
// Calculate offsets for source map merging
|
|
25
29
|
// 1. Script Code
|
|
@@ -153,7 +157,7 @@ if (typeof module !== 'undefined' && module.hot) {
|
|
|
153
157
|
}
|
|
154
158
|
|
|
155
159
|
// console.log('[MulanJS] Component created:', __component__);
|
|
156
|
-
|
|
160
|
+
module.exports = __component__;
|
|
157
161
|
|
|
158
162
|
// Helper to get relative path for sourceURL
|
|
159
163
|
// This ensures the generated file appears in a readable folder structure in DevTools
|
|
@@ -167,3 +171,42 @@ export default __component__;
|
|
|
167
171
|
};
|
|
168
172
|
}
|
|
169
173
|
exports.compileSFC = compileSFC;
|
|
174
|
+
// --- Mulan Server Components (MSC) ---
|
|
175
|
+
async function compileSFCForSSR(source, filename, options) {
|
|
176
|
+
const descriptor = (0, sfc_parser_1.parseMUJS)(source, filename);
|
|
177
|
+
const scriptResult = await (0, script_compiler_1.compileScript)(descriptor, options);
|
|
178
|
+
let scriptCode = scriptResult.code;
|
|
179
|
+
// Robust replacement for various export styles
|
|
180
|
+
if (scriptCode.includes('export default')) {
|
|
181
|
+
scriptCode = scriptCode.replace('export default', 'const __component__ =');
|
|
182
|
+
}
|
|
183
|
+
else if (scriptCode.includes('exports.default =')) {
|
|
184
|
+
scriptCode = scriptCode.replace('exports.default =', 'const __component__ =');
|
|
185
|
+
}
|
|
186
|
+
else if (scriptCode.includes('module.exports =')) {
|
|
187
|
+
scriptCode = scriptCode.replace('module.exports =', 'const __component__ =');
|
|
188
|
+
}
|
|
189
|
+
else {
|
|
190
|
+
// Fallback: search for defineComponent if it's there
|
|
191
|
+
scriptCode += `\nconst __component__ = typeof exports !== 'undefined' ? (exports.default || module.exports) : {};`;
|
|
192
|
+
}
|
|
193
|
+
const templateResult = (0, ssr_compiler_1.compileToSSR)(descriptor, scriptResult, undefined);
|
|
194
|
+
const finalCode = `${scriptCode}
|
|
195
|
+
|
|
196
|
+
${templateResult.code}
|
|
197
|
+
|
|
198
|
+
if (__component__.prototype) {
|
|
199
|
+
__component__.prototype.renderToString = render;
|
|
200
|
+
} else if (typeof __component__ === 'object') {
|
|
201
|
+
__component__.renderToString = render;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
module.exports = __component__;
|
|
205
|
+
`;
|
|
206
|
+
return {
|
|
207
|
+
code: finalCode,
|
|
208
|
+
css: '', // CSS handling for SSR can be extracted separately
|
|
209
|
+
errors: [...scriptResult.errors, ...templateResult.errors],
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
exports.compileSFCForSSR = compileSFCForSSR;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { SFCDescriptor } from './sfc-parser';
|
|
2
|
+
import { ScriptCompileResult } from './script-compiler';
|
|
3
|
+
export interface DOMCompileResult {
|
|
4
|
+
code: string;
|
|
5
|
+
errors: string[];
|
|
6
|
+
}
|
|
7
|
+
export declare function compileToDOM(descriptor: SFCDescriptor, scriptResult: ScriptCompileResult, scopedId?: string): DOMCompileResult;
|