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.
@@ -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
- const errorDetails = error instanceof Error ? error.stack : undefined;
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
- tsResult = await preCompileTS(code, inPath);
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}`);
@@ -1,5 +1,6 @@
1
1
  import { createHash } from 'node:crypto';
2
- import { minify } from 'oxc-minify';
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 = await minify(filename, data, options);
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
- console.warn(`⚠️ Minificación fallida para ${filename}, usando código original`);
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
- console.warn(`⚠️ Error al minificar ${filename}: ${error instanceof Error ? error.message : String(error)}`);
85
- console.warn(` Usando código original sin minificar`);
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
- console.warn('[MinificationCache] Error cacheando minificación:', error);
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
- console.warn('[MinifyTemplate] Error detectando template strings:', error);
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
- console.warn('[MinifyTemplate] Error removiendo tags temporales:', error);
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
- console.warn('[MinifyTemplate] Error minificando CSS:', error);
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
- console.warn(`[MinifyTemplate] minifyHTMLLiterals falló para ${fileName}, usando código sin minificar:`, parseError instanceof Error
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
- console.warn(`[MinifyTemplate] Error minificando plantilla ${fileName}:`, error);
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 = JSON.parse(env.PATH_ALIAS);
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 = JSON.parse(env.PATH_ALIAS);
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 = JSON.parse(env.PATH_ALIAS);
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.isProd === 'true') {
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
- // Usar el mejorador de errores para obtener mensaje detallado
9
- const enhancedMessage = enhanceErrorMessage(diagnostic, fileName, sourceCode); // Determinar la severidad
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.file && diagnostic.start !== undefined) {
24
- const sourceFile = diagnostic.file;
25
- // Verificar que el método getLineAndCharacterOfPosition existe (para compatibilidad con mocks)
26
- if (typeof sourceFile.getLineAndCharacterOfPosition === 'function') {
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 = sourceFile.getLineAndCharacterOfPosition(diagnostic.start);
29
- help += ` | Línea ${lineAndChar.line + 1}, Columna ${lineAndChar.character + 1}`;
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
- // Si falla, solo mostrar la posición de carácter
33
- help += ` | Posición ${diagnostic.start}`;
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 para cuando no está disponible el método (como en tests)
38
- help += ` | Posición ${diagnostic.start}`;
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: enhancedMessage,
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
- const line = lineAndChar.line + 1;
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 la posición de carácter
85
- location = `Posición ${diagnostic.start} | Código TS${diagnostic.code}`;
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 para cuando no está disponible el método (como en tests)
90
- location = `Posición ${diagnostic.start} | Código TS${diagnostic.code}`;
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
- const text = sourceCode || sourceFile.text;
178
+ // Obtener código fuente apropiado
179
+ const text = scriptInfo?.originalData || sourceCode || sourceFile.text;
97
180
  const lines = text.split('\n');
98
- const errorLine = lines[lineAndChar.line];
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, lineAndChar.line - 2);
102
- const endLine = Math.min(lines.length - 1, lineAndChar.line + 2);
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 === lineAndChar.line;
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: new Error(errorMessage),
286
+ error,
280
287
  data: null,
281
288
  lang: 'ts',
282
289
  };
@@ -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
- return {
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
- } // Buscar archivos que contengan patrones ESM/browser dinámicamente
145
- const esmBrowserFiles = files.filter((file) => {
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
- return ((lowerFile.includes('.esm-browser.') || // Prioridad alta: combinación esm-browser
148
- lowerFile.includes('.esm.') ||
149
- lowerFile.includes('.module.') ||
150
- lowerFile.includes('.browser.') ||
151
- lowerFile.includes('.web.') ||
152
- lowerFile.includes('.runtime.esm-browser.')) && // Runtime como última opción
153
- (file.endsWith('.js') || file.endsWith('.mjs')));
154
- });
155
- if (esmBrowserFiles.length > 0) {
156
- // Primera prioridad: archivos que combinan ESM y Browser (sin runtime)
157
- const esmBrowserCombined = esmBrowserFiles.filter((file) => file.toLowerCase().includes('.esm-browser.') &&
158
- !file.toLowerCase().includes('.runtime.'));
159
- if (esmBrowserCombined.length > 0) {
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
- // Segunda prioridad: cualquier versión ESM disponible
221
- if (env.isPROD === 'true') {
222
- // En producción, buscar versiones minificadas/prod primero
223
- const esmProdFiles = esmBrowserFiles.filter((file) => (file.toLowerCase().includes('.esm.') ||
224
- file.toLowerCase().includes('.module.')) &&
225
- (file.toLowerCase().includes('.prod.') ||
226
- file.toLowerCase().includes('.min.')) &&
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
- // En desarrollo, buscar versiones sin minificar
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
- // Tercera prioridad: archivos minificados de cualquier tipo ESM/browser (sin runtime)
252
- const minifiedFiles = esmBrowserFiles.filter((file) => (file.toLowerCase().includes('.min.') ||
253
- file.toLowerCase().includes('.prod.')) &&
254
- !file.toLowerCase().includes('.runtime.'));
255
- if (minifiedFiles.length > 0) {
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
- // Cuarta prioridad: versiones runtime como último recurso
275
- const runtimeFiles = esmBrowserFiles.filter((file) => file.toLowerCase().includes('.runtime.esm-browser.'));
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
- // Fallback: cualquier versión browser
296
- if (esmBrowserFiles[0]) {
297
- const optimizedPath = join(dir, esmBrowserFiles[0]).replace(/\\/g, '/');
298
- if (env.VERBOSE === 'true') {
299
- logger.info(`Versión browser encontrada: ${optimizedPath}`);
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 = JSON.parse(readFileSync(packagePath, 'utf-8'));
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 = JSON.parse(readFileSync(packagePath, 'utf-8'));
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.2",
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
- "test": "vitest run",
24
- "test:watch": "vitest",
25
- "test:ui": "vitest --ui",
26
- "test:coverage": "vitest run --coverage",
27
- "build": "tsx src/main.ts --all -t --cc --co -y --verbose",
28
- "lint": "oxlint --fix --config .oxlintrc.json",
29
- "lint:eslint": "eslint --ext .js,.ts,.vue src/ --fix"
30
- },
31
- "keywords": [
32
- "vue",
33
- "compiler",
34
- "minifier",
35
- "vue3",
36
- "versacompiler",
37
- "typescript",
38
- "linter"
39
- ],
40
- "author": "Jorge Jara H (kriollone@gmail.com)",
41
- "license": "MIT",
42
- "repository": {
43
- "type": "git",
44
- "url": "git+https://github.com/kriollo/versaCompiler.git"
45
- },
46
- "bugs": {
47
- "url": "https://github.com/kriollo/versaCompiler/issues"
48
- },
49
- "homepage": "https://github.com/kriollo/versaCompiler#readme",
50
- "dependencies": {
51
- "@vue/compiler-dom": "^3.5.26",
52
- "@vue/reactivity": "^3.5.26",
53
- "@vue/runtime-core": "^3.5.26",
54
- "@vue/runtime-dom": "^3.5.26",
55
- "browser-sync": "^3.0.4",
56
- "chalk": "5.6.2",
57
- "chokidar": "^5.0.0",
58
- "enhanced-resolve": "^5.18.4",
59
- "execa": "^9.6.1",
60
- "find-root": "^1.1.0",
61
- "fs-extra": "^11.3.3",
62
- "get-port": "^7.1.0",
63
- "minify-html-literals": "^1.3.5",
64
- "minimatch": "^10.1.1",
65
- "oxc-minify": "^0.108.0",
66
- "oxc-parser": "^0.108.0",
67
- "oxc-transform": "^0.108.0",
68
- "resolve": "^1.22.11",
69
- "tsx": "^4.21.0",
70
- "typescript": "^5.9.3",
71
- "vue": "3.5.26",
72
- "yargs": "^18.0.0"
73
- },
74
- "devDependencies": {
75
- "@eslint/eslintrc": "^3.3.3",
76
- "@tailwindcss/cli": "^4.1.18",
77
- "@types/browser-sync": "^2.29.1",
78
- "@types/find-root": "^1.1.4",
79
- "@types/fs-extra": "^11.0.4",
80
- "@types/jest": "^30.0.0",
81
- "@types/mocha": "^10.0.10",
82
- "@types/node": "^25.0.9",
83
- "@types/resolve": "^1.20.6",
84
- "@types/yargs": "^17.0.35",
85
- "@typescript-eslint/eslint-plugin": "^8.53.0",
86
- "@typescript-eslint/parser": "^8.53.0",
87
- "@vitest/coverage-v8": "^4.0.17",
88
- "@vitest/ui": "^4.0.17",
89
- "@vue/eslint-config-typescript": "^14.6.0",
90
- "@vue/test-utils": "^2.4.6",
91
- "code-tag": "^1.2.0",
92
- "eslint": "^9.39.2",
93
- "eslint-import-resolver-typescript": "^4.4.4",
94
- "eslint-plugin-import": "^2.32.0",
95
- "eslint-plugin-oxlint": "^1.39.0",
96
- "eslint-plugin-promise": "^7.2.1",
97
- "eslint-plugin-unicorn": "^62.0.0",
98
- "eslint-plugin-vue": "^10.6.2",
99
- "oxlint": "^1.39.0",
100
- "pinia": "^3.0.4",
101
- "prettier": "3.8.0",
102
- "rimraf": "^6.1.2",
103
- "sweetalert2": "^11.26.17",
104
- "tailwindcss": "^4.1.18",
105
- "vitest": "^4.0.17",
106
- "vue-eslint-parser": "^10.2.0",
107
- "vue-router": "^4.6.4"
108
- },
109
- "packageManager": "pnpm@10.15.0+sha512.486ebc259d3e999a4e8691ce03b5cac4a71cbeca39372a9b762cb500cfdf0873e2cb16abe3d951b1ee2cf012503f027b98b6584e4df22524e0c7450d9ec7aa7b"
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
+ }