@sprlab/wccompiler 0.11.3 → 0.11.5
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/bin/wcc.js +5 -0
- package/lib/codegen.js +26 -0
- package/lib/compiler.js +16 -0
- package/lib/config.js +6 -1
- package/lib/parser-extractors.js +17 -4
- package/lib/parser.js +3 -2
- package/package.json +1 -1
- package/types/wcc.d.ts +1 -0
package/bin/wcc.js
CHANGED
|
@@ -35,6 +35,7 @@ async function build(config, cwd) {
|
|
|
35
35
|
|
|
36
36
|
const { code, usesSharedRuntime } = await compile(file, {
|
|
37
37
|
standalone: config.standalone,
|
|
38
|
+
minify: config.minify,
|
|
38
39
|
runtimeImportPath,
|
|
39
40
|
});
|
|
40
41
|
|
|
@@ -209,6 +210,9 @@ async function main() {
|
|
|
209
210
|
const cwd = process.cwd();
|
|
210
211
|
const config = await loadConfig(cwd);
|
|
211
212
|
|
|
213
|
+
// CLI flags override config
|
|
214
|
+
if (process.argv.includes('--minify')) config.minify = true;
|
|
215
|
+
|
|
212
216
|
if (command === 'build') {
|
|
213
217
|
const errors = await build(config, cwd);
|
|
214
218
|
if (errors > 0) process.exit(1);
|
|
@@ -236,6 +240,7 @@ async function main() {
|
|
|
236
240
|
|
|
237
241
|
const { code, usesSharedRuntime } = await compile(filePath, {
|
|
238
242
|
standalone: config.standalone,
|
|
243
|
+
minify: config.minify,
|
|
239
244
|
runtimeImportPath,
|
|
240
245
|
});
|
|
241
246
|
|
package/lib/codegen.js
CHANGED
|
@@ -864,6 +864,7 @@ export function generateComponent(parseResult, options = {}) {
|
|
|
864
864
|
forBlocks = [],
|
|
865
865
|
onMountHooks = [],
|
|
866
866
|
onDestroyHooks = [],
|
|
867
|
+
onAdoptHooks = [],
|
|
867
868
|
modelBindings = [],
|
|
868
869
|
modelPropBindings = [],
|
|
869
870
|
attrBindings = [],
|
|
@@ -1698,6 +1699,31 @@ export function generateComponent(parseResult, options = {}) {
|
|
|
1698
1699
|
lines.push(' }');
|
|
1699
1700
|
lines.push('');
|
|
1700
1701
|
|
|
1702
|
+
// adoptedCallback (if onAdopt hooks exist)
|
|
1703
|
+
if (onAdoptHooks.length > 0) {
|
|
1704
|
+
lines.push(' adoptedCallback() {');
|
|
1705
|
+
for (const hook of onAdoptHooks) {
|
|
1706
|
+
const body = transformMethodBody(hook.body, signalNames, computedNames, propsObjectName, propNames, emitsObjectName, refVarNames, constantNames, modelVarMap);
|
|
1707
|
+
if (hook.async) {
|
|
1708
|
+
lines.push(' ;(async () => {');
|
|
1709
|
+
const bodyLines = body.split('\n');
|
|
1710
|
+
for (const line of bodyLines) {
|
|
1711
|
+
lines.push(` ${line}`);
|
|
1712
|
+
}
|
|
1713
|
+
lines.push(' })();');
|
|
1714
|
+
} else {
|
|
1715
|
+
const bodyLines = body.split('\n');
|
|
1716
|
+
for (const line of bodyLines) {
|
|
1717
|
+
const trimmed = line.trimEnd();
|
|
1718
|
+
const needsSemi = trimmed && !trimmed.endsWith(';') && !trimmed.endsWith('{') && !trimmed.endsWith('}');
|
|
1719
|
+
lines.push(` ${trimmed}${needsSemi ? ';' : ''}`);
|
|
1720
|
+
}
|
|
1721
|
+
}
|
|
1722
|
+
}
|
|
1723
|
+
lines.push(' }');
|
|
1724
|
+
lines.push('');
|
|
1725
|
+
}
|
|
1726
|
+
|
|
1701
1727
|
// attributeChangedCallback (if props or model props exist)
|
|
1702
1728
|
if (propDefs.length > 0 || modelDefs.length > 0) {
|
|
1703
1729
|
lines.push(' attributeChangedCallback(name, oldVal, newVal) {');
|
package/lib/compiler.js
CHANGED
|
@@ -485,5 +485,21 @@ export function resolveStandalone(componentValue, globalValue) {
|
|
|
485
485
|
*/
|
|
486
486
|
export async function compile(filePath, config) {
|
|
487
487
|
const result = await compileSFC(filePath, config);
|
|
488
|
+
|
|
489
|
+
if (config?.minify) {
|
|
490
|
+
const { transform } = await import('esbuild');
|
|
491
|
+
try {
|
|
492
|
+
const minified = await transform(result.code, {
|
|
493
|
+
minify: true,
|
|
494
|
+
loader: 'js',
|
|
495
|
+
target: 'esnext',
|
|
496
|
+
});
|
|
497
|
+
result.code = minified.code;
|
|
498
|
+
} catch {
|
|
499
|
+
// If minification fails (e.g., edge-case syntax), return unminified code
|
|
500
|
+
// This is a graceful fallback — the code still works at runtime
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
|
|
488
504
|
return result;
|
|
489
505
|
}
|
package/lib/config.js
CHANGED
|
@@ -19,7 +19,7 @@ import { pathToFileURL } from 'node:url';
|
|
|
19
19
|
* @returns {Promise<WccConfig>}
|
|
20
20
|
*/
|
|
21
21
|
export async function loadConfig(projectRoot) {
|
|
22
|
-
const defaults = { port: 4100, input: 'src', output: 'dist', standalone: false };
|
|
22
|
+
const defaults = { port: 4100, input: 'src', output: 'dist', standalone: false, minify: false };
|
|
23
23
|
const configPath = resolve(projectRoot, 'wcc.config.js');
|
|
24
24
|
|
|
25
25
|
if (!existsSync(configPath)) return defaults;
|
|
@@ -56,6 +56,11 @@ export async function loadConfig(projectRoot) {
|
|
|
56
56
|
error.code = 'INVALID_CONFIG';
|
|
57
57
|
throw error;
|
|
58
58
|
}
|
|
59
|
+
if (typeof config.minify !== 'boolean') {
|
|
60
|
+
const error = new Error(`Error en wcc.config.js: minify debe ser un booleano`);
|
|
61
|
+
error.code = 'INVALID_CONFIG';
|
|
62
|
+
throw error;
|
|
63
|
+
}
|
|
59
64
|
|
|
60
65
|
return config;
|
|
61
66
|
}
|
package/lib/parser-extractors.js
CHANGED
|
@@ -890,6 +890,14 @@ export function extractFunctions(source) {
|
|
|
890
890
|
if (j === i) {
|
|
891
891
|
// First line: capture everything after the opening brace
|
|
892
892
|
const afterBrace = l.substring(l.indexOf('{') + 1);
|
|
893
|
+
// Single-line function: depth already closed on first line
|
|
894
|
+
if (depth <= 0) {
|
|
895
|
+
const lastBraceIdx = afterBrace.lastIndexOf('}');
|
|
896
|
+
const inner = lastBraceIdx >= 0 ? afterBrace.substring(0, lastBraceIdx) : afterBrace;
|
|
897
|
+
if (inner.trim()) bodyLines.push(inner);
|
|
898
|
+
i = j;
|
|
899
|
+
break;
|
|
900
|
+
}
|
|
893
901
|
if (afterBrace.trim()) bodyLines.push(afterBrace);
|
|
894
902
|
} else if (depth <= 0) {
|
|
895
903
|
// Last line: capture everything before the closing brace
|
|
@@ -925,13 +933,15 @@ export function extractFunctions(source) {
|
|
|
925
933
|
* Only extracts top-level calls (brace depth === 0 when the call is encountered).
|
|
926
934
|
*
|
|
927
935
|
* @param {string} script - The script content (after type stripping)
|
|
928
|
-
* @returns {{ onMountHooks: LifecycleHook[], onDestroyHooks: LifecycleHook[] }}
|
|
936
|
+
* @returns {{ onMountHooks: LifecycleHook[], onDestroyHooks: LifecycleHook[], onAdoptHooks: LifecycleHook[] }}
|
|
929
937
|
*/
|
|
930
938
|
export function extractLifecycleHooks(script) {
|
|
931
939
|
/** @type {LifecycleHook[]} */
|
|
932
940
|
const onMountHooks = [];
|
|
933
941
|
/** @type {LifecycleHook[]} */
|
|
934
942
|
const onDestroyHooks = [];
|
|
943
|
+
/** @type {LifecycleHook[]} */
|
|
944
|
+
const onAdoptHooks = [];
|
|
935
945
|
const lines = script.split('\n');
|
|
936
946
|
let i = 0;
|
|
937
947
|
|
|
@@ -939,8 +949,9 @@ export function extractLifecycleHooks(script) {
|
|
|
939
949
|
const line = lines[i];
|
|
940
950
|
const mountMatch = line.match(/\bonMount\s*\(\s*(?:async\s*)?\(\s*\)\s*=>\s*\{/);
|
|
941
951
|
const destroyMatch = line.match(/\bonDestroy\s*\(\s*(?:async\s*)?\(\s*\)\s*=>\s*\{/);
|
|
952
|
+
const adoptMatch = line.match(/\bonAdopt\s*\(\s*(?:async\s*)?\(\s*\)\s*=>\s*\{/);
|
|
942
953
|
|
|
943
|
-
if (mountMatch || destroyMatch) {
|
|
954
|
+
if (mountMatch || destroyMatch || adoptMatch) {
|
|
944
955
|
// Detect if the callback is async
|
|
945
956
|
const isAsync = /\basync\s*\(/.test(line);
|
|
946
957
|
|
|
@@ -998,14 +1009,16 @@ export function extractLifecycleHooks(script) {
|
|
|
998
1009
|
|
|
999
1010
|
if (mountMatch) {
|
|
1000
1011
|
onMountHooks.push({ body, async: isAsync });
|
|
1001
|
-
} else {
|
|
1012
|
+
} else if (destroyMatch) {
|
|
1002
1013
|
onDestroyHooks.push({ body, async: isAsync });
|
|
1014
|
+
} else {
|
|
1015
|
+
onAdoptHooks.push({ body, async: isAsync });
|
|
1003
1016
|
}
|
|
1004
1017
|
}
|
|
1005
1018
|
i++;
|
|
1006
1019
|
}
|
|
1007
1020
|
|
|
1008
|
-
return { onMountHooks, onDestroyHooks };
|
|
1021
|
+
return { onMountHooks, onDestroyHooks, onAdoptHooks };
|
|
1009
1022
|
}
|
|
1010
1023
|
|
|
1011
1024
|
// ── Ref extraction ───────────────────────────────────────────────────
|
package/lib/parser.js
CHANGED
|
@@ -153,12 +153,12 @@ export async function parse(filePath) {
|
|
|
153
153
|
}
|
|
154
154
|
|
|
155
155
|
// 8. Extract lifecycle hooks (before other extractions to avoid misidentification)
|
|
156
|
-
const { onMountHooks, onDestroyHooks } = extractLifecycleHooks(source);
|
|
156
|
+
const { onMountHooks, onDestroyHooks, onAdoptHooks } = extractLifecycleHooks(source);
|
|
157
157
|
|
|
158
158
|
// 8b. Strip lifecycle hook blocks from source to prevent signal/computed/effect/function
|
|
159
159
|
// extractors from misidentifying code inside hook bodies
|
|
160
160
|
let sourceForExtraction = source;
|
|
161
|
-
const hookLinePattern = /\bonMount\s*\(|\bonDestroy\s*\(|\bwatch\s*\(/;
|
|
161
|
+
const hookLinePattern = /\bonMount\s*\(|\bonDestroy\s*\(|\bonAdopt\s*\(|\bwatch\s*\(/;
|
|
162
162
|
const sourceLines = sourceForExtraction.split('\n');
|
|
163
163
|
const filteredLines = [];
|
|
164
164
|
let skipDepth = 0;
|
|
@@ -263,6 +263,7 @@ export async function parse(filePath) {
|
|
|
263
263
|
processedTemplate: null,
|
|
264
264
|
onMountHooks,
|
|
265
265
|
onDestroyHooks,
|
|
266
|
+
onAdoptHooks,
|
|
266
267
|
refs,
|
|
267
268
|
};
|
|
268
269
|
}
|
package/package.json
CHANGED
package/types/wcc.d.ts
CHANGED
|
@@ -23,5 +23,6 @@ declare module 'wcc' {
|
|
|
23
23
|
|
|
24
24
|
export function onMount(fn: () => void | Promise<void>): void;
|
|
25
25
|
export function onDestroy(fn: () => void | Promise<void>): void;
|
|
26
|
+
export function onAdopt(fn: () => void | Promise<void>): void;
|
|
26
27
|
export function defineExpose(bindings: Record<string, any>): void;
|
|
27
28
|
}
|