versacompiler 2.3.2 → 2.3.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/compiler/compile.js +5 -2
- package/dist/compiler/minify.js +25 -6
- package/dist/compiler/minifyTemplate.js +6 -5
- package/dist/compiler/transforms.js +18 -4
- package/dist/compiler/typescript-error-parser.js +113 -26
- package/dist/compiler/typescript-manager.js +11 -4
- package/dist/compiler/vuejs.js +16 -1
- package/dist/main.js +1 -0
- package/dist/utils/module-resolver.js +164 -154
- package/package.json +111 -110
package/dist/compiler/compile.js
CHANGED
|
@@ -1036,7 +1036,9 @@ function registerCompilationResult(stage, errors, success, files = []) {
|
|
|
1036
1036
|
*/
|
|
1037
1037
|
async function handleCompilationError(error, fileName, stage, mode, isVerbose = false) {
|
|
1038
1038
|
const errorMessage = error instanceof Error ? error.message : error;
|
|
1039
|
-
|
|
1039
|
+
// No mostrar stack trace para errores de tipo TypeScript (son errores del usuario, no del compilador)
|
|
1040
|
+
const isTypeError = error instanceof Error && error.isTypeError;
|
|
1041
|
+
const errorDetails = error instanceof Error && !isTypeError ? error.stack : undefined;
|
|
1040
1042
|
// Registrar el error en el sistema unificado
|
|
1041
1043
|
registerCompilationError(fileName, stage, errorMessage, 'error', errorDetails);
|
|
1042
1044
|
registerCompilationResult(stage, 1, 0, [fileName]); // Mostrar error inmediatamente solo en modo individual y watch
|
|
@@ -1628,7 +1630,8 @@ async function compileJS(inPath, outPath, mode = 'individual') {
|
|
|
1628
1630
|
if (typeof preCompileTS !== 'function') {
|
|
1629
1631
|
throw new Error(`loadTypeScript devolvió ${typeof preCompileTS} en lugar de una función para archivo: ${inPath}`);
|
|
1630
1632
|
}
|
|
1631
|
-
|
|
1633
|
+
// 🚀 OPTIMIZACIÓN: Pasar scriptInfo directamente sin crear objeto nuevo
|
|
1634
|
+
tsResult = await preCompileTS(code, inPath, vueResult?.scriptInfo);
|
|
1632
1635
|
timings.tsCompile = Date.now() - start;
|
|
1633
1636
|
if (tsResult === undefined || tsResult === null) {
|
|
1634
1637
|
throw new Error(`preCompileTS devolvió ${tsResult} para archivo: ${inPath}`);
|
package/dist/compiler/minify.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { createHash } from 'node:crypto';
|
|
2
|
-
import {
|
|
2
|
+
import { minifySync } from 'oxc-minify';
|
|
3
|
+
import { logger } from '../servicios/logger.js';
|
|
3
4
|
import { minifyTemplate } from './minifyTemplate.js';
|
|
4
5
|
class MinificationCache {
|
|
5
6
|
static instance;
|
|
@@ -49,11 +50,18 @@ class MinificationCache {
|
|
|
49
50
|
this.cacheMisses++;
|
|
50
51
|
const originalSize = data.length;
|
|
51
52
|
try {
|
|
52
|
-
const result =
|
|
53
|
+
const result = minifySync(filename, data, options);
|
|
53
54
|
// Si el código de entrada no estaba vacío pero el resultado sí,
|
|
54
55
|
// retornar código original sin minificar con advertencia
|
|
55
56
|
if (data.trim() && !result.code.trim()) {
|
|
56
|
-
|
|
57
|
+
logger.warn(`⚠️ Minificación fallida para ${filename}, usando código original`);
|
|
58
|
+
if (process.env.VERBOSE === 'true') {
|
|
59
|
+
logger.debug(`[Minify Debug] El resultado de oxc-minify fue un código vacío para un archivo de tamaño: ${data.length}`);
|
|
60
|
+
// Si el objeto result tiene otros campos útiles (como errores), los mostramos
|
|
61
|
+
if (Object.keys(result).length > 1) {
|
|
62
|
+
logger.debug(`[Minify Debug] Información adicional del resultado:`, JSON.stringify({ ...result, code: '[REDACTED]' }, null, 2));
|
|
63
|
+
}
|
|
64
|
+
}
|
|
57
65
|
return {
|
|
58
66
|
code: data, // Retornar código original
|
|
59
67
|
error: null, // No es un error crítico
|
|
@@ -81,8 +89,15 @@ class MinificationCache {
|
|
|
81
89
|
}
|
|
82
90
|
catch (error) {
|
|
83
91
|
// En caso de excepción, retornar código original con advertencia
|
|
84
|
-
|
|
85
|
-
|
|
92
|
+
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
93
|
+
logger.warn(`⚠️ Error al minificar ${filename}: ${errorMsg}`);
|
|
94
|
+
logger.warn(` Usando código original sin minificar`);
|
|
95
|
+
if (process.env.VERBOSE === 'true') {
|
|
96
|
+
if (error instanceof Error && error.stack) {
|
|
97
|
+
logger.debug(`[Minify Debug] Stack trace: ${error.stack}`);
|
|
98
|
+
}
|
|
99
|
+
logger.debug(`[Minify Debug] Opciones de minificación:`, JSON.stringify(options, null, 2));
|
|
100
|
+
}
|
|
86
101
|
return {
|
|
87
102
|
code: data, // Retornar código original
|
|
88
103
|
error: null, // No propagar el error
|
|
@@ -102,7 +117,7 @@ class MinificationCache {
|
|
|
102
117
|
this.currentMemoryUsage += entrySize;
|
|
103
118
|
}
|
|
104
119
|
catch (error) {
|
|
105
|
-
|
|
120
|
+
logger.warn('[MinificationCache] Error cacheando minificación:', error);
|
|
106
121
|
}
|
|
107
122
|
}
|
|
108
123
|
/**
|
|
@@ -215,6 +230,10 @@ export const minifyJS = async (data, filename, isProd = true) => {
|
|
|
215
230
|
},
|
|
216
231
|
codegen: {
|
|
217
232
|
removeWhitespace: true,
|
|
233
|
+
normal: true,
|
|
234
|
+
jsdoc: true,
|
|
235
|
+
annotation: true,
|
|
236
|
+
legal: true
|
|
218
237
|
},
|
|
219
238
|
sourcemap: !isProd,
|
|
220
239
|
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { minifyHTMLLiterals } from 'minify-html-literals';
|
|
2
|
+
import { logger } from '../servicios/logger.js';
|
|
2
3
|
const defaultMinifyOptions = {
|
|
3
4
|
// Opciones esenciales para componentes Vue
|
|
4
5
|
caseSensitive: true, // Preserva mayúsculas/minúsculas en nombres de componentes
|
|
@@ -96,7 +97,7 @@ const detectAndTagTemplateStrings = (code) => {
|
|
|
96
97
|
});
|
|
97
98
|
}
|
|
98
99
|
catch (error) {
|
|
99
|
-
|
|
100
|
+
logger.warn('[MinifyTemplate] Error detectando template strings:', error);
|
|
100
101
|
return code;
|
|
101
102
|
}
|
|
102
103
|
};
|
|
@@ -113,7 +114,7 @@ const removeTemporaryTags = (code) => {
|
|
|
113
114
|
return code.replace(tempHtmlPattern, '`').replace(tempCssPattern, '`');
|
|
114
115
|
}
|
|
115
116
|
catch (error) {
|
|
116
|
-
|
|
117
|
+
logger.warn('[MinifyTemplate] Error removiendo tags temporales:', error);
|
|
117
118
|
return code;
|
|
118
119
|
}
|
|
119
120
|
};
|
|
@@ -163,7 +164,7 @@ const minifyCSS = (code) => {
|
|
|
163
164
|
});
|
|
164
165
|
}
|
|
165
166
|
catch (error) {
|
|
166
|
-
|
|
167
|
+
logger.warn('[MinifyTemplate] Error minificando CSS:', error);
|
|
167
168
|
return code;
|
|
168
169
|
}
|
|
169
170
|
};
|
|
@@ -208,7 +209,7 @@ const minifyTemplate = (data, fileName) => {
|
|
|
208
209
|
catch (parseError) {
|
|
209
210
|
// Si minifyHTMLLiterals falla (ej: encuentra código TypeScript en vez de HTML),
|
|
210
211
|
// devolver el código sin minificar en lugar de fallar completamente
|
|
211
|
-
|
|
212
|
+
logger.warn(`[MinifyTemplate] minifyHTMLLiterals falló para ${fileName}, usando código sin minificar:`, parseError instanceof Error
|
|
212
213
|
? parseError.message
|
|
213
214
|
: String(parseError));
|
|
214
215
|
// minifiedCode ya tiene el valor de code
|
|
@@ -221,7 +222,7 @@ const minifyTemplate = (data, fileName) => {
|
|
|
221
222
|
return { code: finalCode, error: null };
|
|
222
223
|
}
|
|
223
224
|
catch (error) {
|
|
224
|
-
|
|
225
|
+
logger.warn(`[MinifyTemplate] Error minificando plantilla ${fileName}:`, error);
|
|
225
226
|
return { code: data, error };
|
|
226
227
|
}
|
|
227
228
|
};
|
|
@@ -6,6 +6,20 @@ import { getModuleSubPath } from '../utils/module-resolver.js';
|
|
|
6
6
|
import { analyzeAndFormatMultipleErrors } from './error-reporter.js';
|
|
7
7
|
import { getOptimizedAliasPath, getOptimizedModulePath, } from './module-resolution-optimizer.js';
|
|
8
8
|
import { parser } from './parser.js';
|
|
9
|
+
// ✨ OPTIMIZACIÓN CRÍTICA: Cache de PATH_ALIAS parseado
|
|
10
|
+
let cachedPathAlias = null;
|
|
11
|
+
let lastPathAliasString = null;
|
|
12
|
+
function getParsedPathAlias() {
|
|
13
|
+
if (!env.PATH_ALIAS)
|
|
14
|
+
return null;
|
|
15
|
+
// Solo parsear si el string cambió
|
|
16
|
+
if (cachedPathAlias && lastPathAliasString === env.PATH_ALIAS) {
|
|
17
|
+
return cachedPathAlias;
|
|
18
|
+
}
|
|
19
|
+
cachedPathAlias = JSON.parse(env.PATH_ALIAS);
|
|
20
|
+
lastPathAliasString = env.PATH_ALIAS;
|
|
21
|
+
return cachedPathAlias;
|
|
22
|
+
}
|
|
9
23
|
// Módulos built-in de Node.js que no deben ser resueltos
|
|
10
24
|
const NODE_BUILTIN_MODULES = new Set([
|
|
11
25
|
'fs',
|
|
@@ -94,7 +108,7 @@ export async function replaceAliasImportStatic(file, code) {
|
|
|
94
108
|
if (!env.PATH_ALIAS || !env.PATH_DIST) {
|
|
95
109
|
return code;
|
|
96
110
|
}
|
|
97
|
-
const pathAlias =
|
|
111
|
+
const pathAlias = getParsedPathAlias();
|
|
98
112
|
let resultCode = code;
|
|
99
113
|
// Usar regex para transformar imports estáticos
|
|
100
114
|
const importRegex = /import\s+(?:(?:\{[^}]*\}|\*\s+as\s+\w+|\w+)(?:\s*,\s*(?:\{[^}]*\}|\*\s+as\s+\w+|\w+))*\s+from\s+)?['"`]([^'"`]+)['"`]/g;
|
|
@@ -206,7 +220,7 @@ export async function replaceAliasImportDynamic(code, _imports, file) {
|
|
|
206
220
|
if (!env.PATH_ALIAS || !env.PATH_DIST) {
|
|
207
221
|
return code;
|
|
208
222
|
}
|
|
209
|
-
const pathAlias =
|
|
223
|
+
const pathAlias = getParsedPathAlias();
|
|
210
224
|
const pathDist = env.PATH_DIST;
|
|
211
225
|
let resultCode = code;
|
|
212
226
|
// Regex para imports dinámicos normales con string (solo comillas simples y dobles)
|
|
@@ -391,7 +405,7 @@ async function replaceAliasInStrings(code) {
|
|
|
391
405
|
if (!env.PATH_ALIAS || !env.PATH_DIST) {
|
|
392
406
|
return code;
|
|
393
407
|
}
|
|
394
|
-
const pathAlias =
|
|
408
|
+
const pathAlias = getParsedPathAlias();
|
|
395
409
|
const pathDist = env.PATH_DIST;
|
|
396
410
|
let resultCode = code; // Regex para encontrar strings que contengan posibles alias
|
|
397
411
|
// Busca strings entre comillas simples, dobles o backticks que contengan alias
|
|
@@ -539,7 +553,7 @@ export async function estandarizaCode(code, file) {
|
|
|
539
553
|
code = await replaceAliasInStrings(code);
|
|
540
554
|
code = await removehtmlOfTemplateString(code);
|
|
541
555
|
code = await removeCodeTagImport(code);
|
|
542
|
-
if (env.
|
|
556
|
+
if (env.isPROD === 'true') {
|
|
543
557
|
code = await removePreserverComent(code);
|
|
544
558
|
}
|
|
545
559
|
return { code, error: null };
|
|
@@ -1,12 +1,18 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs';
|
|
1
2
|
import * as typescript from 'typescript';
|
|
2
3
|
/**
|
|
3
4
|
* Parsea errores de TypeScript y los convierte a un formato limpio
|
|
4
5
|
* que incluye solo: archivo, mensaje, severidad y ubicación como ayuda
|
|
6
|
+
* 🚀 OPTIMIZADO: Sin split preventivo, sin enhance - solo lo esencial para máxima velocidad
|
|
7
|
+
* @param scriptInfo - Información de extracción de script para archivos Vue (opcional)
|
|
5
8
|
*/
|
|
6
|
-
export function parseTypeScriptErrors(diagnostics, fileName, sourceCode) {
|
|
9
|
+
export function parseTypeScriptErrors(diagnostics, fileName, sourceCode, scriptInfo) {
|
|
7
10
|
return diagnostics.map(diagnostic => {
|
|
8
|
-
//
|
|
9
|
-
const
|
|
11
|
+
// Extraer mensaje básico sin enhance (más rápido)
|
|
12
|
+
const message = typeof diagnostic.messageText === 'string'
|
|
13
|
+
? diagnostic.messageText
|
|
14
|
+
: typescript.flattenDiagnosticMessageText(diagnostic.messageText, '\n');
|
|
15
|
+
const cleanedMessage = cleanErrorMessage(message); // Determinar la severidad
|
|
10
16
|
let severity;
|
|
11
17
|
switch (diagnostic.category) {
|
|
12
18
|
case typescript.DiagnosticCategory.Error:
|
|
@@ -20,32 +26,102 @@ export function parseTypeScriptErrors(diagnostics, fileName, sourceCode) {
|
|
|
20
26
|
break;
|
|
21
27
|
} // Construir información de ubicación limpia
|
|
22
28
|
let help = `Código TS${diagnostic.code}`;
|
|
23
|
-
if (diagnostic.
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
29
|
+
if (diagnostic.start !== undefined) {
|
|
30
|
+
// Intentar usar el sourceFile si está disponible
|
|
31
|
+
if (diagnostic.file &&
|
|
32
|
+
typeof diagnostic.file.getLineAndCharacterOfPosition ===
|
|
33
|
+
'function') {
|
|
27
34
|
try {
|
|
28
|
-
const lineAndChar =
|
|
29
|
-
|
|
35
|
+
const lineAndChar = diagnostic.file.getLineAndCharacterOfPosition(diagnostic.start);
|
|
36
|
+
// Ajustar línea si es un archivo Vue con script extraído
|
|
37
|
+
const adjustedLine = scriptInfo
|
|
38
|
+
? lineAndChar.line + scriptInfo.startLine
|
|
39
|
+
: lineAndChar.line + 1;
|
|
40
|
+
help += ` | Línea ${adjustedLine}, Columna ${lineAndChar.character + 1}`;
|
|
30
41
|
}
|
|
31
42
|
catch {
|
|
32
|
-
//
|
|
33
|
-
|
|
43
|
+
// Fallback: calcular posición leyendo el archivo
|
|
44
|
+
try {
|
|
45
|
+
const content = readFileSync(fileName, 'utf-8');
|
|
46
|
+
const lines = content.split('\n');
|
|
47
|
+
const { line, column } = getLineAndColumnFromOffset(lines, diagnostic.start);
|
|
48
|
+
help += ` | Línea ${line}, Columna ${column}`;
|
|
49
|
+
}
|
|
50
|
+
catch {
|
|
51
|
+
// Último fallback: solo mostrar posición
|
|
52
|
+
help += ` | Posición ${diagnostic.start}`;
|
|
53
|
+
}
|
|
34
54
|
}
|
|
35
55
|
}
|
|
36
56
|
else {
|
|
37
|
-
// Fallback
|
|
38
|
-
|
|
57
|
+
// Fallback: calcular posición y mostrar snippet de código
|
|
58
|
+
try {
|
|
59
|
+
// Para archivos Vue con sourceCode, extraer el snippet del código compilado
|
|
60
|
+
if (scriptInfo && sourceCode) {
|
|
61
|
+
const compiledLines = sourceCode.split('\n');
|
|
62
|
+
const { line: compiledLine, column } = getLineAndColumnFromOffset(compiledLines, diagnostic.start);
|
|
63
|
+
// Extraer la línea donde está el error
|
|
64
|
+
const errorLine = compiledLines[compiledLine - 1]?.trim() || '';
|
|
65
|
+
// Truncar si es muy largo, centrando en el punto del error
|
|
66
|
+
const maxSnippetLength = 80;
|
|
67
|
+
let snippet = errorLine;
|
|
68
|
+
if (snippet.length > maxSnippetLength) {
|
|
69
|
+
// Tomar alrededor del punto del error
|
|
70
|
+
const start = Math.max(0, column - 40);
|
|
71
|
+
const end = Math.min(snippet.length, column + 40);
|
|
72
|
+
snippet =
|
|
73
|
+
(start > 0 ? '...' : '') +
|
|
74
|
+
snippet.substring(start, end) +
|
|
75
|
+
(end < snippet.length ? '...' : '');
|
|
76
|
+
}
|
|
77
|
+
// Para archivos Vue, mostrar snippet para buscar
|
|
78
|
+
help += ` | Buscar en archivo: "${snippet}"`;
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
// No es Vue o no tenemos sourceCode, usar el archivo directamente
|
|
82
|
+
const content = readFileSync(fileName, 'utf-8');
|
|
83
|
+
const lines = content.split('\n');
|
|
84
|
+
const { line, column } = getLineAndColumnFromOffset(lines, diagnostic.start);
|
|
85
|
+
help += ` | Línea ${line}, Columna ${column}`;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
catch {
|
|
89
|
+
// Último fallback: solo mostrar posición
|
|
90
|
+
help += ` | Posición ${diagnostic.start}`;
|
|
91
|
+
}
|
|
39
92
|
}
|
|
40
93
|
}
|
|
41
94
|
return {
|
|
42
95
|
file: fileName,
|
|
43
|
-
message:
|
|
96
|
+
message: cleanedMessage,
|
|
44
97
|
severity,
|
|
45
98
|
help,
|
|
46
99
|
};
|
|
47
100
|
});
|
|
48
101
|
}
|
|
102
|
+
/**
|
|
103
|
+
* Calcula línea y columna desde un offset de caracteres
|
|
104
|
+
* @param lines - Array de líneas ya procesadas (para evitar múltiples splits)
|
|
105
|
+
* @param offset - Posición del carácter
|
|
106
|
+
*/
|
|
107
|
+
function getLineAndColumnFromOffset(lines, offset) {
|
|
108
|
+
let currentOffset = 0;
|
|
109
|
+
let line = 1;
|
|
110
|
+
let column = 1;
|
|
111
|
+
for (let i = 0; i < lines.length; i++) {
|
|
112
|
+
const currentLine = lines[i];
|
|
113
|
+
if (currentLine === undefined)
|
|
114
|
+
continue;
|
|
115
|
+
const lineLength = currentLine.length + 1; // +1 para el \n
|
|
116
|
+
if (currentOffset + lineLength > offset) {
|
|
117
|
+
line = i + 1;
|
|
118
|
+
column = offset - currentOffset + 1;
|
|
119
|
+
break;
|
|
120
|
+
}
|
|
121
|
+
currentOffset += lineLength;
|
|
122
|
+
}
|
|
123
|
+
return { line, column };
|
|
124
|
+
}
|
|
49
125
|
/**
|
|
50
126
|
* Limpia el mensaje de error eliminando información redundante
|
|
51
127
|
*/
|
|
@@ -61,8 +137,11 @@ function cleanErrorMessage(message) {
|
|
|
61
137
|
}
|
|
62
138
|
/**
|
|
63
139
|
* Mejora significativamente el mensaje de error TypeScript con contexto visual
|
|
140
|
+
* ⚠️ DEPRECATED: Ya no se usa en el flujo normal para evitar overhead de performance
|
|
141
|
+
* Se mantiene para compatibilidad futura o modo verbose avanzado
|
|
142
|
+
* @param scriptInfo - Información de extracción de script para archivos Vue (opcional)
|
|
64
143
|
*/
|
|
65
|
-
function enhanceErrorMessage(diagnostic, fileName, sourceCode) {
|
|
144
|
+
function enhanceErrorMessage(diagnostic, fileName, sourceCode, scriptInfo) {
|
|
66
145
|
// Extraer el mensaje del error
|
|
67
146
|
const message = typeof diagnostic.messageText === 'string'
|
|
68
147
|
? diagnostic.messageText
|
|
@@ -76,35 +155,43 @@ function enhanceErrorMessage(diagnostic, fileName, sourceCode) {
|
|
|
76
155
|
if (typeof sourceFile.getLineAndCharacterOfPosition === 'function') {
|
|
77
156
|
try {
|
|
78
157
|
const lineAndChar = sourceFile.getLineAndCharacterOfPosition(diagnostic.start);
|
|
79
|
-
|
|
158
|
+
// Ajustar línea si es un archivo Vue con script extraído
|
|
159
|
+
const line = scriptInfo
|
|
160
|
+
? lineAndChar.line + scriptInfo.startLine
|
|
161
|
+
: lineAndChar.line + 1;
|
|
80
162
|
const column = lineAndChar.character + 1;
|
|
81
163
|
location = `Línea ${line}, Columna ${column} | Código TS${diagnostic.code}`;
|
|
82
164
|
}
|
|
83
165
|
catch {
|
|
84
|
-
// Si falla, solo mostrar
|
|
85
|
-
location = `
|
|
166
|
+
// Si falla, solo mostrar el código de error
|
|
167
|
+
location = `Código TS${diagnostic.code}`;
|
|
86
168
|
}
|
|
87
169
|
}
|
|
88
170
|
else {
|
|
89
|
-
// Fallback
|
|
90
|
-
location = `
|
|
171
|
+
// Fallback: solo mostrar el código de error
|
|
172
|
+
location = `Código TS${diagnostic.code}`;
|
|
91
173
|
} // Agregar contexto del código si está disponible
|
|
92
|
-
if ((sourceCode || sourceFile.text) &&
|
|
174
|
+
if ((sourceCode || scriptInfo?.originalData || sourceFile.text) &&
|
|
93
175
|
typeof sourceFile.getLineAndCharacterOfPosition === 'function') {
|
|
94
176
|
try {
|
|
95
177
|
const lineAndChar = sourceFile.getLineAndCharacterOfPosition(diagnostic.start);
|
|
96
|
-
|
|
178
|
+
// Obtener código fuente apropiado
|
|
179
|
+
const text = scriptInfo?.originalData || sourceCode || sourceFile.text;
|
|
97
180
|
const lines = text.split('\n');
|
|
98
|
-
|
|
181
|
+
// Calcular la línea real en el archivo original
|
|
182
|
+
const actualLineIndex = scriptInfo
|
|
183
|
+
? lineAndChar.line + scriptInfo.startLine - 1
|
|
184
|
+
: lineAndChar.line;
|
|
185
|
+
const errorLine = lines[actualLineIndex];
|
|
99
186
|
if (errorLine) {
|
|
100
187
|
// Mostrar hasta 2 líneas antes y después para contexto
|
|
101
|
-
const startLine = Math.max(0,
|
|
102
|
-
const endLine = Math.min(lines.length - 1,
|
|
188
|
+
const startLine = Math.max(0, actualLineIndex - 2);
|
|
189
|
+
const endLine = Math.min(lines.length - 1, actualLineIndex + 2);
|
|
103
190
|
codeContext = '\n\n📝 Contexto del código:\n';
|
|
104
191
|
for (let i = startLine; i <= endLine; i++) {
|
|
105
192
|
const currentLine = i + 1;
|
|
106
193
|
const lineContent = lines[i] || '';
|
|
107
|
-
const isErrorLine = i ===
|
|
194
|
+
const isErrorLine = i === actualLineIndex;
|
|
108
195
|
if (isErrorLine) {
|
|
109
196
|
codeContext += ` ${currentLine.toString().padStart(3, ' ')} ❌ ${lineContent}\n`;
|
|
110
197
|
// Agregar flecha apuntando al error
|
|
@@ -213,9 +213,10 @@ const cleanupUnnecessaryExports = (compiledOutput, originalSource) => {
|
|
|
213
213
|
* Precompila el código TypeScript con pipeline optimizado para máxima performance.
|
|
214
214
|
* @param {string} data - El código TypeScript a precompilar.
|
|
215
215
|
* @param {string} fileName - El nombre del archivo que contiene el código typescript.
|
|
216
|
+
* @param {ScriptExtractionInfo} scriptInfo - Información de extracción de script para archivos Vue (opcional).
|
|
216
217
|
* @returns {Promise<CompileResult>} - Un objeto con el código precompilado o un error.
|
|
217
218
|
*/
|
|
218
|
-
export const preCompileTS = async (data, fileName) => {
|
|
219
|
+
export const preCompileTS = async (data, fileName, scriptInfo) => {
|
|
219
220
|
try {
|
|
220
221
|
// Validación temprana: contenido vacío
|
|
221
222
|
if (!data.trim()) {
|
|
@@ -241,6 +242,7 @@ export const preCompileTS = async (data, fileName) => {
|
|
|
241
242
|
// Modo más rápido
|
|
242
243
|
incremental: false, // No usar incremental en transpileModule
|
|
243
244
|
diagnostics: false,
|
|
245
|
+
removeComments: env.isPROD === 'true',
|
|
244
246
|
},
|
|
245
247
|
fileName,
|
|
246
248
|
reportDiagnostics: env.VERBOSE === 'true', // Solo reportar en verbose
|
|
@@ -260,7 +262,7 @@ export const preCompileTS = async (data, fileName) => {
|
|
|
260
262
|
diag.code !== 6059);
|
|
261
263
|
});
|
|
262
264
|
if (criticalErrors.length > 0) {
|
|
263
|
-
const errorMessage = createUnifiedErrorMessage(parseTypeScriptErrors(criticalErrors, fileName, data));
|
|
265
|
+
const errorMessage = createUnifiedErrorMessage(parseTypeScriptErrors(criticalErrors, fileName, data, scriptInfo));
|
|
264
266
|
return {
|
|
265
267
|
error: new Error(errorMessage),
|
|
266
268
|
data: null,
|
|
@@ -274,9 +276,14 @@ export const preCompileTS = async (data, fileName) => {
|
|
|
274
276
|
const serializableOptions = createSerializableCompilerOptions(compilerOptions);
|
|
275
277
|
const typeCheckResult = await workerPool.typeCheck(fileName, data, serializableOptions);
|
|
276
278
|
if (typeCheckResult.hasErrors) {
|
|
277
|
-
const errorMessage = createUnifiedErrorMessage(parseTypeScriptErrors(typeCheckResult.diagnostics, fileName, data));
|
|
279
|
+
const errorMessage = createUnifiedErrorMessage(parseTypeScriptErrors(typeCheckResult.diagnostics, fileName, data, scriptInfo));
|
|
280
|
+
const error = new Error(errorMessage);
|
|
281
|
+
// Marcar como error de tipo (no error del compilador)
|
|
282
|
+
error.isTypeError = true;
|
|
283
|
+
// Limpiar stack trace para no confundir con errores del compilador
|
|
284
|
+
error.stack = undefined;
|
|
278
285
|
return {
|
|
279
|
-
error
|
|
286
|
+
error,
|
|
280
287
|
data: null,
|
|
281
288
|
lang: 'ts',
|
|
282
289
|
};
|
package/dist/compiler/vuejs.js
CHANGED
|
@@ -158,8 +158,11 @@ export const preCompileVue = async (data, source, isProd = false) => {
|
|
|
158
158
|
error: null,
|
|
159
159
|
data: 'export default {};',
|
|
160
160
|
lang: 'js',
|
|
161
|
+
scriptInfo: undefined,
|
|
161
162
|
};
|
|
162
163
|
}
|
|
164
|
+
// Guardar el código original antes de inyectar HMR
|
|
165
|
+
const originalData = data;
|
|
163
166
|
if (!isProd) {
|
|
164
167
|
const { injectedData } = hmrInjectionCache.getOrGenerateHMRInjection(data, fileName);
|
|
165
168
|
data = injectedData;
|
|
@@ -370,11 +373,22 @@ export const preCompileVue = async (data, source, isProd = false) => {
|
|
|
370
373
|
|
|
371
374
|
export default ${componentName}; `;
|
|
372
375
|
output = `${output}\n${finishComponent}`;
|
|
373
|
-
|
|
376
|
+
// 🚀 OPTIMIZACIÓN CRÍTICA: Evitar crear scriptInfo si no hay script
|
|
377
|
+
const result = {
|
|
374
378
|
lang: finalCompiledScript.lang,
|
|
375
379
|
error: null,
|
|
376
380
|
data: output,
|
|
377
381
|
};
|
|
382
|
+
// Solo agregar scriptInfo cuando realmente hay script (evita overhead)
|
|
383
|
+
if (descriptor.script || descriptor.scriptSetup) {
|
|
384
|
+
result.scriptInfo = {
|
|
385
|
+
startLine: (descriptor.script || descriptor.scriptSetup).loc?.start
|
|
386
|
+
.line || 1,
|
|
387
|
+
content: (descriptor.script || descriptor.scriptSetup).content,
|
|
388
|
+
originalData: originalData, // String directa, no closure
|
|
389
|
+
};
|
|
390
|
+
}
|
|
391
|
+
return result;
|
|
378
392
|
}
|
|
379
393
|
catch (error) {
|
|
380
394
|
logger.error('Vue compilation error:', error);
|
|
@@ -382,6 +396,7 @@ export const preCompileVue = async (data, source, isProd = false) => {
|
|
|
382
396
|
lang: null,
|
|
383
397
|
error: error instanceof Error ? error : new Error(String(error)),
|
|
384
398
|
data: null,
|
|
399
|
+
scriptInfo: undefined,
|
|
385
400
|
};
|
|
386
401
|
}
|
|
387
402
|
};
|
package/dist/main.js
CHANGED
|
@@ -97,6 +97,7 @@ async function main() {
|
|
|
97
97
|
default: false, // Por defecto, verbose está deshabilitado
|
|
98
98
|
})
|
|
99
99
|
.alias('v', 'verbose')
|
|
100
|
+
.alias('debug', 'verbose')
|
|
100
101
|
.option('cleanOutput', {
|
|
101
102
|
type: 'boolean',
|
|
102
103
|
description: 'Limpiar el directorio de salida antes de compilar',
|
|
@@ -6,6 +6,48 @@ import { cwd, env } from 'node:process';
|
|
|
6
6
|
// import resolve from '/node_modules/resolve/index.js';
|
|
7
7
|
import { logger } from '../servicios/logger.js';
|
|
8
8
|
import { EXCLUDED_MODULES } from './excluded-modules.js';
|
|
9
|
+
class PackageJsonCache {
|
|
10
|
+
static instance;
|
|
11
|
+
cache = new Map();
|
|
12
|
+
MAX_CACHE_SIZE = 200;
|
|
13
|
+
static getInstance() {
|
|
14
|
+
if (!PackageJsonCache.instance) {
|
|
15
|
+
PackageJsonCache.instance = new PackageJsonCache();
|
|
16
|
+
}
|
|
17
|
+
return PackageJsonCache.instance;
|
|
18
|
+
}
|
|
19
|
+
get(packagePath) {
|
|
20
|
+
try {
|
|
21
|
+
if (!fs.existsSync(packagePath)) {
|
|
22
|
+
return null;
|
|
23
|
+
}
|
|
24
|
+
const stats = fs.statSync(packagePath);
|
|
25
|
+
const cached = this.cache.get(packagePath);
|
|
26
|
+
if (cached && cached.mtime === stats.mtimeMs) {
|
|
27
|
+
return cached.content;
|
|
28
|
+
}
|
|
29
|
+
const content = JSON.parse(readFileSync(packagePath, 'utf-8'));
|
|
30
|
+
if (this.cache.size >= this.MAX_CACHE_SIZE) {
|
|
31
|
+
const firstKey = this.cache.keys().next().value;
|
|
32
|
+
if (firstKey) {
|
|
33
|
+
this.cache.delete(firstKey);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
this.cache.set(packagePath, {
|
|
37
|
+
content,
|
|
38
|
+
mtime: stats.mtimeMs,
|
|
39
|
+
});
|
|
40
|
+
return content;
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
return null;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
clear() {
|
|
47
|
+
this.cache.clear();
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
const packageJsonCache = PackageJsonCache.getInstance();
|
|
9
51
|
// function resolveESMWithLibrary(moduleName: string): string | null {
|
|
10
52
|
// try {
|
|
11
53
|
// // Resolver el módulo
|
|
@@ -141,166 +183,130 @@ function findOptimalESMVersion(moduleDir, entryPoint) {
|
|
|
141
183
|
}
|
|
142
184
|
return optimizedPath;
|
|
143
185
|
}
|
|
144
|
-
}
|
|
145
|
-
|
|
186
|
+
}
|
|
187
|
+
// ✨ OPTIMIZACIÓN CRÍTICA: Clasificar archivos en un solo loop
|
|
188
|
+
const fileGroups = {
|
|
189
|
+
esmBrowserProd: [],
|
|
190
|
+
esmBrowserMin: [],
|
|
191
|
+
esmBrowserDev: [],
|
|
192
|
+
esmProd: [],
|
|
193
|
+
esmMin: [],
|
|
194
|
+
esmDev: [],
|
|
195
|
+
browserMin: [],
|
|
196
|
+
runtimeDev: [],
|
|
197
|
+
runtime: [],
|
|
198
|
+
other: [],
|
|
199
|
+
};
|
|
200
|
+
for (const file of files) {
|
|
201
|
+
if (!file.endsWith('.js') && !file.endsWith('.mjs'))
|
|
202
|
+
continue;
|
|
146
203
|
const lowerFile = file.toLowerCase();
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
// ✨ MODO PRODUCCIÓN: Priorizar .prod.js o .min.js
|
|
161
|
-
if (env.isPROD === 'true') {
|
|
162
|
-
// Primera opción: archivos .prod.js
|
|
163
|
-
const prodFiles = esmBrowserCombined.filter((file) => file.toLowerCase().includes('.prod.'));
|
|
164
|
-
if (prodFiles.length > 0 && prodFiles[0]) {
|
|
165
|
-
const optimizedPath = join(dir, prodFiles[0]).replace(/\\/g, '/');
|
|
166
|
-
if (env.VERBOSE === 'true') {
|
|
167
|
-
logger.info(`🏭 Versión ESM-Browser producción encontrada: ${optimizedPath}`);
|
|
168
|
-
}
|
|
169
|
-
return optimizedPath;
|
|
170
|
-
}
|
|
171
|
-
// Segunda opción: archivos .min.js
|
|
172
|
-
const minFiles = esmBrowserCombined.filter((file) => file.toLowerCase().includes('.min.'));
|
|
173
|
-
if (minFiles.length > 0 && minFiles[0]) {
|
|
174
|
-
const optimizedPath = join(dir, minFiles[0]).replace(/\\/g, '/');
|
|
175
|
-
if (env.VERBOSE === 'true') {
|
|
176
|
-
logger.info(`🗜️ Versión ESM-Browser minificada encontrada: ${optimizedPath}`);
|
|
177
|
-
}
|
|
178
|
-
return optimizedPath;
|
|
179
|
-
}
|
|
180
|
-
// Fallback: si no hay .prod ni .min, usar desarrollo
|
|
181
|
-
if (env.VERBOSE === 'true') {
|
|
182
|
-
logger.warn('⚠️ No se encontró versión de producción, usando desarrollo');
|
|
183
|
-
}
|
|
184
|
-
}
|
|
185
|
-
// ✨ MODO DESARROLLO: Priorizar desarrollo > .prod > .min
|
|
186
|
-
const devFiles = esmBrowserCombined.filter((file) => !file.toLowerCase().includes('.prod.') &&
|
|
187
|
-
!file.toLowerCase().includes('.min.'));
|
|
188
|
-
if (devFiles.length > 0 && devFiles[0]) {
|
|
189
|
-
const optimizedPath = join(dir, devFiles[0]).replace(/\\/g, '/');
|
|
190
|
-
if (env.VERBOSE === 'true') {
|
|
191
|
-
logger.info(`🔧 Versión ESM-Browser desarrollo encontrada: ${optimizedPath}`);
|
|
192
|
-
}
|
|
193
|
-
return optimizedPath;
|
|
194
|
-
}
|
|
195
|
-
// Fallback en desarrollo: si no hay versión dev, usar prod
|
|
196
|
-
const prodFiles = esmBrowserCombined.filter((file) => file.toLowerCase().includes('.prod.'));
|
|
197
|
-
if (prodFiles.length > 0 && prodFiles[0]) {
|
|
198
|
-
const optimizedPath = join(dir, prodFiles[0]).replace(/\\/g, '/');
|
|
199
|
-
if (env.VERBOSE === 'true') {
|
|
200
|
-
logger.info(`Versión ESM-Browser producción encontrada (fallback): ${optimizedPath}`);
|
|
201
|
-
}
|
|
202
|
-
return optimizedPath;
|
|
203
|
-
}
|
|
204
|
-
const minFiles = esmBrowserCombined.filter((file) => file.toLowerCase().includes('.min.'));
|
|
205
|
-
if (minFiles.length > 0 && minFiles[0]) {
|
|
206
|
-
const optimizedPath = join(dir, minFiles[0]).replace(/\\/g, '/');
|
|
207
|
-
if (env.VERBOSE === 'true') {
|
|
208
|
-
logger.info(`Versión ESM-Browser minificada encontrada (fallback): ${optimizedPath}`);
|
|
209
|
-
}
|
|
210
|
-
return optimizedPath;
|
|
211
|
-
}
|
|
212
|
-
if (esmBrowserCombined[0]) {
|
|
213
|
-
const optimizedPath = join(dir, esmBrowserCombined[0]).replace(/\\/g, '/');
|
|
214
|
-
if (env.VERBOSE === 'true') {
|
|
215
|
-
logger.info(`Versión ESM-Browser encontrada: ${optimizedPath}`);
|
|
216
|
-
}
|
|
217
|
-
return optimizedPath;
|
|
218
|
-
}
|
|
204
|
+
const hasEsmBrowser = lowerFile.includes('.esm-browser.');
|
|
205
|
+
const hasEsm = lowerFile.includes('.esm.') || lowerFile.includes('.module.');
|
|
206
|
+
const hasBrowser = lowerFile.includes('.browser.') || lowerFile.includes('.web.');
|
|
207
|
+
const hasRuntime = lowerFile.includes('.runtime.');
|
|
208
|
+
const isProd = lowerFile.includes('.prod.');
|
|
209
|
+
const isMin = lowerFile.includes('.min.');
|
|
210
|
+
if (hasEsmBrowser && !hasRuntime) {
|
|
211
|
+
if (isProd)
|
|
212
|
+
fileGroups.esmBrowserProd.push(file);
|
|
213
|
+
else if (isMin)
|
|
214
|
+
fileGroups.esmBrowserMin.push(file);
|
|
215
|
+
else
|
|
216
|
+
fileGroups.esmBrowserDev.push(file);
|
|
219
217
|
}
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
!file.toLowerCase().includes('.runtime.'));
|
|
228
|
-
if (esmProdFiles.length > 0 && esmProdFiles[0]) {
|
|
229
|
-
const optimizedPath = join(dir, esmProdFiles[0]).replace(/\\/g, '/');
|
|
230
|
-
if (env.VERBOSE === 'true') {
|
|
231
|
-
logger.info(`🏭 Versión ESM producción encontrada: ${optimizedPath}`);
|
|
232
|
-
}
|
|
233
|
-
return optimizedPath;
|
|
234
|
-
}
|
|
218
|
+
else if (hasEsm && !hasRuntime) {
|
|
219
|
+
if (isProd)
|
|
220
|
+
fileGroups.esmProd.push(file);
|
|
221
|
+
else if (isMin)
|
|
222
|
+
fileGroups.esmMin.push(file);
|
|
223
|
+
else
|
|
224
|
+
fileGroups.esmDev.push(file);
|
|
235
225
|
}
|
|
236
|
-
else {
|
|
237
|
-
|
|
238
|
-
const esmFiles = esmBrowserFiles.filter((file) => (file.toLowerCase().includes('.esm.') ||
|
|
239
|
-
file.toLowerCase().includes('.module.')) &&
|
|
240
|
-
!file.toLowerCase().includes('.min.') &&
|
|
241
|
-
!file.toLowerCase().includes('.prod.') &&
|
|
242
|
-
!file.toLowerCase().includes('.runtime.'));
|
|
243
|
-
if (esmFiles.length > 0 && esmFiles[0]) {
|
|
244
|
-
const optimizedPath = join(dir, esmFiles[0]).replace(/\\/g, '/');
|
|
245
|
-
if (env.VERBOSE === 'true') {
|
|
246
|
-
logger.info(`🔧 Versión ESM desarrollo encontrada: ${optimizedPath}`);
|
|
247
|
-
}
|
|
248
|
-
return optimizedPath;
|
|
249
|
-
}
|
|
226
|
+
else if (hasBrowser && isMin) {
|
|
227
|
+
fileGroups.browserMin.push(file);
|
|
250
228
|
}
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
// Priorizar ESM sobre browser sobre UMD
|
|
257
|
-
const esmFiles = minifiedFiles.filter((file) => file.toLowerCase().includes('.esm.') ||
|
|
258
|
-
file.toLowerCase().includes('.module.'));
|
|
259
|
-
if (esmFiles.length > 0 && esmFiles[0]) {
|
|
260
|
-
const optimizedPath = join(dir, esmFiles[0]).replace(/\\/g, '/');
|
|
261
|
-
if (env.VERBOSE === 'true') {
|
|
262
|
-
logger.info(`Versión ESM minificada encontrada: ${optimizedPath}`);
|
|
263
|
-
}
|
|
264
|
-
return optimizedPath;
|
|
265
|
-
}
|
|
266
|
-
if (minifiedFiles[0]) {
|
|
267
|
-
const optimizedPath = join(dir, minifiedFiles[0]).replace(/\\/g, '/');
|
|
268
|
-
if (env.VERBOSE === 'true') {
|
|
269
|
-
logger.info(`Versión minificada encontrada: ${optimizedPath}`);
|
|
270
|
-
}
|
|
271
|
-
return optimizedPath;
|
|
272
|
-
}
|
|
229
|
+
else if (hasRuntime && hasEsmBrowser) {
|
|
230
|
+
if (!isProd && !isMin)
|
|
231
|
+
fileGroups.runtimeDev.push(file);
|
|
232
|
+
else
|
|
233
|
+
fileGroups.runtime.push(file);
|
|
273
234
|
}
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
if (runtimeFiles.length > 0) {
|
|
277
|
-
// Priorizar desarrollo sobre producción en runtime también
|
|
278
|
-
const devRuntimeFiles = runtimeFiles.filter((file) => !file.toLowerCase().includes('.prod.') &&
|
|
279
|
-
!file.toLowerCase().includes('.min.'));
|
|
280
|
-
if (devRuntimeFiles.length > 0 && devRuntimeFiles[0]) {
|
|
281
|
-
const optimizedPath = join(dir, devRuntimeFiles[0]).replace(/\\/g, '/');
|
|
282
|
-
if (env.VERBOSE === 'true') {
|
|
283
|
-
logger.info(`Versión Runtime ESM-Browser dev encontrada: ${optimizedPath}`);
|
|
284
|
-
}
|
|
285
|
-
return optimizedPath;
|
|
286
|
-
}
|
|
287
|
-
if (runtimeFiles[0]) {
|
|
288
|
-
const optimizedPath = join(dir, runtimeFiles[0]).replace(/\\/g, '/');
|
|
289
|
-
if (env.VERBOSE === 'true') {
|
|
290
|
-
logger.info(`Versión Runtime ESM-Browser encontrada: ${optimizedPath}`);
|
|
291
|
-
}
|
|
292
|
-
return optimizedPath;
|
|
293
|
-
}
|
|
235
|
+
else if (hasEsm || hasBrowser) {
|
|
236
|
+
fileGroups.other.push(file);
|
|
294
237
|
}
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
238
|
+
}
|
|
239
|
+
// Seleccionar archivo según prioridad y modo
|
|
240
|
+
const isProd = env.isPROD === 'true';
|
|
241
|
+
// Prioridad 1: ESM-Browser
|
|
242
|
+
if (isProd) {
|
|
243
|
+
if (fileGroups.esmBrowserProd[0]) {
|
|
244
|
+
const optimizedPath = join(dir, fileGroups.esmBrowserProd[0]).replace(/\\/g, '/');
|
|
245
|
+
if (env.VERBOSE === 'true')
|
|
246
|
+
logger.info(`🏭 Versión ESM-Browser producción encontrada: ${optimizedPath}`);
|
|
247
|
+
return optimizedPath;
|
|
248
|
+
}
|
|
249
|
+
if (fileGroups.esmBrowserMin[0]) {
|
|
250
|
+
const optimizedPath = join(dir, fileGroups.esmBrowserMin[0]).replace(/\\/g, '/');
|
|
251
|
+
if (env.VERBOSE === 'true')
|
|
252
|
+
logger.info(`🗜️ Versión ESM-Browser minificada encontrada: ${optimizedPath}`);
|
|
301
253
|
return optimizedPath;
|
|
302
254
|
}
|
|
303
255
|
}
|
|
256
|
+
if (fileGroups.esmBrowserDev[0]) {
|
|
257
|
+
const optimizedPath = join(dir, fileGroups.esmBrowserDev[0]).replace(/\\/g, '/');
|
|
258
|
+
if (env.VERBOSE === 'true')
|
|
259
|
+
logger.info(`🔧 Versión ESM-Browser desarrollo encontrada: ${optimizedPath}`);
|
|
260
|
+
return optimizedPath;
|
|
261
|
+
}
|
|
262
|
+
// Prioridad 2: ESM puro
|
|
263
|
+
if (isProd) {
|
|
264
|
+
if (fileGroups.esmProd[0]) {
|
|
265
|
+
const optimizedPath = join(dir, fileGroups.esmProd[0]).replace(/\\/g, '/');
|
|
266
|
+
if (env.VERBOSE === 'true')
|
|
267
|
+
logger.info(`Versión ESM producción encontrada: ${optimizedPath}`);
|
|
268
|
+
return optimizedPath;
|
|
269
|
+
}
|
|
270
|
+
if (fileGroups.esmMin[0]) {
|
|
271
|
+
const optimizedPath = join(dir, fileGroups.esmMin[0]).replace(/\\/g, '/');
|
|
272
|
+
if (env.VERBOSE === 'true')
|
|
273
|
+
logger.info(`Versión ESM minificada encontrada: ${optimizedPath}`);
|
|
274
|
+
return optimizedPath;
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
if (fileGroups.esmDev[0]) {
|
|
278
|
+
const optimizedPath = join(dir, fileGroups.esmDev[0]).replace(/\\/g, '/');
|
|
279
|
+
if (env.VERBOSE === 'true')
|
|
280
|
+
logger.info(`Versión ESM encontrada: ${optimizedPath}`);
|
|
281
|
+
return optimizedPath;
|
|
282
|
+
}
|
|
283
|
+
// Prioridad 3: Browser minificado
|
|
284
|
+
if (fileGroups.browserMin[0]) {
|
|
285
|
+
const optimizedPath = join(dir, fileGroups.browserMin[0]).replace(/\\/g, '/');
|
|
286
|
+
if (env.VERBOSE === 'true')
|
|
287
|
+
logger.info(`Versión browser minificada encontrada: ${optimizedPath}`);
|
|
288
|
+
return optimizedPath;
|
|
289
|
+
}
|
|
290
|
+
// Prioridad 4: Runtime
|
|
291
|
+
if (fileGroups.runtimeDev[0]) {
|
|
292
|
+
const optimizedPath = join(dir, fileGroups.runtimeDev[0]).replace(/\\/g, '/');
|
|
293
|
+
if (env.VERBOSE === 'true')
|
|
294
|
+
logger.info(`Versión Runtime ESM-Browser dev encontrada: ${optimizedPath}`);
|
|
295
|
+
return optimizedPath;
|
|
296
|
+
}
|
|
297
|
+
if (fileGroups.runtime[0]) {
|
|
298
|
+
const optimizedPath = join(dir, fileGroups.runtime[0]).replace(/\\/g, '/');
|
|
299
|
+
if (env.VERBOSE === 'true')
|
|
300
|
+
logger.info(`Versión Runtime ESM-Browser encontrada: ${optimizedPath}`);
|
|
301
|
+
return optimizedPath;
|
|
302
|
+
}
|
|
303
|
+
// Fallback: otros archivos browser/esm
|
|
304
|
+
if (fileGroups.other[0]) {
|
|
305
|
+
const optimizedPath = join(dir, fileGroups.other[0]).replace(/\\/g, '/');
|
|
306
|
+
if (env.VERBOSE === 'true')
|
|
307
|
+
logger.info(`Versión browser encontrada: ${optimizedPath}`);
|
|
308
|
+
return optimizedPath;
|
|
309
|
+
}
|
|
304
310
|
}
|
|
305
311
|
catch (error) {
|
|
306
312
|
if (env.VERBOSE === 'true') {
|
|
@@ -323,7 +329,9 @@ function simpleESMResolver(moduleName) {
|
|
|
323
329
|
catch {
|
|
324
330
|
return null;
|
|
325
331
|
}
|
|
326
|
-
const packageJson =
|
|
332
|
+
const packageJson = packageJsonCache.get(packagePath);
|
|
333
|
+
if (!packageJson)
|
|
334
|
+
return null;
|
|
327
335
|
const moduleDir = dirname(packagePath);
|
|
328
336
|
const isESM = packageJson.type === 'module'; // Determinar el entry point ESM/Browser optimizado
|
|
329
337
|
let entryPoint = null;
|
|
@@ -392,7 +400,7 @@ function simpleESMResolver(moduleName) {
|
|
|
392
400
|
entryPoint = isESM ? 'index.js' : 'index.cjs';
|
|
393
401
|
} // Resolver la ruta final
|
|
394
402
|
let finalPath = join(moduleDir, entryPoint);
|
|
395
|
-
// Buscar una versión ESM/browser optimizada
|
|
403
|
+
// Buscar una versión ESM/browser optimizada (garantizar que entryPoint es string)
|
|
396
404
|
const optimizedEntry = findOptimalESMVersion(moduleDir, entryPoint);
|
|
397
405
|
if (optimizedEntry && optimizedEntry !== entryPoint) {
|
|
398
406
|
finalPath = join(moduleDir, optimizedEntry);
|
|
@@ -507,7 +515,9 @@ export function getModuleSubPath(moduleName, fromFile) {
|
|
|
507
515
|
if (!fs.existsSync(packagePath)) {
|
|
508
516
|
return null;
|
|
509
517
|
}
|
|
510
|
-
const packageJson =
|
|
518
|
+
const packageJson = packageJsonCache.get(packagePath);
|
|
519
|
+
if (!packageJson)
|
|
520
|
+
return null;
|
|
511
521
|
const moduleDir = dirname(packagePath);
|
|
512
522
|
// Revisar exports field para subpaths
|
|
513
523
|
if (packageJson.exports &&
|
package/package.json
CHANGED
|
@@ -1,110 +1,111 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "versacompiler",
|
|
3
|
-
"version": "2.3.
|
|
4
|
-
"description": "Una herramienta para compilar y minificar archivos .vue, .js y .ts para proyectos de Vue 3 con soporte para TypeScript.",
|
|
5
|
-
"main": "dist/main.js",
|
|
6
|
-
"bin": {
|
|
7
|
-
"versacompiler": "dist/main.js"
|
|
8
|
-
},
|
|
9
|
-
"publishConfig": {
|
|
10
|
-
"access": "public"
|
|
11
|
-
},
|
|
12
|
-
"files": [
|
|
13
|
-
"dist",
|
|
14
|
-
"LICENSE",
|
|
15
|
-
"README.md"
|
|
16
|
-
],
|
|
17
|
-
"type": "module",
|
|
18
|
-
"scripts": {
|
|
19
|
-
"dev": "tsx --watch src/main.ts --watch --verbose --tailwind",
|
|
20
|
-
"file": "tsx src/main.ts ",
|
|
21
|
-
"compile": "tsx src/main.ts --all --cc -y --verbose --prod",
|
|
22
|
-
"compileDev": "tsx src/main.ts --all --cc -y --verbose",
|
|
23
|
-
"
|
|
24
|
-
"test
|
|
25
|
-
"test:
|
|
26
|
-
"test:
|
|
27
|
-
"
|
|
28
|
-
"
|
|
29
|
-
"lint
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
"
|
|
34
|
-
"
|
|
35
|
-
"
|
|
36
|
-
"
|
|
37
|
-
"
|
|
38
|
-
"
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
"
|
|
42
|
-
"
|
|
43
|
-
|
|
44
|
-
"
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
"
|
|
51
|
-
|
|
52
|
-
"@vue/
|
|
53
|
-
"@vue/
|
|
54
|
-
"@vue/runtime-
|
|
55
|
-
"
|
|
56
|
-
"
|
|
57
|
-
"
|
|
58
|
-
"
|
|
59
|
-
"
|
|
60
|
-
"
|
|
61
|
-
"
|
|
62
|
-
"
|
|
63
|
-
"
|
|
64
|
-
"
|
|
65
|
-
"
|
|
66
|
-
"oxc-
|
|
67
|
-
"oxc-
|
|
68
|
-
"
|
|
69
|
-
"
|
|
70
|
-
"
|
|
71
|
-
"
|
|
72
|
-
"
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
"@
|
|
77
|
-
"@
|
|
78
|
-
"@types/
|
|
79
|
-
"@types/
|
|
80
|
-
"@types/
|
|
81
|
-
"@types/
|
|
82
|
-
"@types/
|
|
83
|
-
"@types/
|
|
84
|
-
"@types/
|
|
85
|
-
"@
|
|
86
|
-
"@typescript-eslint/
|
|
87
|
-
"@
|
|
88
|
-
"@vitest/
|
|
89
|
-
"@
|
|
90
|
-
"@vue/
|
|
91
|
-
"
|
|
92
|
-
"
|
|
93
|
-
"eslint
|
|
94
|
-
"eslint-
|
|
95
|
-
"eslint-plugin-
|
|
96
|
-
"eslint-plugin-
|
|
97
|
-
"eslint-plugin-
|
|
98
|
-
"eslint-plugin-
|
|
99
|
-
"
|
|
100
|
-
"
|
|
101
|
-
"
|
|
102
|
-
"
|
|
103
|
-
"
|
|
104
|
-
"
|
|
105
|
-
"
|
|
106
|
-
"
|
|
107
|
-
"vue-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
1
|
+
{
|
|
2
|
+
"name": "versacompiler",
|
|
3
|
+
"version": "2.3.4",
|
|
4
|
+
"description": "Una herramienta para compilar y minificar archivos .vue, .js y .ts para proyectos de Vue 3 con soporte para TypeScript.",
|
|
5
|
+
"main": "dist/main.js",
|
|
6
|
+
"bin": {
|
|
7
|
+
"versacompiler": "dist/main.js"
|
|
8
|
+
},
|
|
9
|
+
"publishConfig": {
|
|
10
|
+
"access": "public"
|
|
11
|
+
},
|
|
12
|
+
"files": [
|
|
13
|
+
"dist",
|
|
14
|
+
"LICENSE",
|
|
15
|
+
"README.md"
|
|
16
|
+
],
|
|
17
|
+
"type": "module",
|
|
18
|
+
"scripts": {
|
|
19
|
+
"dev": "tsx --watch src/main.ts --watch --verbose --tailwind",
|
|
20
|
+
"file": "tsx src/main.ts ",
|
|
21
|
+
"compile": "tsx src/main.ts --all --cc --co -y --verbose --prod",
|
|
22
|
+
"compileDev": "tsx src/main.ts --all --cc -y --linter -t --verbose",
|
|
23
|
+
"vtlint": "tsx src/main.ts --all --cc --co -y -t",
|
|
24
|
+
"test": "vitest run",
|
|
25
|
+
"test:watch": "vitest",
|
|
26
|
+
"test:ui": "vitest --ui",
|
|
27
|
+
"test:coverage": "vitest run --coverage",
|
|
28
|
+
"build": "tsx src/main.ts --all -t --cc --co -y --verbose",
|
|
29
|
+
"lint": "oxlint --fix --config .oxlintrc.json",
|
|
30
|
+
"lint:eslint": "eslint --ext .js,.ts,.vue src/ --fix"
|
|
31
|
+
},
|
|
32
|
+
"keywords": [
|
|
33
|
+
"vue",
|
|
34
|
+
"compiler",
|
|
35
|
+
"minifier",
|
|
36
|
+
"vue3",
|
|
37
|
+
"versacompiler",
|
|
38
|
+
"typescript",
|
|
39
|
+
"linter"
|
|
40
|
+
],
|
|
41
|
+
"author": "Jorge Jara H (kriollone@gmail.com)",
|
|
42
|
+
"license": "MIT",
|
|
43
|
+
"repository": {
|
|
44
|
+
"type": "git",
|
|
45
|
+
"url": "git+https://github.com/kriollo/versaCompiler.git"
|
|
46
|
+
},
|
|
47
|
+
"bugs": {
|
|
48
|
+
"url": "https://github.com/kriollo/versaCompiler/issues"
|
|
49
|
+
},
|
|
50
|
+
"homepage": "https://github.com/kriollo/versaCompiler#readme",
|
|
51
|
+
"dependencies": {
|
|
52
|
+
"@vue/compiler-dom": "^3.5.27",
|
|
53
|
+
"@vue/reactivity": "^3.5.27",
|
|
54
|
+
"@vue/runtime-core": "^3.5.27",
|
|
55
|
+
"@vue/runtime-dom": "^3.5.27",
|
|
56
|
+
"browser-sync": "^3.0.4",
|
|
57
|
+
"chalk": "5.6.2",
|
|
58
|
+
"chokidar": "^5.0.0",
|
|
59
|
+
"enhanced-resolve": "^5.19.0",
|
|
60
|
+
"execa": "^9.6.1",
|
|
61
|
+
"find-root": "^1.1.0",
|
|
62
|
+
"fs-extra": "^11.3.3",
|
|
63
|
+
"get-port": "^7.1.0",
|
|
64
|
+
"minify-html-literals": "^1.3.5",
|
|
65
|
+
"minimatch": "^10.1.2",
|
|
66
|
+
"oxc-minify": "^0.112.0",
|
|
67
|
+
"oxc-parser": "^0.112.0",
|
|
68
|
+
"oxc-transform": "^0.112.0",
|
|
69
|
+
"resolve": "^1.22.11",
|
|
70
|
+
"tsx": "^4.21.0",
|
|
71
|
+
"typescript": "^5.9.3",
|
|
72
|
+
"vue": "3.5.27",
|
|
73
|
+
"yargs": "^18.0.0"
|
|
74
|
+
},
|
|
75
|
+
"devDependencies": {
|
|
76
|
+
"@eslint/eslintrc": "^3.3.3",
|
|
77
|
+
"@tailwindcss/cli": "^4.1.18",
|
|
78
|
+
"@types/browser-sync": "^2.29.1",
|
|
79
|
+
"@types/find-root": "^1.1.4",
|
|
80
|
+
"@types/fs-extra": "^11.0.4",
|
|
81
|
+
"@types/jest": "^30.0.0",
|
|
82
|
+
"@types/mocha": "^10.0.10",
|
|
83
|
+
"@types/node": "^25.2.0",
|
|
84
|
+
"@types/resolve": "^1.20.6",
|
|
85
|
+
"@types/yargs": "^17.0.35",
|
|
86
|
+
"@typescript-eslint/eslint-plugin": "^8.54.0",
|
|
87
|
+
"@typescript-eslint/parser": "^8.54.0",
|
|
88
|
+
"@vitest/coverage-v8": "^4.0.18",
|
|
89
|
+
"@vitest/ui": "^4.0.18",
|
|
90
|
+
"@vue/eslint-config-typescript": "^14.6.0",
|
|
91
|
+
"@vue/test-utils": "^2.4.6",
|
|
92
|
+
"code-tag": "^1.2.0",
|
|
93
|
+
"eslint": "^9.39.2",
|
|
94
|
+
"eslint-import-resolver-typescript": "^4.4.4",
|
|
95
|
+
"eslint-plugin-import": "^2.32.0",
|
|
96
|
+
"eslint-plugin-oxlint": "^1.43.0",
|
|
97
|
+
"eslint-plugin-promise": "^7.2.1",
|
|
98
|
+
"eslint-plugin-unicorn": "^62.0.0",
|
|
99
|
+
"eslint-plugin-vue": "^10.7.0",
|
|
100
|
+
"oxlint": "^1.43.0",
|
|
101
|
+
"pinia": "^3.0.4",
|
|
102
|
+
"prettier": "3.8.1",
|
|
103
|
+
"rimraf": "^6.1.2",
|
|
104
|
+
"sweetalert2": "^11.26.18",
|
|
105
|
+
"tailwindcss": "^4.1.18",
|
|
106
|
+
"vitest": "^4.0.18",
|
|
107
|
+
"vue-eslint-parser": "^10.2.0",
|
|
108
|
+
"vue-router": "^5.0.2"
|
|
109
|
+
},
|
|
110
|
+
"packageManager": "pnpm@10.15.0+sha512.486ebc259d3e999a4e8691ce03b5cac4a71cbeca39372a9b762cb500cfdf0873e2cb16abe3d951b1ee2cf012503f027b98b6584e4df22524e0c7450d9ec7aa7b"
|
|
111
|
+
}
|