versacompiler 2.4.1 → 2.6.0
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 +722 -722
- package/dist/compiler/compile-worker-pool.js +108 -0
- package/dist/compiler/compile-worker-thread.cjs +72 -0
- package/dist/compiler/compile.js +177 -18
- package/dist/compiler/error-reporter.js +12 -0
- package/dist/compiler/integrity-validator.js +13 -1
- package/dist/compiler/linter.js +12 -0
- package/dist/compiler/minify.js +12 -0
- package/dist/compiler/minifyTemplate.js +12 -0
- package/dist/compiler/module-resolution-optimizer.js +35 -20
- package/dist/compiler/parser.js +12 -0
- package/dist/compiler/performance-monitor.js +73 -61
- package/dist/compiler/pipeline/build-pipeline.js +139 -0
- package/dist/compiler/pipeline/core-plugins.js +230 -0
- package/dist/compiler/pipeline/module-graph.js +75 -0
- package/dist/compiler/pipeline/plugin-driver.js +99 -0
- package/dist/compiler/pipeline/types.js +14 -0
- package/dist/compiler/tailwindcss.js +12 -0
- package/dist/compiler/transform-optimizer.js +12 -0
- package/dist/compiler/transformTStoJS.js +38 -5
- package/dist/compiler/transforms.js +234 -16
- package/dist/compiler/typescript-compiler.js +12 -0
- package/dist/compiler/typescript-error-parser.js +12 -0
- package/dist/compiler/typescript-manager.js +15 -1
- package/dist/compiler/typescript-sync-validator.js +45 -31
- package/dist/compiler/typescript-worker-pool.js +12 -0
- package/dist/compiler/typescript-worker-thread.cjs +482 -475
- package/dist/compiler/typescript-worker.js +12 -0
- package/dist/compiler/vuejs.js +73 -47
- package/dist/config.js +14 -0
- package/dist/hrm/VueHRM.js +484 -359
- package/dist/hrm/errorScreen.js +95 -83
- package/dist/hrm/getInstanciaVue.js +325 -313
- package/dist/hrm/initHRM.js +736 -586
- package/dist/hrm/versaHMR.js +317 -0
- package/dist/main.js +23 -3
- package/dist/servicios/browserSync.js +127 -6
- package/dist/servicios/file-watcher.js +139 -8
- package/dist/servicios/logger.js +12 -0
- package/dist/servicios/readConfig.js +141 -54
- package/dist/servicios/versacompile.config.types.js +14 -0
- package/dist/utils/excluded-modules.js +12 -0
- package/dist/utils/module-resolver.js +86 -40
- package/dist/utils/promptUser.js +12 -0
- package/dist/utils/proxyValidator.js +12 -0
- package/dist/utils/resolve-bin.js +12 -0
- package/dist/utils/utils.js +12 -0
- package/dist/utils/vue-types-setup.js +260 -248
- package/dist/wrappers/eslint-node.js +15 -1
- package/dist/wrappers/oxlint-node.js +15 -1
- package/dist/wrappers/tailwind-node.js +12 -0
- package/package.json +74 -54
|
@@ -1,12 +1,24 @@
|
|
|
1
|
-
|
|
1
|
+
/* VersaCompiler HMR shim [dev] */
|
|
2
|
+
if (typeof window !== 'undefined' && window.__versaHMR) {
|
|
3
|
+
(() => {
|
|
4
|
+
const _id = new URL(import.meta.url).pathname;
|
|
5
|
+
import.meta.hot = {
|
|
6
|
+
accept(cb) { window.__versaHMR.accept(_id, typeof cb === 'function' ? cb : () => {}); },
|
|
7
|
+
invalidate() { window.__versaHMR._invalidate?.(_id); },
|
|
8
|
+
dispose(cb) { window.__versaHMR._onDispose?.(_id, cb); },
|
|
9
|
+
get data() { return window.__versaHMR._getHotData?.(_id) ?? {}; },
|
|
10
|
+
};
|
|
11
|
+
})();
|
|
12
|
+
}
|
|
13
|
+
import { readdir, readFile, rm, stat, unlink } from 'node:fs/promises';
|
|
2
14
|
import * as path from 'node:path';
|
|
3
15
|
import * as process from 'node:process';
|
|
4
16
|
const { env } = process;
|
|
5
17
|
import * as chokidar from 'chokidar';
|
|
6
18
|
import { minimatch } from 'minimatch';
|
|
7
|
-
import { clearCompilationState, getOutputPath, initCompile, normalizeRuta } from '../compiler/compile.js';
|
|
19
|
+
import { clearCompilationState, getOutputPath, getPipelineModuleGraph, initCompile, normalizeRuta, runPipelineHotUpdate, } from '../compiler/compile.js';
|
|
8
20
|
import { promptUser } from '../utils/promptUser.js';
|
|
9
|
-
import { emitirCambios } from './browserSync.js';
|
|
21
|
+
import { emitirCambios, registerHMRUpdate } from './browserSync.js';
|
|
10
22
|
import { logger } from './logger.js';
|
|
11
23
|
// Lazy loading para chalk
|
|
12
24
|
let chalk;
|
|
@@ -16,6 +28,49 @@ async function loadChalk() {
|
|
|
16
28
|
}
|
|
17
29
|
return chalk;
|
|
18
30
|
}
|
|
31
|
+
/**
|
|
32
|
+
* Analiza el contenido de un módulo JS compilado para determinar si es seguro
|
|
33
|
+
* hacer HMR sin full-reload. Un módulo es "simple" si:
|
|
34
|
+
* - Solo exporta funciones, constantes o valores (no clases con estado ni patrones singleton)
|
|
35
|
+
* - No usa new/class en el scope raíz (como estado global mutable)
|
|
36
|
+
*
|
|
37
|
+
* @param outputPath - Ruta del archivo compilado a analizar
|
|
38
|
+
* @returns 'propagate' si es seguro sin full-reload, 'full-reload' si no se puede determinar
|
|
39
|
+
*/
|
|
40
|
+
async function analyzeCompiledModuleStrategy(outputPath) {
|
|
41
|
+
try {
|
|
42
|
+
const content = await readFile(outputPath, 'utf8');
|
|
43
|
+
// Si el módulo fue compilado por VersaCompiler en modo dev, el shim HMR
|
|
44
|
+
// está inyectado y gestiona la estrategia de reemplazo vía versaHMR.
|
|
45
|
+
// No analizar el shim como side-effect — siempre es propagate.
|
|
46
|
+
if (content.startsWith('/* VersaCompiler HMR shim [dev] */')) {
|
|
47
|
+
return 'propagate';
|
|
48
|
+
}
|
|
49
|
+
// Si el módulo declara que acepta HMR, propagate es seguro
|
|
50
|
+
if (/import\.meta\.hot\.accept/.test(content)) {
|
|
51
|
+
return 'propagate';
|
|
52
|
+
}
|
|
53
|
+
// Heurística: módulos con solo exports de funciones/constantes son seguros
|
|
54
|
+
const hasExports = /export\s+(const|let|function|async function|class\b)/.test(content) || /export\s+default/.test(content);
|
|
55
|
+
if (!hasExports) {
|
|
56
|
+
return 'full-reload';
|
|
57
|
+
}
|
|
58
|
+
// Señales de estado global mutable o efectos secundarios al import:
|
|
59
|
+
// new ClassName() en scope raíz, módulos con side-effects de init
|
|
60
|
+
const hasRootLevelSideEffects =
|
|
61
|
+
// new en scope raíz (fuera de funciones/clases) — detectar heurísticamente
|
|
62
|
+
/^\s*(?:const|let|var)\s+\w+\s*=\s*new\s+\w+/m.test(content) ||
|
|
63
|
+
// Llamadas a funciones en scope raíz que sugieren init
|
|
64
|
+
/^\s*(?:init|setup|bootstrap|start|connect|register)\s*\(/m.test(content);
|
|
65
|
+
if (hasRootLevelSideEffects) {
|
|
66
|
+
return 'full-reload';
|
|
67
|
+
}
|
|
68
|
+
return 'propagate';
|
|
69
|
+
}
|
|
70
|
+
catch {
|
|
71
|
+
return 'full-reload';
|
|
72
|
+
}
|
|
73
|
+
}
|
|
19
74
|
class WatchDebouncer {
|
|
20
75
|
pendingChanges = new Map();
|
|
21
76
|
debounceTimer = null;
|
|
@@ -147,13 +202,44 @@ class WatchDebouncer {
|
|
|
147
202
|
*/
|
|
148
203
|
async processCompilableFiles(compilableFiles) {
|
|
149
204
|
const chalkInstance = await loadChalk();
|
|
205
|
+
const graph = getPipelineModuleGraph();
|
|
150
206
|
// Procesar en batches para evitar sobrecarga
|
|
151
207
|
for (let i = 0; i < compilableFiles.length; i += this.BATCH_SIZE) {
|
|
152
208
|
const batch = compilableFiles.slice(i, i + this.BATCH_SIZE);
|
|
153
209
|
if (batch.length > 1) {
|
|
154
210
|
logger.info(chalkInstance.cyan(`📦 Procesando batch de ${batch.length} archivos compilables (${i + 1}-${Math.min(i + this.BATCH_SIZE, compilableFiles.length)} de ${compilableFiles.length})`));
|
|
155
211
|
}
|
|
156
|
-
const
|
|
212
|
+
const expandedChanges = new Map();
|
|
213
|
+
for (const change of batch) {
|
|
214
|
+
expandedChanges.set(change.filePath, change);
|
|
215
|
+
if (graph) {
|
|
216
|
+
const invalidated = graph.invalidate(change.filePath);
|
|
217
|
+
for (const invalidatedPath of invalidated) {
|
|
218
|
+
if (expandedChanges.has(invalidatedPath))
|
|
219
|
+
continue;
|
|
220
|
+
// Usar la acción correcta según la extensión del archivo invalidado
|
|
221
|
+
// en lugar de forzar 'reloadFull' para todos los importers
|
|
222
|
+
const invalidatedExt = path
|
|
223
|
+
.extname(invalidatedPath)
|
|
224
|
+
.replace('.', '');
|
|
225
|
+
const invalidatedAction = {
|
|
226
|
+
vue: 'HRMVue',
|
|
227
|
+
ts: 'HRMHelper',
|
|
228
|
+
js: 'HRMHelper',
|
|
229
|
+
mjs: 'HRMHelper',
|
|
230
|
+
cjs: 'HRMHelper',
|
|
231
|
+
}[invalidatedExt] ?? 'reloadFull';
|
|
232
|
+
expandedChanges.set(invalidatedPath, {
|
|
233
|
+
filePath: invalidatedPath,
|
|
234
|
+
action: 'change',
|
|
235
|
+
timestamp: Date.now(),
|
|
236
|
+
extensionAction: invalidatedAction,
|
|
237
|
+
isAdditionalFile: false,
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
const promises = Array.from(expandedChanges.values()).map(change => this.compileFile(change));
|
|
157
243
|
await Promise.allSettled(promises);
|
|
158
244
|
}
|
|
159
245
|
if (compilableFiles.length > 1) {
|
|
@@ -177,12 +263,59 @@ class WatchDebouncer {
|
|
|
177
263
|
*/
|
|
178
264
|
async compileFile(change) {
|
|
179
265
|
try {
|
|
266
|
+
let pluginHmrReload = 'none';
|
|
267
|
+
if (change.action !== 'unlink') {
|
|
268
|
+
const hotUpdate = await runPipelineHotUpdate(change.filePath, change.action);
|
|
269
|
+
pluginHmrReload = hotUpdate.reload || 'none';
|
|
270
|
+
}
|
|
180
271
|
const result = await initCompile(change.filePath, true, 'watch');
|
|
181
272
|
if (result.success) {
|
|
273
|
+
// Registrar el output para que el middleware HMR reescriba imports dependientes
|
|
274
|
+
if (result.output) {
|
|
275
|
+
registerHMRUpdate(result.output);
|
|
276
|
+
}
|
|
182
277
|
let accion = result.action || change.extensionAction;
|
|
183
278
|
accion =
|
|
184
279
|
accion === 'extension' ? change.extensionAction : accion;
|
|
185
|
-
|
|
280
|
+
let payload = {};
|
|
281
|
+
if (accion === 'HRMHelper') {
|
|
282
|
+
if (pluginHmrReload === 'full') {
|
|
283
|
+
accion = 'reloadFull';
|
|
284
|
+
}
|
|
285
|
+
else {
|
|
286
|
+
const graph = getPipelineModuleGraph();
|
|
287
|
+
const node = graph?.getNode(change.filePath);
|
|
288
|
+
const importers = node
|
|
289
|
+
? Array.from(node.importers)
|
|
290
|
+
: [];
|
|
291
|
+
// Determinar estrategia base:
|
|
292
|
+
// Si el plugin dice 'module' → propagate garantizado
|
|
293
|
+
// Si hay importers conocidos → propagate (los consumers actualizarán sus refs)
|
|
294
|
+
// Si no hay importers → analizar el módulo compilado para detectar si es "simple"
|
|
295
|
+
let strategy;
|
|
296
|
+
if (pluginHmrReload === 'module') {
|
|
297
|
+
strategy = 'propagate';
|
|
298
|
+
}
|
|
299
|
+
else if (importers.length > 0) {
|
|
300
|
+
strategy = 'propagate';
|
|
301
|
+
}
|
|
302
|
+
else {
|
|
303
|
+
// Sin importers conocidos: analizar el output compilado
|
|
304
|
+
strategy = await analyzeCompiledModuleStrategy(result.output);
|
|
305
|
+
}
|
|
306
|
+
// moduleId: path del output relativo al proyecto para que el cliente
|
|
307
|
+
// pueda hacer lookup en VersaModuleRegistry
|
|
308
|
+
const moduleId = result.output.startsWith('/')
|
|
309
|
+
? result.output
|
|
310
|
+
: `/${result.output}`;
|
|
311
|
+
payload = {
|
|
312
|
+
moduleId,
|
|
313
|
+
importers,
|
|
314
|
+
strategy,
|
|
315
|
+
};
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
emitirCambios(this.browserSyncInstance, accion || 'reloadFull', result.output, payload);
|
|
186
319
|
}
|
|
187
320
|
}
|
|
188
321
|
catch (error) {
|
|
@@ -355,9 +488,7 @@ export async function initChokidar(bs) {
|
|
|
355
488
|
// ✨ OPTIMIZACIÓN: Pre-cargar módulos críticos al iniciar el watcher
|
|
356
489
|
watcher.on('ready', async () => {
|
|
357
490
|
const chalkInstance = await loadChalk();
|
|
358
|
-
logger.info(chalkInstance.green(`👀 : Listo para observar \n${fileWatch
|
|
359
|
-
.map((item) => `${item}`)
|
|
360
|
-
.join('\n')}\n`));
|
|
491
|
+
logger.info(chalkInstance.green(`👀 : Listo para observar \n${fileWatch.map((item) => `${item}`).join('\n')}\n`));
|
|
361
492
|
// Pre-cargar módulos críticos para primera compilación más rápida
|
|
362
493
|
setImmediate(async () => {
|
|
363
494
|
try {
|
package/dist/servicios/logger.js
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
/* VersaCompiler HMR shim [dev] */
|
|
2
|
+
if (typeof window !== 'undefined' && window.__versaHMR) {
|
|
3
|
+
(() => {
|
|
4
|
+
const _id = new URL(import.meta.url).pathname;
|
|
5
|
+
import.meta.hot = {
|
|
6
|
+
accept(cb) { window.__versaHMR.accept(_id, typeof cb === 'function' ? cb : () => {}); },
|
|
7
|
+
invalidate() { window.__versaHMR._invalidate?.(_id); },
|
|
8
|
+
dispose(cb) { window.__versaHMR._onDispose?.(_id, cb); },
|
|
9
|
+
get data() { return window.__versaHMR._getHotData?.(_id) ?? {}; },
|
|
10
|
+
};
|
|
11
|
+
})();
|
|
12
|
+
}
|
|
1
13
|
import * as process from 'node:process';
|
|
2
14
|
// Función para obtener ProgressManager (lazy import para evitar dependencias circulares)
|
|
3
15
|
let getProgressManager = null;
|
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
/* VersaCompiler HMR shim [dev] */
|
|
2
|
+
if (typeof window !== 'undefined' && window.__versaHMR) {
|
|
3
|
+
(() => {
|
|
4
|
+
const _id = new URL(import.meta.url).pathname;
|
|
5
|
+
import.meta.hot = {
|
|
6
|
+
accept(cb) { window.__versaHMR.accept(_id, typeof cb === 'function' ? cb : () => {}); },
|
|
7
|
+
invalidate() { window.__versaHMR._invalidate?.(_id); },
|
|
8
|
+
dispose(cb) { window.__versaHMR._onDispose?.(_id, cb); },
|
|
9
|
+
get data() { return window.__versaHMR._getHotData?.(_id) ?? {}; },
|
|
10
|
+
};
|
|
11
|
+
})();
|
|
12
|
+
}
|
|
1
13
|
import { normalize, relative, resolve } from 'node:path';
|
|
2
14
|
import * as process from 'node:process';
|
|
3
15
|
import { env } from 'node:process';
|
|
@@ -25,7 +37,7 @@ export function validatePath(pathStr) {
|
|
|
25
37
|
return false;
|
|
26
38
|
}
|
|
27
39
|
// Rechazar rutas absolutas de Windows (válido en cualquier plataforma)
|
|
28
|
-
if (/^[A-Za-z]:[
|
|
40
|
+
if (/^[A-Za-z]:[/\\]/.test(pathStr)) {
|
|
29
41
|
logger.error(`Ruta absoluta de Windows no permitida: ${pathStr}`);
|
|
30
42
|
return false;
|
|
31
43
|
}
|
|
@@ -238,6 +250,80 @@ function safeJsonStringify(obj, fallback = 'false') {
|
|
|
238
250
|
return fallback;
|
|
239
251
|
}
|
|
240
252
|
}
|
|
253
|
+
function normalizeAliasKey(key) {
|
|
254
|
+
if (key.includes('*'))
|
|
255
|
+
return key;
|
|
256
|
+
if (key.endsWith('/'))
|
|
257
|
+
return `${key}*`;
|
|
258
|
+
return `${key}/*`;
|
|
259
|
+
}
|
|
260
|
+
function normalizeAliasValue(value) {
|
|
261
|
+
if (value.includes('*'))
|
|
262
|
+
return value;
|
|
263
|
+
if (value.endsWith('/'))
|
|
264
|
+
return `${value}*`;
|
|
265
|
+
return `${value}/*`;
|
|
266
|
+
}
|
|
267
|
+
function normalizeAlias(alias) {
|
|
268
|
+
if (!alias)
|
|
269
|
+
return {};
|
|
270
|
+
const result = {};
|
|
271
|
+
if (Array.isArray(alias)) {
|
|
272
|
+
for (const entry of alias) {
|
|
273
|
+
if (!entry || typeof entry.find !== 'string')
|
|
274
|
+
continue;
|
|
275
|
+
if (typeof entry.replacement !== 'string')
|
|
276
|
+
continue;
|
|
277
|
+
const key = normalizeAliasKey(entry.find);
|
|
278
|
+
const value = normalizeAliasValue(entry.replacement);
|
|
279
|
+
result[key] = [value];
|
|
280
|
+
}
|
|
281
|
+
return result;
|
|
282
|
+
}
|
|
283
|
+
for (const [key, value] of Object.entries(alias)) {
|
|
284
|
+
const normalizedKey = normalizeAliasKey(key);
|
|
285
|
+
if (Array.isArray(value)) {
|
|
286
|
+
result[normalizedKey] = value
|
|
287
|
+
.filter(v => typeof v === 'string')
|
|
288
|
+
.map(v => normalizeAliasValue(v));
|
|
289
|
+
}
|
|
290
|
+
else if (typeof value === 'string') {
|
|
291
|
+
result[normalizedKey] = [normalizeAliasValue(value)];
|
|
292
|
+
}
|
|
293
|
+
}
|
|
294
|
+
return result;
|
|
295
|
+
}
|
|
296
|
+
function normalizeConfig(input) {
|
|
297
|
+
if (input?.compilerOptions) {
|
|
298
|
+
return input;
|
|
299
|
+
}
|
|
300
|
+
const viteConfig = input;
|
|
301
|
+
const aliases = normalizeAlias(viteConfig?.resolve?.alias);
|
|
302
|
+
return {
|
|
303
|
+
tsconfig: viteConfig?.tsconfig,
|
|
304
|
+
compilerOptions: {
|
|
305
|
+
sourceRoot: viteConfig?.root || './src',
|
|
306
|
+
outDir: viteConfig?.build?.outDir || './dist',
|
|
307
|
+
pathsAlias: aliases,
|
|
308
|
+
},
|
|
309
|
+
plugins: viteConfig?.plugins,
|
|
310
|
+
proxyConfig: {
|
|
311
|
+
proxyUrl: viteConfig?.server?.proxyUrl || '',
|
|
312
|
+
assetsOmit: viteConfig?.server?.assetsOmit ?? false,
|
|
313
|
+
},
|
|
314
|
+
aditionalWatch: viteConfig?.watch?.additional ||
|
|
315
|
+
viteConfig?.server?.watch?.additional ||
|
|
316
|
+
[],
|
|
317
|
+
tailwindConfig: viteConfig?.tailwindConfig,
|
|
318
|
+
linter: viteConfig?.linter,
|
|
319
|
+
bundlers: viteConfig?.build?.bundlers,
|
|
320
|
+
typeCheckOptions: viteConfig?.typeCheckOptions,
|
|
321
|
+
};
|
|
322
|
+
}
|
|
323
|
+
let loadedConfig = null;
|
|
324
|
+
export function getLoadedConfig() {
|
|
325
|
+
return loadedConfig;
|
|
326
|
+
}
|
|
241
327
|
/**
|
|
242
328
|
* Wrapper para el import dinámico que permite mejor testing
|
|
243
329
|
*/
|
|
@@ -272,7 +358,8 @@ export async function readConfig() {
|
|
|
272
358
|
if (!data) {
|
|
273
359
|
throw new Error('No se pudo leer el archivo de configuración.');
|
|
274
360
|
}
|
|
275
|
-
const
|
|
361
|
+
const rawConfig = data.default || data;
|
|
362
|
+
const tsConfig = normalizeConfig(rawConfig);
|
|
276
363
|
// Validar tamaño de configuración
|
|
277
364
|
if (!validateConfigSize(tsConfig)) {
|
|
278
365
|
throw new Error('Configuración demasiado grande o contiene referencias circulares.');
|
|
@@ -323,6 +410,7 @@ export async function readConfig() {
|
|
|
323
410
|
if (!tsConfig.compilerOptions.sourceRoot) {
|
|
324
411
|
env.tsConfig = safeJsonStringify(tsConfig, '{}');
|
|
325
412
|
}
|
|
413
|
+
loadedConfig = tsConfig;
|
|
326
414
|
logger.info('✅ Configuration loaded and validated successfully');
|
|
327
415
|
return true;
|
|
328
416
|
}
|
|
@@ -347,58 +435,57 @@ export async function initConfig() {
|
|
|
347
435
|
logger.warn(`🚩 El archivo de configuración '${env.PATH_CONFIG_FILE}' ya existe.`);
|
|
348
436
|
return true;
|
|
349
437
|
}
|
|
350
|
-
const configContent =
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
outDir: './dist',
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
{
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
};
|
|
438
|
+
const configContent = `import { defineConfig } from 'versacompiler/config';
|
|
439
|
+
|
|
440
|
+
export default defineConfig({
|
|
441
|
+
root: './src',
|
|
442
|
+
build: {
|
|
443
|
+
outDir: './dist',
|
|
444
|
+
bundlers: [
|
|
445
|
+
{
|
|
446
|
+
name: 'appLoader',
|
|
447
|
+
fileInput: './public/module/appLoader.js',
|
|
448
|
+
fileOutput: './public/module/appLoader.prod.js',
|
|
449
|
+
},
|
|
450
|
+
],
|
|
451
|
+
},
|
|
452
|
+
resolve: {
|
|
453
|
+
alias: {
|
|
454
|
+
'/dist/public': 'src',
|
|
455
|
+
'/dist/public': 'public',
|
|
456
|
+
},
|
|
457
|
+
},
|
|
458
|
+
server: {
|
|
459
|
+
proxyUrl: '',
|
|
460
|
+
assetsOmit: true,
|
|
461
|
+
watch: {
|
|
462
|
+
additional: ['./app/templates/**/*.twig', './app/templates/**/*.html'],
|
|
463
|
+
},
|
|
464
|
+
},
|
|
465
|
+
tsconfig: './tsconfig.json',
|
|
466
|
+
tailwindConfig: {
|
|
467
|
+
bin: './node_modules/.bin/tailwindcss',
|
|
468
|
+
input: './src/css/input.css',
|
|
469
|
+
output: './public/css/output.css',
|
|
470
|
+
},
|
|
471
|
+
linter: [
|
|
472
|
+
{
|
|
473
|
+
name: 'eslint',
|
|
474
|
+
bin: './node_modules/.bin/eslint',
|
|
475
|
+
configFile: './.eslintrc.json',
|
|
476
|
+
fix: false,
|
|
477
|
+
paths: ['src/'],
|
|
478
|
+
},
|
|
479
|
+
{
|
|
480
|
+
name: 'oxlint',
|
|
481
|
+
bin: './node_modules/.bin/oxlint',
|
|
482
|
+
configFile: './.oxlintrc.json',
|
|
483
|
+
fix: false,
|
|
484
|
+
paths: ['src/'],
|
|
485
|
+
},
|
|
486
|
+
],
|
|
487
|
+
plugins: [],
|
|
488
|
+
});
|
|
402
489
|
`;
|
|
403
490
|
fs.writeFileSync(configPath, configContent, 'utf8');
|
|
404
491
|
logger.info(`🚩 Archivo de configuración '${env.PATH_CONFIG_FILE}' creado correctamente.`);
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/* VersaCompiler HMR shim [dev] */
|
|
2
|
+
if (typeof window !== 'undefined' && window.__versaHMR) {
|
|
3
|
+
(() => {
|
|
4
|
+
const _id = new URL(import.meta.url).pathname;
|
|
5
|
+
import.meta.hot = {
|
|
6
|
+
accept(cb) { window.__versaHMR.accept(_id, typeof cb === 'function' ? cb : () => {}); },
|
|
7
|
+
invalidate() { window.__versaHMR._invalidate?.(_id); },
|
|
8
|
+
dispose(cb) { window.__versaHMR._onDispose?.(_id, cb); },
|
|
9
|
+
get data() { return window.__versaHMR._getHotData?.(_id) ?? {}; },
|
|
10
|
+
};
|
|
11
|
+
})();
|
|
12
|
+
}
|
|
13
|
+
export const defineConfig = (config) => config;
|
|
14
|
+
//# sourceMappingURL=versacompile.config.types.js.map
|
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
/* VersaCompiler HMR shim [dev] */
|
|
2
|
+
if (typeof window !== 'undefined' && window.__versaHMR) {
|
|
3
|
+
(() => {
|
|
4
|
+
const _id = new URL(import.meta.url).pathname;
|
|
5
|
+
import.meta.hot = {
|
|
6
|
+
accept(cb) { window.__versaHMR.accept(_id, typeof cb === 'function' ? cb : () => {}); },
|
|
7
|
+
invalidate() { window.__versaHMR._invalidate?.(_id); },
|
|
8
|
+
dispose(cb) { window.__versaHMR._onDispose?.(_id, cb); },
|
|
9
|
+
get data() { return window.__versaHMR._getHotData?.(_id) ?? {}; },
|
|
10
|
+
};
|
|
11
|
+
})();
|
|
12
|
+
}
|
|
1
13
|
/**
|
|
2
14
|
* Lista centralizada de módulos excluidos de la resolución automática
|
|
3
15
|
* Estos módulos se mantienen con su importación original sin transformar
|
|
@@ -1,9 +1,21 @@
|
|
|
1
|
-
|
|
1
|
+
/* VersaCompiler HMR shim [dev] */
|
|
2
|
+
if (typeof window !== 'undefined' && window.__versaHMR) {
|
|
3
|
+
(() => {
|
|
4
|
+
const _id = new URL(import.meta.url).pathname;
|
|
5
|
+
import.meta.hot = {
|
|
6
|
+
accept(cb) { window.__versaHMR.accept(_id, typeof cb === 'function' ? cb : () => {}); },
|
|
7
|
+
invalidate() { window.__versaHMR._invalidate?.(_id); },
|
|
8
|
+
dispose(cb) { window.__versaHMR._onDispose?.(_id, cb); },
|
|
9
|
+
get data() { return window.__versaHMR._getHotData?.(_id) ?? {}; },
|
|
10
|
+
};
|
|
11
|
+
})();
|
|
12
|
+
}
|
|
13
|
+
// Opción con librería 'resolve' (npm install resolve)
|
|
2
14
|
import fs, { readFileSync } from 'node:fs';
|
|
3
15
|
import { dirname, join, relative } from 'node:path';
|
|
4
16
|
import { cwd, env } from 'node:process';
|
|
5
|
-
// import pkg from '
|
|
6
|
-
// import resolve from '
|
|
17
|
+
// import pkg from 'enhanced-resolve';
|
|
18
|
+
// import resolve from 'resolve';
|
|
7
19
|
import { logger } from '../servicios/logger.js';
|
|
8
20
|
import { EXCLUDED_MODULES } from './excluded-modules.js';
|
|
9
21
|
class PackageJsonCache {
|
|
@@ -72,7 +84,7 @@ const packageJsonCache = PackageJsonCache.getInstance();
|
|
|
72
84
|
// return null;
|
|
73
85
|
// }
|
|
74
86
|
// }
|
|
75
|
-
// Opción con '
|
|
87
|
+
// Opción con 'enhanced-resolve' (webpack's resolver)
|
|
76
88
|
// npm install enhanced-resolve
|
|
77
89
|
// const { ResolverFactory } = pkg;
|
|
78
90
|
// const resolver = ResolverFactory.createResolver({
|
|
@@ -350,26 +362,7 @@ function simpleESMResolver(moduleName) {
|
|
|
350
362
|
entryPoint = dotExport;
|
|
351
363
|
}
|
|
352
364
|
else if (typeof dotExport === 'object') {
|
|
353
|
-
|
|
354
|
-
// Buscar específicamente patrones esm-browser primero
|
|
355
|
-
const exportKeys = Object.keys(dotExport);
|
|
356
|
-
const esmBrowserKey = exportKeys.find(key => key.includes('browser') &&
|
|
357
|
-
(key.includes('esm') || key.includes('module')));
|
|
358
|
-
if (esmBrowserKey &&
|
|
359
|
-
typeof dotExport[esmBrowserKey] === 'string') {
|
|
360
|
-
entryPoint = dotExport[esmBrowserKey];
|
|
361
|
-
}
|
|
362
|
-
else {
|
|
363
|
-
// Priorizar import > browser > default
|
|
364
|
-
entryPoint =
|
|
365
|
-
(typeof dotExport.import === 'string'
|
|
366
|
-
? dotExport.import
|
|
367
|
-
: null) ||
|
|
368
|
-
dotExport.browser ||
|
|
369
|
-
(typeof dotExport.default === 'string'
|
|
370
|
-
? dotExport.default
|
|
371
|
-
: null);
|
|
372
|
-
}
|
|
365
|
+
entryPoint = resolveExportValue(dotExport);
|
|
373
366
|
}
|
|
374
367
|
}
|
|
375
368
|
}
|
|
@@ -489,6 +482,64 @@ function getNodeModulesRelativePath(fullPath, _fromFile) {
|
|
|
489
482
|
}
|
|
490
483
|
return rel;
|
|
491
484
|
}
|
|
485
|
+
/**
|
|
486
|
+
* Parses a module specifier into packageName and subPath.
|
|
487
|
+
* Handles scoped packages correctly.
|
|
488
|
+
* Examples:
|
|
489
|
+
* '@vueuse/core' → { packageName: '@vueuse/core', subPath: '' }
|
|
490
|
+
* '@vueuse/core/sub' → { packageName: '@vueuse/core', subPath: 'sub' }
|
|
491
|
+
* 'vue/dist/x' → { packageName: 'vue', subPath: 'dist/x' }
|
|
492
|
+
* 'vue' → { packageName: 'vue', subPath: '' }
|
|
493
|
+
*/
|
|
494
|
+
export function parseModuleSpecifier(moduleName) {
|
|
495
|
+
if (moduleName.startsWith('@')) {
|
|
496
|
+
const parts = moduleName.split('/');
|
|
497
|
+
if (parts.length < 2 || !parts[1]) {
|
|
498
|
+
return { packageName: moduleName, subPath: '' };
|
|
499
|
+
}
|
|
500
|
+
const packageName = `${parts[0]}/${parts[1]}`;
|
|
501
|
+
const subPath = parts.slice(2).join('/');
|
|
502
|
+
return { packageName, subPath };
|
|
503
|
+
}
|
|
504
|
+
else {
|
|
505
|
+
const slashIdx = moduleName.indexOf('/');
|
|
506
|
+
if (slashIdx === -1) {
|
|
507
|
+
return { packageName: moduleName, subPath: '' };
|
|
508
|
+
}
|
|
509
|
+
return {
|
|
510
|
+
packageName: moduleName.slice(0, slashIdx),
|
|
511
|
+
subPath: moduleName.slice(slashIdx + 1),
|
|
512
|
+
};
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
/**
|
|
516
|
+
* Recursively resolves a conditional export value.
|
|
517
|
+
* Priority: import > browser > module > default
|
|
518
|
+
* Handles nested objects up to a depth limit.
|
|
519
|
+
*/
|
|
520
|
+
export function resolveExportValue(exportVal, depth = 0) {
|
|
521
|
+
if (depth > 5)
|
|
522
|
+
return null;
|
|
523
|
+
if (typeof exportVal === 'string')
|
|
524
|
+
return exportVal;
|
|
525
|
+
if (typeof exportVal === 'object' && exportVal !== null) {
|
|
526
|
+
const obj = exportVal;
|
|
527
|
+
for (const key of [
|
|
528
|
+
'import',
|
|
529
|
+
'browser',
|
|
530
|
+
'module',
|
|
531
|
+
'default',
|
|
532
|
+
'require',
|
|
533
|
+
]) {
|
|
534
|
+
if (obj[key] !== undefined) {
|
|
535
|
+
const resolved = resolveExportValue(obj[key], depth + 1);
|
|
536
|
+
if (resolved)
|
|
537
|
+
return resolved;
|
|
538
|
+
}
|
|
539
|
+
}
|
|
540
|
+
}
|
|
541
|
+
return null;
|
|
542
|
+
}
|
|
492
543
|
export function getModulePath(moduleName, fromFile) {
|
|
493
544
|
// Verificar si el módulo está en la lista de excluidos
|
|
494
545
|
if (EXCLUDED_MODULES.has(moduleName)) {
|
|
@@ -501,14 +552,15 @@ export function getModuleSubPath(moduleName, fromFile) {
|
|
|
501
552
|
// Verificar si el módulo está en la lista de excluidos
|
|
502
553
|
if (EXCLUDED_MODULES.has(moduleName)) {
|
|
503
554
|
return null; // Retornar null para mantener la importación original
|
|
504
|
-
}
|
|
555
|
+
}
|
|
556
|
+
// Usar parseModuleSpecifier para manejar correctamente paquetes con scope
|
|
557
|
+
const { packageName, subPath } = parseModuleSpecifier(moduleName);
|
|
558
|
+
// Si no hay subPath, delegar al resolver normal
|
|
559
|
+
if (!subPath) {
|
|
560
|
+
return getModulePath(moduleName, fromFile);
|
|
561
|
+
}
|
|
562
|
+
// Es un subpath: resolver con el packageName correcto
|
|
505
563
|
if (moduleName.includes('/')) {
|
|
506
|
-
const [packageName, ...subPathParts] = moduleName.split('/');
|
|
507
|
-
const subPath = subPathParts.join('/');
|
|
508
|
-
// Verificar que packageName no esté vacío
|
|
509
|
-
if (!packageName) {
|
|
510
|
-
return null;
|
|
511
|
-
}
|
|
512
564
|
try {
|
|
513
565
|
const nodeModulesPath = join(cwd(), 'node_modules', packageName);
|
|
514
566
|
const packagePath = join(nodeModulesPath, 'package.json');
|
|
@@ -525,15 +577,9 @@ export function getModuleSubPath(moduleName, fromFile) {
|
|
|
525
577
|
const exportKey = `./${subPath}`;
|
|
526
578
|
const exportPath = packageJson.exports[exportKey];
|
|
527
579
|
if (exportPath) {
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
else if (typeof exportPath === 'object') {
|
|
532
|
-
// Priorizar import > default para ESM
|
|
533
|
-
const importPath = exportPath.import || exportPath.default;
|
|
534
|
-
if (typeof importPath === 'string') {
|
|
535
|
-
return getNodeModulesRelativePath(join(moduleDir, importPath), fromFile);
|
|
536
|
-
}
|
|
580
|
+
const resolved = resolveExportValue(exportPath);
|
|
581
|
+
if (resolved) {
|
|
582
|
+
return getNodeModulesRelativePath(join(moduleDir, resolved), fromFile);
|
|
537
583
|
}
|
|
538
584
|
}
|
|
539
585
|
}
|
package/dist/utils/promptUser.js
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
/* VersaCompiler HMR shim [dev] */
|
|
2
|
+
if (typeof window !== 'undefined' && window.__versaHMR) {
|
|
3
|
+
(() => {
|
|
4
|
+
const _id = new URL(import.meta.url).pathname;
|
|
5
|
+
import.meta.hot = {
|
|
6
|
+
accept(cb) { window.__versaHMR.accept(_id, typeof cb === 'function' ? cb : () => {}); },
|
|
7
|
+
invalidate() { window.__versaHMR._invalidate?.(_id); },
|
|
8
|
+
dispose(cb) { window.__versaHMR._onDispose?.(_id, cb); },
|
|
9
|
+
get data() { return window.__versaHMR._getHotData?.(_id) ?? {}; },
|
|
10
|
+
};
|
|
11
|
+
})();
|
|
12
|
+
}
|
|
1
13
|
import process, { stdin as input, stdout as output } from 'node:process';
|
|
2
14
|
import * as readline from 'node:readline/promises';
|
|
3
15
|
import { logger } from '../servicios/logger.js';
|