versacompiler 2.0.0 → 2.0.2
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/README.md +345 -69
- package/dist/compiler/compile.js +762 -183
- package/dist/compiler/minify.js +199 -10
- package/dist/compiler/module-resolution-optimizer.js +822 -0
- package/dist/compiler/parser.js +179 -6
- package/dist/compiler/performance-monitor.js +192 -0
- package/dist/compiler/transform-optimizer.js +392 -0
- package/dist/compiler/transforms.js +124 -118
- package/dist/compiler/{typescript.js → typescript-compiler.js} +27 -30
- package/dist/compiler/typescript-error-parser.js +6 -7
- package/dist/compiler/typescript-manager.js +378 -0
- package/dist/compiler/typescript-sync-validator.js +13 -15
- package/dist/compiler/typescript-worker-pool.js +845 -0
- package/dist/compiler/typescript-worker.js +51 -21
- package/dist/compiler/vuejs.js +131 -37
- package/dist/main.js +5 -6
- package/dist/servicios/browserSync.js +313 -21
- package/dist/servicios/file-watcher.js +367 -0
- package/dist/servicios/logger.js +1 -0
- package/dist/servicios/readConfig.js +1 -0
- package/dist/utils/excluded-modules.js +36 -0
- package/dist/utils/module-resolver.js +9 -48
- package/dist/utils/promptUser.js +1 -1
- package/dist/utils/resolve-bin.js +28 -9
- package/package.json +8 -7
- package/dist/servicios/chokidar.js +0 -178
|
@@ -0,0 +1,367 @@
|
|
|
1
|
+
import { readdir, rm, stat, unlink } from 'node:fs/promises';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import process, { env } from 'node:process';
|
|
4
|
+
import * as chokidar from 'chokidar';
|
|
5
|
+
import { minimatch } from 'minimatch';
|
|
6
|
+
import { getOutputPath, initCompile, normalizeRuta } from '../compiler/compile.js';
|
|
7
|
+
import { promptUser } from '../utils/promptUser.js';
|
|
8
|
+
import { emitirCambios } from './browserSync.js';
|
|
9
|
+
import { logger } from './logger.js';
|
|
10
|
+
// Lazy loading para chalk
|
|
11
|
+
let chalk;
|
|
12
|
+
async function loadChalk() {
|
|
13
|
+
if (!chalk) {
|
|
14
|
+
chalk = (await import('chalk')).default;
|
|
15
|
+
}
|
|
16
|
+
return chalk;
|
|
17
|
+
}
|
|
18
|
+
class WatchDebouncer {
|
|
19
|
+
pendingChanges = new Map();
|
|
20
|
+
debounceTimer = null;
|
|
21
|
+
DEBOUNCE_DELAY = 300; // 300ms debounce
|
|
22
|
+
BATCH_SIZE = 10; // Máximo archivos por batch
|
|
23
|
+
isProcessing = false;
|
|
24
|
+
browserSyncInstance = null; // ✨ Almacenar referencia a browserSync
|
|
25
|
+
/**
|
|
26
|
+
* Establece la instancia de browserSync
|
|
27
|
+
*/
|
|
28
|
+
setBrowserSyncInstance(bs) {
|
|
29
|
+
this.browserSyncInstance = bs;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Añade un cambio al sistema de debouncing
|
|
33
|
+
*/
|
|
34
|
+
addChange(filePath, action, extensionAction, isAdditionalFile = false) {
|
|
35
|
+
// Normalizar ruta para evitar duplicados
|
|
36
|
+
const normalizedPath = normalizeRuta(filePath);
|
|
37
|
+
// Agregar o actualizar el cambio pendiente
|
|
38
|
+
this.pendingChanges.set(normalizedPath, {
|
|
39
|
+
filePath: normalizedPath,
|
|
40
|
+
action,
|
|
41
|
+
timestamp: Date.now(),
|
|
42
|
+
extensionAction,
|
|
43
|
+
isAdditionalFile,
|
|
44
|
+
});
|
|
45
|
+
// Reiniciar el timer de debounce
|
|
46
|
+
this.resetDebounceTimer();
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Reinicia el timer de debounce
|
|
50
|
+
*/
|
|
51
|
+
resetDebounceTimer() {
|
|
52
|
+
if (this.debounceTimer) {
|
|
53
|
+
clearTimeout(this.debounceTimer);
|
|
54
|
+
}
|
|
55
|
+
this.debounceTimer = setTimeout(() => {
|
|
56
|
+
this.processPendingChanges();
|
|
57
|
+
}, this.DEBOUNCE_DELAY);
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Procesa todos los cambios pendientes en batch
|
|
61
|
+
*/
|
|
62
|
+
async processPendingChanges() {
|
|
63
|
+
if (this.isProcessing || this.pendingChanges.size === 0) {
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
this.isProcessing = true;
|
|
67
|
+
const changes = Array.from(this.pendingChanges.values());
|
|
68
|
+
this.pendingChanges.clear();
|
|
69
|
+
try {
|
|
70
|
+
// Agrupar por tipo de acción para optimización
|
|
71
|
+
const deleteChanges = changes.filter(c => c.action === 'unlink');
|
|
72
|
+
const compileChanges = changes.filter(c => c.action === 'add' || c.action === 'change');
|
|
73
|
+
// Procesar eliminaciones primero
|
|
74
|
+
if (deleteChanges.length > 0) {
|
|
75
|
+
await this.processDeleteChanges(deleteChanges);
|
|
76
|
+
}
|
|
77
|
+
// Procesar compilaciones en batches
|
|
78
|
+
if (compileChanges.length > 0) {
|
|
79
|
+
await this.processCompileChanges(compileChanges);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
catch (error) {
|
|
83
|
+
const chalkInstance = await loadChalk();
|
|
84
|
+
logger.error(chalkInstance.red(`🚩 Error procesando cambios en batch: ${error instanceof Error ? error.message : String(error)}`));
|
|
85
|
+
}
|
|
86
|
+
finally {
|
|
87
|
+
this.isProcessing = false;
|
|
88
|
+
// Si hay más cambios pendientes, procesarlos
|
|
89
|
+
if (this.pendingChanges.size > 0) {
|
|
90
|
+
this.resetDebounceTimer();
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
} /**
|
|
94
|
+
* Procesa cambios de eliminación
|
|
95
|
+
*/
|
|
96
|
+
async processDeleteChanges(deleteChanges) {
|
|
97
|
+
for (const change of deleteChanges) {
|
|
98
|
+
if (change.isAdditionalFile) {
|
|
99
|
+
// ✨ Archivos adicionales: solo reload, sin eliminar del output
|
|
100
|
+
logger.info(`\n🗑️ Archivo adicional eliminado: ${change.filePath}`);
|
|
101
|
+
emitirCambios(this.browserSyncInstance, 'reloadFull', change.filePath);
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
// Archivos compilables: eliminar del output
|
|
105
|
+
logger.info(`\n🗑️ Eliminando archivo compilado: ${change.filePath}`);
|
|
106
|
+
const result = await deleteFile(getOutputPath(change.filePath));
|
|
107
|
+
if (result) {
|
|
108
|
+
logger.info(`Archivo eliminado: ${change.filePath}`);
|
|
109
|
+
emitirCambios(this.browserSyncInstance, 'reloadFull', change.filePath);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Procesa cambios de compilación en paralelo con límite de concurrencia
|
|
116
|
+
*/
|
|
117
|
+
async processCompileChanges(compileChanges) {
|
|
118
|
+
// ✨ NUEVO: Separar archivos adicionales de archivos compilables
|
|
119
|
+
const additionalFiles = compileChanges.filter(c => c.isAdditionalFile);
|
|
120
|
+
const compilableFiles = compileChanges.filter(c => !c.isAdditionalFile);
|
|
121
|
+
// ✨ Procesar archivos adicionales (solo reload, sin compilación)
|
|
122
|
+
if (additionalFiles.length > 0) {
|
|
123
|
+
await this.processAdditionalFiles(additionalFiles);
|
|
124
|
+
}
|
|
125
|
+
// Procesar archivos compilables normalmente
|
|
126
|
+
if (compilableFiles.length > 0) {
|
|
127
|
+
await this.processCompilableFiles(compilableFiles);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* ✨ RENOMBRADO: Procesa archivos compilables
|
|
132
|
+
*/
|
|
133
|
+
async processCompilableFiles(compilableFiles) {
|
|
134
|
+
const chalkInstance = await loadChalk();
|
|
135
|
+
// Procesar en batches para evitar sobrecarga
|
|
136
|
+
for (let i = 0; i < compilableFiles.length; i += this.BATCH_SIZE) {
|
|
137
|
+
const batch = compilableFiles.slice(i, i + this.BATCH_SIZE);
|
|
138
|
+
if (batch.length > 1) {
|
|
139
|
+
logger.info(chalkInstance.cyan(`📦 Procesando batch de ${batch.length} archivos compilables (${i + 1}-${Math.min(i + this.BATCH_SIZE, compilableFiles.length)} de ${compilableFiles.length})`));
|
|
140
|
+
}
|
|
141
|
+
const promises = batch.map(change => this.compileFile(change));
|
|
142
|
+
await Promise.allSettled(promises);
|
|
143
|
+
}
|
|
144
|
+
if (compilableFiles.length > 1) {
|
|
145
|
+
logger.info(chalkInstance.green(`✅ Batch completado: ${compilableFiles.length} archivos compilados`));
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* ✨ NUEVO: Procesa archivos adicionales (solo reloadFull)
|
|
150
|
+
*/
|
|
151
|
+
async processAdditionalFiles(additionalFiles) {
|
|
152
|
+
const chalkInstance = await loadChalk();
|
|
153
|
+
logger.info(chalkInstance.blue(`🔄 Recargando ${additionalFiles.length} archivo(s) adicional(es) (sin compilación)`));
|
|
154
|
+
for (const change of additionalFiles) {
|
|
155
|
+
logger.info(`📄 Archivo adicional modificado: ${change.filePath}`);
|
|
156
|
+
// Solo hacer reloadFull, sin compilación
|
|
157
|
+
emitirCambios(this.browserSyncInstance, 'reloadFull', change.filePath);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Compila un archivo individual
|
|
162
|
+
*/
|
|
163
|
+
async compileFile(change) {
|
|
164
|
+
try {
|
|
165
|
+
const result = await initCompile(change.filePath, true, 'watch');
|
|
166
|
+
if (result.success) {
|
|
167
|
+
let accion = result.action || change.extensionAction;
|
|
168
|
+
accion =
|
|
169
|
+
accion === 'extension' ? change.extensionAction : accion;
|
|
170
|
+
emitirCambios(this.browserSyncInstance, accion || 'reloadFull', result.output);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
catch (error) {
|
|
174
|
+
const chalkInstance = await loadChalk();
|
|
175
|
+
logger.error(chalkInstance.red(`🚩 Error compilando ${change.filePath}: ${error instanceof Error ? error.message : String(error)}`));
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Obtiene estadísticas del debouncer
|
|
180
|
+
*/
|
|
181
|
+
getStats() {
|
|
182
|
+
return {
|
|
183
|
+
pendingChanges: this.pendingChanges.size,
|
|
184
|
+
isProcessing: this.isProcessing,
|
|
185
|
+
hasTimer: this.debounceTimer !== null,
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
// Instancia global del debouncer
|
|
190
|
+
const watchDebouncer = new WatchDebouncer();
|
|
191
|
+
// const cacheImportMap = new Map<string, string[]>();
|
|
192
|
+
// const cacheComponentMap = new Map<string, string[]>();
|
|
193
|
+
export async function cleanOutputDir(outputDir, primerInteraccion = true) {
|
|
194
|
+
try {
|
|
195
|
+
if (!outputDir) {
|
|
196
|
+
throw new Error('El directorio de salida no está definido');
|
|
197
|
+
}
|
|
198
|
+
if (primerInteraccion) {
|
|
199
|
+
const stats = await stat(outputDir).catch(() => null);
|
|
200
|
+
if (!stats || !stats.isDirectory()) {
|
|
201
|
+
logger.error(`🚩 El directorio de salida no existe o no es un directorio: ${outputDir}`);
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
try {
|
|
205
|
+
if (env.yes === 'false') {
|
|
206
|
+
const chalkInstance = await loadChalk();
|
|
207
|
+
const answer = await promptUser('\n\n¿Estás seguro deseas limpiar la carpeta ' +
|
|
208
|
+
chalkInstance.yellow(outputDir) +
|
|
209
|
+
'? (s / N) : ');
|
|
210
|
+
if (answer.toLowerCase() !== 's') {
|
|
211
|
+
logger.info('🛑 Compilación cancelada por el usuario.');
|
|
212
|
+
process.exit(0);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
catch (error) {
|
|
217
|
+
logger.error(`Error en la entrada del usuario: ${error}`);
|
|
218
|
+
process.exit(1);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
const chalkInstance = await loadChalk();
|
|
222
|
+
logger.info(`🗑️ Limpiando directorio de salida: ${chalkInstance.yellow(outputDir)}\n`);
|
|
223
|
+
const items = await readdir(outputDir);
|
|
224
|
+
await Promise.all(items.map(async (item) => {
|
|
225
|
+
const itemPath = path.join(outputDir, item);
|
|
226
|
+
const itemStat = await stat(itemPath);
|
|
227
|
+
if (itemStat.isDirectory()) {
|
|
228
|
+
await rm(itemPath, { recursive: true });
|
|
229
|
+
}
|
|
230
|
+
else {
|
|
231
|
+
await unlink(itemPath);
|
|
232
|
+
}
|
|
233
|
+
}));
|
|
234
|
+
logger.info(`✅ Directorio limpiado: ${outputDir}`);
|
|
235
|
+
}
|
|
236
|
+
catch (error) {
|
|
237
|
+
logger.error(`🚩 Error al limpiar directorio de salida: ${error instanceof Error ? error.message : String(error)}`);
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
async function deleteFile(filePath) {
|
|
241
|
+
try {
|
|
242
|
+
await unlink(filePath);
|
|
243
|
+
return true;
|
|
244
|
+
}
|
|
245
|
+
catch (error) {
|
|
246
|
+
logger.error(`🚩 Error eliminando archivo ${filePath}: ${error instanceof Error ? error.message : String(error)}`);
|
|
247
|
+
return false;
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
function getAction(ruta, extendsionWatch) {
|
|
251
|
+
const action = extendsionWatch
|
|
252
|
+
.filter((item) => item !== undefined)
|
|
253
|
+
.find(item => item.ext === ruta.split('.').pop())?.action;
|
|
254
|
+
return action || 'reloadFull';
|
|
255
|
+
}
|
|
256
|
+
/**
|
|
257
|
+
* Verifica si un archivo pertenece a las rutas adicionales (no compilables)
|
|
258
|
+
*/
|
|
259
|
+
function isAdditionalWatchFile(filePath, additionalPatterns) {
|
|
260
|
+
if (!additionalPatterns || additionalPatterns.length === 0) {
|
|
261
|
+
return false;
|
|
262
|
+
}
|
|
263
|
+
const normalizedPath = normalizeRuta(filePath);
|
|
264
|
+
return additionalPatterns.some(pattern => {
|
|
265
|
+
// Normalizar el patrón también
|
|
266
|
+
const normalizedPattern = pattern.replace(/\\/g, '/');
|
|
267
|
+
return minimatch(normalizedPath, normalizedPattern);
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
export async function initChokidar(bs) {
|
|
271
|
+
try {
|
|
272
|
+
if (!env.PATH_SOURCE) {
|
|
273
|
+
logger.error('Error: La variable de entorno PATH_SOURCE no está definida.');
|
|
274
|
+
process.exit(1);
|
|
275
|
+
}
|
|
276
|
+
const watchJS = `${env.PATH_SOURCE}/**/*.js`;
|
|
277
|
+
const watchVue = `${env.PATH_SOURCE}/**/*.vue`;
|
|
278
|
+
const watchTS = `${env.PATH_SOURCE}/**/*.ts`;
|
|
279
|
+
const watchCJS = `${env.PATH_SOURCE}/**/*.cjs`;
|
|
280
|
+
const watchMJS = `${env.PATH_SOURCE}/**/*.mjs`;
|
|
281
|
+
//TODO: agregar watch para CSS
|
|
282
|
+
const watchAditional = JSON.parse(env.aditionalWatch || '[]');
|
|
283
|
+
let fileWatch = [
|
|
284
|
+
watchJS,
|
|
285
|
+
watchVue,
|
|
286
|
+
watchTS,
|
|
287
|
+
watchCJS,
|
|
288
|
+
watchMJS,
|
|
289
|
+
...watchAditional,
|
|
290
|
+
];
|
|
291
|
+
//extraer sólo las extesniones de fileWatch
|
|
292
|
+
const accionExtension = {
|
|
293
|
+
vue: 'HRMVue',
|
|
294
|
+
js: 'HRMHelper',
|
|
295
|
+
ts: 'HRMHelper',
|
|
296
|
+
cjs: 'HRMHelper',
|
|
297
|
+
mjs: 'HRMHelper',
|
|
298
|
+
};
|
|
299
|
+
const extendsionWatch = fileWatch.map(item => {
|
|
300
|
+
const ext = item.split('.').pop();
|
|
301
|
+
if (ext) {
|
|
302
|
+
return {
|
|
303
|
+
ext,
|
|
304
|
+
action: accionExtension[ext] ||
|
|
305
|
+
'reloadFull',
|
|
306
|
+
};
|
|
307
|
+
}
|
|
308
|
+
});
|
|
309
|
+
if (extendsionWatch.length === 0 || extendsionWatch[0] === undefined) {
|
|
310
|
+
throw new Error('No se encontraron extensiones para observar');
|
|
311
|
+
}
|
|
312
|
+
const regExtExtension = new RegExp(`\\.(?!${extendsionWatch
|
|
313
|
+
.filter(item => item !== undefined)
|
|
314
|
+
.map(item => item.ext)
|
|
315
|
+
.join('$|')}$).+$`);
|
|
316
|
+
fileWatch = fileWatch.map(item => item.replace(/\/\*\*\//g, '/'));
|
|
317
|
+
const directories = new Map();
|
|
318
|
+
fileWatch.forEach(item => {
|
|
319
|
+
const dir = item.substring(0, item.lastIndexOf('/'));
|
|
320
|
+
if (!directories.has(dir)) {
|
|
321
|
+
directories.set(dir, []);
|
|
322
|
+
}
|
|
323
|
+
directories.get(dir).push(item);
|
|
324
|
+
});
|
|
325
|
+
const DirWatch = Array.from(directories.keys());
|
|
326
|
+
const watcher = chokidar.watch(DirWatch, {
|
|
327
|
+
persistent: true,
|
|
328
|
+
ignoreInitial: true,
|
|
329
|
+
ignored: regExtExtension,
|
|
330
|
+
});
|
|
331
|
+
watcher.on('ready', async () => {
|
|
332
|
+
const chalkInstance = await loadChalk();
|
|
333
|
+
logger.info(chalkInstance.green(`👀 : Listo para observar \n${fileWatch
|
|
334
|
+
.map((item) => `${item}`)
|
|
335
|
+
.join('\n')}\n`));
|
|
336
|
+
});
|
|
337
|
+
// ✨ CONFIGURAR: Establecer la instancia de browserSync en el debouncer
|
|
338
|
+
watchDebouncer.setBrowserSyncInstance(bs);
|
|
339
|
+
// ✨ OPTIMIZADO: Evento cuando se añade un archivo - Con debouncing
|
|
340
|
+
watcher.on('add', async (ruta) => {
|
|
341
|
+
const isAdditional = isAdditionalWatchFile(ruta, watchAditional);
|
|
342
|
+
const action = getAction(ruta, extendsionWatch.filter((item) => item !== undefined));
|
|
343
|
+
// Usar sistema de debouncing en lugar de compilación inmediata
|
|
344
|
+
watchDebouncer.addChange(ruta, 'add', action, isAdditional);
|
|
345
|
+
});
|
|
346
|
+
// ✨ OPTIMIZADO: Evento cuando se modifica un archivo - Con debouncing
|
|
347
|
+
watcher.on('change', async (ruta) => {
|
|
348
|
+
const isAdditional = isAdditionalWatchFile(ruta, watchAditional);
|
|
349
|
+
const action = getAction(ruta, extendsionWatch.filter((item) => item !== undefined));
|
|
350
|
+
// Usar sistema de debouncing en lugar de compilación inmediata
|
|
351
|
+
watchDebouncer.addChange(ruta, 'change', action, isAdditional);
|
|
352
|
+
});
|
|
353
|
+
// ✨ OPTIMIZADO: Evento cuando se elimina un archivo - Con debouncing
|
|
354
|
+
watcher.on('unlink', async (ruta) => {
|
|
355
|
+
const action = getAction(ruta, extendsionWatch.filter((item) => item !== undefined));
|
|
356
|
+
const isAdditional = isAdditionalWatchFile(ruta, watchAditional);
|
|
357
|
+
// Usar sistema de debouncing para eliminaciones también
|
|
358
|
+
watchDebouncer.addChange(ruta, 'unlink', action, isAdditional);
|
|
359
|
+
});
|
|
360
|
+
return watcher;
|
|
361
|
+
}
|
|
362
|
+
catch (error) {
|
|
363
|
+
logger.error(`🚩 :Error al iniciar watch: ${error instanceof Error ? error.message : String(error)}`);
|
|
364
|
+
process.exit(1);
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
//# sourceMappingURL=file-watcher.js.map
|
package/dist/servicios/logger.js
CHANGED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lista centralizada de módulos excluidos de la resolución automática
|
|
3
|
+
* Estos módulos se mantienen con su importación original sin transformar
|
|
4
|
+
*/
|
|
5
|
+
export const EXCLUDED_MODULES = new Set([
|
|
6
|
+
// Módulos de Vue.js que requieren resolución específica
|
|
7
|
+
'vue/compiler-sfc',
|
|
8
|
+
'vue/dist/vue.runtime.esm-bundler',
|
|
9
|
+
'@vue/compiler-sfc',
|
|
10
|
+
'@vue/compiler-dom',
|
|
11
|
+
'@vue/runtime-core',
|
|
12
|
+
'@vue/runtime-dom',
|
|
13
|
+
// Módulos de oxc-parser que tienen dependencias específicas de WASM
|
|
14
|
+
'oxc-parser',
|
|
15
|
+
'oxc-parser/wasm',
|
|
16
|
+
'oxc-minify',
|
|
17
|
+
'oxc-minify/browser',
|
|
18
|
+
'@oxc-parser/binding-wasm32-wasi',
|
|
19
|
+
'@oxc-minify/binding-wasm32-wasi',
|
|
20
|
+
// Módulos de TypeScript que pueden tener resoluciones complejas
|
|
21
|
+
'typescript',
|
|
22
|
+
'typescript/lib/typescript',
|
|
23
|
+
// Módulos de herramientas de build y utilidades que deben mantenerse originales
|
|
24
|
+
'yargs',
|
|
25
|
+
'yargs/helpers',
|
|
26
|
+
'yargs-parser',
|
|
27
|
+
'chalk',
|
|
28
|
+
'browser-sync',
|
|
29
|
+
'chokidar',
|
|
30
|
+
'get-port',
|
|
31
|
+
'execa',
|
|
32
|
+
'find-root',
|
|
33
|
+
'fs-extra',
|
|
34
|
+
'minimatch', // ✅ Incluir minimatch aquí
|
|
35
|
+
]);
|
|
36
|
+
//# sourceMappingURL=excluded-modules.js.map
|
|
@@ -1,39 +1,11 @@
|
|
|
1
1
|
// Opción con librería '/node_modules/resolve/index.js' (npm install resolve)
|
|
2
2
|
import fs, { readFileSync } from 'node:fs';
|
|
3
3
|
import { dirname, join, relative } from 'node:path';
|
|
4
|
-
import { env } from 'node:process';
|
|
5
|
-
// import pkg from '/node_modules/enhanced-resolve/index.
|
|
4
|
+
import { cwd, env } from 'node:process';
|
|
5
|
+
// import pkg from '/node_modules/enhanced-resolve/lib/index.js';
|
|
6
6
|
// import resolve from '/node_modules/resolve/index.js';
|
|
7
7
|
import { logger } from '../servicios/logger.js';
|
|
8
|
-
|
|
9
|
-
// Estos módulos se mantienen con su importación original sin transformar
|
|
10
|
-
const EXCLUDED_MODULES = new Set([
|
|
11
|
-
'vue/compiler-sfc',
|
|
12
|
-
'vue/dist/vue.runtime.esm-bundler',
|
|
13
|
-
'@vue/compiler-sfc',
|
|
14
|
-
'@vue/compiler-dom',
|
|
15
|
-
'@vue/runtime-core',
|
|
16
|
-
'@vue/runtime-dom', // Módulos de oxc-parser que tienen dependencias específicas de WASM
|
|
17
|
-
'oxc-parser',
|
|
18
|
-
'oxc-parser/wasm',
|
|
19
|
-
'oxc-minify',
|
|
20
|
-
'oxc-minify/browser',
|
|
21
|
-
'@oxc-parser/binding-wasm32-wasi',
|
|
22
|
-
'@oxc-minify/binding-wasm32-wasi',
|
|
23
|
-
// Módulos de TypeScript que pueden tener resoluciones complejas
|
|
24
|
-
'typescript',
|
|
25
|
-
// Agregar más módulos problemáticos aquí según sea necesario
|
|
26
|
-
'yargs',
|
|
27
|
-
'yargs/helpers',
|
|
28
|
-
'yargs-parser',
|
|
29
|
-
'chalk',
|
|
30
|
-
'browser-sync',
|
|
31
|
-
'chokidar',
|
|
32
|
-
'get-port',
|
|
33
|
-
'execa',
|
|
34
|
-
'find-root',
|
|
35
|
-
'fs-extra',
|
|
36
|
-
]);
|
|
8
|
+
import { EXCLUDED_MODULES } from './excluded-modules.js';
|
|
37
9
|
// function resolveESMWithLibrary(moduleName: string): string | null {
|
|
38
10
|
// try {
|
|
39
11
|
// // Resolver el módulo
|
|
@@ -58,7 +30,7 @@ const EXCLUDED_MODULES = new Set([
|
|
|
58
30
|
// return null;
|
|
59
31
|
// }
|
|
60
32
|
// }
|
|
61
|
-
// Opción con '/node_modules/enhanced-resolve/index.
|
|
33
|
+
// Opción con '/node_modules/enhanced-resolve/lib/index.js' (webpack's resolver)
|
|
62
34
|
// npm install enhanced-resolve
|
|
63
35
|
// const { ResolverFactory } = pkg;
|
|
64
36
|
// const resolver = ResolverFactory.createResolver({
|
|
@@ -128,9 +100,6 @@ function findOptimalESMVersion(moduleDir, entryPoint) {
|
|
|
128
100
|
for (const pattern of priorityPatterns) {
|
|
129
101
|
if (files.includes(pattern)) {
|
|
130
102
|
const optimizedPath = join(dir, pattern).replace(/\\/g, '/');
|
|
131
|
-
if (env.VERBOSE === 'true') {
|
|
132
|
-
logger.info(`Versión optimizada encontrada: ${optimizedPath}`);
|
|
133
|
-
}
|
|
134
103
|
return optimizedPath;
|
|
135
104
|
}
|
|
136
105
|
} // Buscar archivos que contengan patrones ESM/browser dinámicamente
|
|
@@ -154,9 +123,6 @@ function findOptimalESMVersion(moduleDir, entryPoint) {
|
|
|
154
123
|
!file.toLowerCase().includes('.min.'));
|
|
155
124
|
if (devFiles.length > 0 && devFiles[0]) {
|
|
156
125
|
const optimizedPath = join(dir, devFiles[0]).replace(/\\/g, '/');
|
|
157
|
-
if (env.VERBOSE === 'true') {
|
|
158
|
-
logger.info(`Versión ESM-Browser dev encontrada: ${optimizedPath}`);
|
|
159
|
-
}
|
|
160
126
|
return optimizedPath;
|
|
161
127
|
}
|
|
162
128
|
const prodFiles = esmBrowserCombined.filter(file => file.toLowerCase().includes('.prod.'));
|
|
@@ -260,7 +226,7 @@ function findOptimalESMVersion(moduleDir, entryPoint) {
|
|
|
260
226
|
// Función mejorada para detectar automáticamente entry points browser-compatible
|
|
261
227
|
function simpleESMResolver(moduleName) {
|
|
262
228
|
try {
|
|
263
|
-
const nodeModulesPath = join(
|
|
229
|
+
const nodeModulesPath = join(cwd(), 'node_modules', moduleName);
|
|
264
230
|
let packagePath;
|
|
265
231
|
let packageJson;
|
|
266
232
|
try {
|
|
@@ -370,7 +336,8 @@ function simpleESMResolver(moduleName) {
|
|
|
370
336
|
if (env.VERBOSE === 'true')
|
|
371
337
|
logger.info(`Módulo ${moduleName} usa imports privados:`, privateImports.map(m => m[1]));
|
|
372
338
|
// Si usa imports privados, asegurarnos de que estén disponibles
|
|
373
|
-
for (const
|
|
339
|
+
for (const match of privateImports) {
|
|
340
|
+
const [, importPath] = match;
|
|
374
341
|
if (!importMap.has(importPath)) {
|
|
375
342
|
if (env.VERBOSE === 'true')
|
|
376
343
|
logger.warn(`Import privado no resuelto: ${importPath} en ${moduleName}`);
|
|
@@ -381,8 +348,6 @@ function simpleESMResolver(moduleName) {
|
|
|
381
348
|
}
|
|
382
349
|
// Verificar que el archivo existe
|
|
383
350
|
if (!fs.existsSync(finalPath)) {
|
|
384
|
-
if (env.VERBOSE === 'true')
|
|
385
|
-
logger.warn(`⚠️ Archivo no existe: ${finalPath}, buscando alternativas...`);
|
|
386
351
|
// Intentar alternativas comunes
|
|
387
352
|
const alternatives = [
|
|
388
353
|
entryPoint,
|
|
@@ -422,7 +387,7 @@ function getNodeModulesRelativePath(fullPath, _fromFile) {
|
|
|
422
387
|
return '/' + relativePath;
|
|
423
388
|
}
|
|
424
389
|
// Para rutas que no están en node_modules, convertir a ruta absoluta desde la raíz
|
|
425
|
-
let rel = relative(
|
|
390
|
+
let rel = relative(cwd(), fullPath).replace(/\\/g, '/');
|
|
426
391
|
if (!rel)
|
|
427
392
|
rel = '.';
|
|
428
393
|
// Convertir a ruta absoluta desde la raíz
|
|
@@ -434,8 +399,6 @@ function getNodeModulesRelativePath(fullPath, _fromFile) {
|
|
|
434
399
|
export function getModulePath(moduleName, fromFile) {
|
|
435
400
|
// Verificar si el módulo está en la lista de excluidos
|
|
436
401
|
if (EXCLUDED_MODULES.has(moduleName)) {
|
|
437
|
-
if (env.VERBOSE === 'true')
|
|
438
|
-
logger.info(`Módulo ${moduleName} está en la lista de excluidos, manteniendo importación original`);
|
|
439
402
|
return null; // Retornar null para mantener la importación original
|
|
440
403
|
}
|
|
441
404
|
return getNodeModulesRelativePath(simpleESMResolver(moduleName), fromFile);
|
|
@@ -444,8 +407,6 @@ export function getModulePath(moduleName, fromFile) {
|
|
|
444
407
|
export function getModuleSubPath(moduleName, fromFile) {
|
|
445
408
|
// Verificar si el módulo está en la lista de excluidos
|
|
446
409
|
if (EXCLUDED_MODULES.has(moduleName)) {
|
|
447
|
-
if (env.VERBOSE === 'true')
|
|
448
|
-
logger.info(`Módulo ${moduleName} está en la lista de excluidos, manteniendo importación original`);
|
|
449
410
|
return null; // Retornar null para mantener la importación original
|
|
450
411
|
} // Si contiene '/', es un subpath
|
|
451
412
|
if (moduleName.includes('/')) {
|
|
@@ -456,7 +417,7 @@ export function getModuleSubPath(moduleName, fromFile) {
|
|
|
456
417
|
return null;
|
|
457
418
|
}
|
|
458
419
|
try {
|
|
459
|
-
const nodeModulesPath = join(
|
|
420
|
+
const nodeModulesPath = join(cwd(), 'node_modules', packageName);
|
|
460
421
|
const packagePath = join(nodeModulesPath, 'package.json');
|
|
461
422
|
if (!fs.existsSync(packagePath)) {
|
|
462
423
|
return null;
|
package/dist/utils/promptUser.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { stdin as input, stdout as output } from 'node:process';
|
|
1
|
+
import process, { stdin as input, stdout as output } from 'node:process';
|
|
2
2
|
import * as readline from 'node:readline/promises';
|
|
3
3
|
import { logger } from '../servicios/logger.js';
|
|
4
4
|
export async function promptUser(question, timeout = 30000) {
|
|
@@ -1,19 +1,38 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
1
|
+
import * as path from 'node:path';
|
|
2
|
+
import * as process from 'node:process';
|
|
3
3
|
import findRoot from 'find-root';
|
|
4
4
|
import fs from 'fs-extra';
|
|
5
|
+
// Función helper para resolver módulos sin createRequire
|
|
6
|
+
function resolveModule(moduleName, paths) {
|
|
7
|
+
for (const searchPath of paths) {
|
|
8
|
+
try {
|
|
9
|
+
const nodeModulesPath = path.join(searchPath, 'node_modules', moduleName);
|
|
10
|
+
if (fs.existsSync(nodeModulesPath)) {
|
|
11
|
+
return nodeModulesPath;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
catch {
|
|
15
|
+
// Continuar con el siguiente path
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
throw new Error(`Cannot resolve module ${moduleName} from paths: ${paths.join(', ')}`);
|
|
19
|
+
}
|
|
5
20
|
export function resolveBin(moduleName, { executable = moduleName, paths = [process.cwd()], } = {}) {
|
|
6
21
|
let rootDir;
|
|
7
22
|
try {
|
|
8
|
-
const
|
|
9
|
-
const resolved = customRequire.resolve(moduleName, { paths });
|
|
23
|
+
const resolved = resolveModule(moduleName, paths);
|
|
10
24
|
rootDir = findRoot(resolved);
|
|
11
25
|
}
|
|
12
|
-
catch
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
26
|
+
catch {
|
|
27
|
+
// Intentar resolver package.json directamente
|
|
28
|
+
const basePath = paths[0] || process.cwd();
|
|
29
|
+
const packagePath = path.join(basePath, 'node_modules', moduleName, 'package.json');
|
|
30
|
+
if (fs.existsSync(packagePath)) {
|
|
31
|
+
rootDir = path.dirname(packagePath);
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
throw new Error(`Cannot resolve module ${moduleName}`);
|
|
35
|
+
}
|
|
17
36
|
}
|
|
18
37
|
const packageJsonPath = path.join(rootDir, 'package.json');
|
|
19
38
|
const packageJson = fs.readJsonSync(packageJsonPath);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "versacompiler",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.2",
|
|
4
4
|
"description": "Una herramienta para compilar y minificar archivos .vue, .js y .ts para proyectos de Vue 3 con soporte para TypeScript.",
|
|
5
5
|
"main": "dist/main.js",
|
|
6
6
|
"bin": {
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"dev": "tsx --watch src/main.ts --watch --verbose --tailwind",
|
|
20
20
|
"compile": "tsx src/main.ts --all",
|
|
21
21
|
"test": "jest --config jest.config.js",
|
|
22
|
-
"build": "tsx src/main.ts --all -t --
|
|
22
|
+
"build": "tsx src/main.ts --all -t --cc --co -y --verbose",
|
|
23
23
|
"lint": "oxlint --fix --config .oxlintrc.json",
|
|
24
24
|
"lint:eslint": "eslint --ext .js,.ts,.vue src/ --fix",
|
|
25
25
|
"perf": "scripts\\run-performance.bat",
|
|
@@ -52,6 +52,7 @@
|
|
|
52
52
|
"find-root": "^1.1.0",
|
|
53
53
|
"fs-extra": "^11.3.0",
|
|
54
54
|
"get-port": "^7.1.0",
|
|
55
|
+
"minimatch": "^10.0.1",
|
|
55
56
|
"oxc-minify": "^0.72.3",
|
|
56
57
|
"oxc-parser": "^0.72.3",
|
|
57
58
|
"oxc-transform": "^0.72.3",
|
|
@@ -69,7 +70,7 @@
|
|
|
69
70
|
"@types/fs-extra": "^11.0.4",
|
|
70
71
|
"@types/jest": "^29.5.14",
|
|
71
72
|
"@types/mocha": "^10.0.10",
|
|
72
|
-
"@types/node": "^
|
|
73
|
+
"@types/node": "^24.0.0",
|
|
73
74
|
"@types/resolve": "^1.20.6",
|
|
74
75
|
"@types/yargs": "^17.0.33",
|
|
75
76
|
"@typescript-eslint/eslint-plugin": "^8.34.0",
|
|
@@ -80,15 +81,15 @@
|
|
|
80
81
|
"eslint": "^9.28.0",
|
|
81
82
|
"eslint-import-resolver-typescript": "^4.4.3",
|
|
82
83
|
"eslint-plugin-import": "^2.31.0",
|
|
83
|
-
"eslint-plugin-oxlint": "^0.
|
|
84
|
+
"eslint-plugin-oxlint": "^1.0.0",
|
|
84
85
|
"eslint-plugin-promise": "^7.2.1",
|
|
85
86
|
"eslint-plugin-unicorn": "^59.0.1",
|
|
86
87
|
"eslint-plugin-vue": "^10.2.0",
|
|
87
88
|
"happy-dom": "^17.6.3",
|
|
88
89
|
"jest": "^29.7.0",
|
|
89
|
-
"jest-environment-jsdom": "30.0.0
|
|
90
|
-
"jest-environment-node": "30.0.0
|
|
91
|
-
"oxlint": "^0.
|
|
90
|
+
"jest-environment-jsdom": "30.0.0",
|
|
91
|
+
"jest-environment-node": "30.0.0",
|
|
92
|
+
"oxlint": "^1.0.0",
|
|
92
93
|
"prettier": "3.5.3",
|
|
93
94
|
"rimraf": "^6.0.1",
|
|
94
95
|
"sweetalert2": "^11.22.0",
|