Skip to content

📚 Referencias

Objetivo: Acceso rápido a configuraciones técnicas, ejemplos de código y recursos para consulta diaria.


graph TD
    A[Repositorio Central] --> B[git clone]
    B --> C[npx plop]
    C --> D[Generar proyecto]
    D --> E[Copiar código generado]
    E --> F[Pegar en workspace real]
    F --> G[Desarrollo normal]

    style A fill:#e1f5fe
    style D fill:#f3e5f5
    style F fill:#e8f5e8

🎯 Beneficios del enfoque centralizado:

  • Una sola fuente de verdad para todos los templates
  • Actualizaciones automáticas - al hacer git pull tienes los últimos templates
  • Consistencia garantizada - todos usan exactamente los mismos templates
  • Mantenimiento simplificado - cambios se hacen en un solo lugar

  1. Clonar el repositorio central (una sola vez por máquina):

    Terminal window
    git clone https://github.com/Kompa-s/proyecto-vue.git
    cd proyecto-vue
  2. Instalar dependencias (una sola vez):

    Terminal window
    pnpm install
  3. Actualizar templates (antes de cada generación):

    Terminal window
    git pull origin master
  4. Generar proyecto:

    Terminal window
    npx plop
  5. Copiar al workspace real:

    Terminal window
    # Copiar desde proyecto-vue a tu workspace
    Copy-Item -Recurse @apps/mi-nuevo-proyecto ../mi-workspace-real/@apps/

🔗 Microfrontend Integrado

¿Cuándo usar?

  • Se ejecuta dentro de aplicación ASP.NET
  • Recibe window.__params del host
  • Ejemplos: checkout, listados, reservas

Genera:

  • Estructura completa con TypeScript
  • Configuración para CDN
  • Store de Pinia configurado
  • Comunicación con host

🚀 Microfrontend Independiente

¿Cuándo usar? - SPA completa independiente - No depende de host ASP.NET - Ejemplos: admin panels, herramientas internas Genera: - Aplicación Vue completa - Routing opcional - Configuración standalone - Build optimizado

🎨 Librería Vue

¿Cuándo usar? - Componentes reutilizables - Composables compartidos - Depende de Vue/Pinia Genera: - Configuración para librería - Build con externals - TypeScript declarations - Exports optimizados

🔧 Librería Utilidades

¿Cuándo usar?

  • Funciones puras JavaScript/TypeScript
  • Sin dependencias de Vue
  • Tipos compartidos

Genera:

  • Build ligero
  • Múltiples entry points
  • Solo TypeScript + Vite
  • Configuración mínima

Terminal window
cd proyecto-vue
npx plop

Interfaz del generador:

? [PLOP] Please choose a generator.
❯ microfrontend-integrado
microfrontend-independiente
libreria-vue
libreria-utils
  1. Seleccionar tipo:

    ? [PLOP] Please choose a generator. microfrontend-integrado
  2. Completar prompts:

    ? Nombre del microfrontend (kebab-case): flight-booking
    ? Descripción del microfrontend: Sistema de reserva de vuelos
    ? URL del CDN de pruebas: https://test-b2b2c.cdnpt.com
    ? URL del CDN de producción: https://b2b2c.cdnpt.com
  3. Código generado exitosamente:

    ✅ Microfrontend integrado "flight-booking" creado exitosamente!
    📁 Ubicación: @apps/flight-booking/
    🚀 Para comenzar: pnpm app-flight-booking dev
    📦 Para construir: pnpm app-flight-booking build
Terminal window
# Desde proyecto-vue hacia tu workspace de trabajo
Copy-Item -Recurse @apps/flight-booking ../mi-workspace-real/@apps/

  1. Agregar script al package.json root:

    {
    "scripts": {
    "app-flight-booking": "pnpm --filter flight-booking"
    }
    }
  2. Instalar dependencias:

    Terminal window
    cd mi-workspace-real
    pnpm install
  3. Build packages del workspace:

    Terminal window
    pnpm -r build
  4. Verificar que funciona:

    Terminal window
    pnpm app-flight-booking dev

El generador incluye validaciones para mantener consistencia:

ValidaciónDescripciónError ejemplo
Nombres únicosVerifica que no existe en @apps/ o packages/Ya existe un microfrontend con el nombre "review"
Formato kebab-caseSolo minúsculas y guionesUse formato kebab-case (ejemplo: mi-proyecto)
Prefijo vue-Librerías Vue deben comenzar con vue-Las librerías Vue deben comenzar con "vue-"
Descripción mínimaAl menos 10 caracteresLa descripción debe tener al menos 10 caracteres

Terminal window
# Antes de cada generación
cd proyecto-vue
git pull origin master
# Si hay nuevas dependencias
pnpm install

El equipo de arquitectura puede actualizar:

  • ✅ Nuevos tipos de templates
  • ✅ Mejores configuraciones base
  • ✅ Nuevas validaciones
  • ✅ Dependencias actualizadas

Tu beneficio: Automáticamente tienes acceso a las mejoras con un simple git pull.


❌ Templates-repo no actualiza

Problema: git pull no trae cambios

Solución:

Terminal window
cd proyecto-vue
git status
git stash # Si hay cambios locales
git pull origin master

❌ Plop no funciona

Problema: npx plop falla

Solución:

Terminal window
# Verificar ubicación
Get-Location # Debe ser proyecto-vue
# Reinstalar dependencias
Remove-Item -Recurse -Force node_modules, pnpm-lock.yaml
pnpm install

❌ Código no se puede copiar

Problema: Copy-paste falla

Solución:

Terminal window
# Verificar permisos Windows
# Ejecutar PowerShell como administrador
# O usar interfaz gráfica
# Explorador de archivos → Copy → Paste
Terminal window
# Verificar ubicación correcta
Get-Location
# Debe mostrar: .../proyecto-vue
# Verificar estructura
Get-ChildItem @apps/
Get-ChildItem packages/
# Verificar plopfile
Get-ChildItem plopfile.js
# Test del generador
npx plop --version

📁 proyecto-vue/
├── 📁 @apps/ # Ejemplos y base para Quick Start
├── 📁 packages/ # Packages base del workspace
├── 📁 plop-templates/ # Templates de Plop
│ ├── 📁 microfrontend-integrado/
│ ├── 📁 microfrontend-independiente/
│ ├── 📁 libreria-vue/
│ └── 📁 libreria-utils/
├── 📄 plopfile.js # Configuración principal
├── 📄 package.json # Dependencias del generador
└── 📄 README.md # Documentación específica

  • proyecto-vue clonado localmente
  • git pull para últimas actualizaciones
  • Saber qué tipo de proyecto necesitas (usar Decision Tree)
  • Tener nombre en kebab-case definido
  • Código copiado al workspace real
  • Script añadido al package.json root
  • pnpm install ejecutado
  • pnpm -r build completado exitosamente
  • pnpm app-{nombre} dev funciona
  • Hot reload funcionando
  • No errores TypeScript
  • Build de producción exitoso
  • Linting sin warnings

  • ⚡ Velocidad: De 0 a proyecto funcional en 5 minutos
  • 🎯 Consistencia: Todos los proyectos siguen los mismos estándares
  • 🔧 Mantenimiento: Updates automáticos de templates
  • 📚 Aprendizaje: Templates como documentación viva
  • 🏗️ Estándares: Arquitectura consistente enforced automáticamente
  • 📈 Onboarding: Nuevos miembros productivos desde día 1
  • 🔄 Evolución: Templates mejoran con la experiencia del equipo
  • 🛡️ Calidad: Configuraciones probadas en producción

{
"files": [],
"references": [{ "path": "./tsconfig.app.json" }, { "path": "./tsconfig.node.json" }]
}
{
"extends": "@vue/tsconfig/tsconfig.dom.json",
"compilerOptions": {
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
"paths": {
"@/*": ["./src/*"]
},
/* Linting */
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"erasableSyntaxOnly": true,
"noFallthroughCasesInSwitch": true,
"noUncheckedSideEffectImports": true
},
"include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue"]
}
{
"extends": "@vue/tsconfig/tsconfig.dom.json",
"compilerOptions": {
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
"strict": true,
"target": "ES2020",
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"module": "ESNext",
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"isolatedModules": true,
"verbatimModuleSyntax": true,
"jsx": "preserve",
"declaration": true,
"declarationMap": true,
"outDir": "./dist",
"rootDir": "./src",
// Strict Mode
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true,
"exactOptionalPropertyTypes": true,
// Paths
"baseUrl": "./",
"paths": {
"@": ["./src"],
"@/*": ["./src/*"]
}
},
"include": ["src/**/*.ts", "src/**/*.vue", "src/**/*.tsx"],
"exclude": ["node_modules", "dist", "**/*.test.ts", "**/*.spec.ts"]
}

tsconfig.json para Librerías de Utilidades

Section titled “tsconfig.json para Librerías de Utilidades”
{
"compilerOptions": {
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
"strict": true,
"target": "ES2020",
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"module": "ESNext",
"skipLibCheck": true,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"noEmit": true,
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"isolatedModules": true,
"verbatimModuleSyntax": true,
"declaration": true,
"declarationMap": true,
"outDir": "./dist",
"rootDir": "./src",
// Strict Mode
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true,
"exactOptionalPropertyTypes": true,
// Paths
"baseUrl": "./",
"paths": {
"@": ["./src"],
"@/*": ["./src/*"]
}
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist", "**/*.test.ts", "**/*.spec.ts"]
}

/* eslint-disable no-undef */
import { fileURLToPath, URL } from "node:url";
import vue from "@vitejs/plugin-vue";
import { defineConfig, loadEnv } from "vite";
export default defineConfig(({ mode }) => {
const env = loadEnv(mode, process.cwd(), "");
const isDebug = env.VITE_IS_DEBUG === "true";
const useMocks = env.VITE_USE_MOCKS === "true";
const cdnBaseUrl = env.VITE_CDN_BASE_URL;
return {
plugins: [
vue({
template: {
compilerOptions: {
isCustomElement: (tag) => tag.includes("-"),
},
},
}),
],
resolve: {
alias: {
"@": fileURLToPath(new URL("./src", import.meta.url)),
},
},
base: cdnBaseUrl ? cdnBaseUrl : "/",
build: {
target: "es2020",
minify: !isDebug,
sourcemap: isDebug,
rollupOptions: {
output: {
chunkFileNames: "[name]-[hash].js",
entryFileNames: "{micro-name}.js", // Cambiar por nombre específico
assetFileNames: "[name][extname]",
// Configurar la ruta de importación de chunks para CDN
...(cdnBaseUrl && {
format: "es",
paths: (id) => {
if (id.startsWith("./") || id.startsWith("../")) {
return `${cdnBaseUrl}${id.replace(/^\.\//, "")}`;
}
return id;
},
}),
// Optimización de chunks
manualChunks: (id) => {
if (useMocks && id.includes("/mocks/")) {
return "mocks";
}
if (id.includes("node_modules")) {
if (id.includes("/vue/") || id.includes("/@vue/")) {
return "vue-vendor";
}
if (id.includes("/pinia/")) {
return "pinia-vendor";
}
if (id.includes("/i18next/")) {
return "i18n-vendor";
}
if (id.includes("/@lottiefiles/")) {
return "lottie-vendor";
}
return "vendor";
}
// Packages del workspace
if (id.includes("packages/utils")) {
return "pk-utils";
}
if (id.includes("packages/vue-utils")) {
return "pk-vue-utils";
}
if (id.includes("packages/vue-modal")) {
return "pk-vue-modal";
}
},
},
},
},
optimizeDeps: {
include: [
"vue",
"@vue/runtime-core",
"@vue/runtime-dom",
"pinia",
"i18next",
"i18next-vue",
],
},
};
});
/* eslint-disable no-undef */
import vue from "@vitejs/plugin-vue";
import path from "path";
import { defineConfig } from "vite";
import dts from "vite-plugin-dts";
export default defineConfig({
build: {
lib: {
entry: path.resolve(__dirname, "src/index.ts"),
formats: ["es"],
},
rollupOptions: {
external: [
// Core Vue
"vue",
// Internacionalización
"i18next",
"i18next-vue",
"i18next-http-backend",
// Componentes específicos
"@lottiefiles/dotlottie-vue",
// Packages del workspace
"@pnpmworkspace/types",
"@pnpmworkspace/utils",
"@pnpmworkspace/vue-modal",
],
output: {
preserveModules: true,
preserveModulesRoot: "src",
entryFileNames: "[name].js",
assetFileNames: (assetInfo) => {
if (assetInfo.name === "style.css") return "style.css";
return assetInfo.name || "asset-[hash][extname]";
},
globals: {
vue: "Vue",
},
},
},
cssCodeSplit: false,
minify: process.env.NODE_ENV === "production",
},
plugins: [
vue(),
dts({
exclude: ["**/*.test.ts", "**/*.spec.ts", "src/test-utils/**/*"],
}),
],
resolve: {
alias: {
"@": path.resolve(__dirname, "./src"),
},
},
});

vite.config.ts para Librerías de Utilidades

Section titled “vite.config.ts para Librerías de Utilidades”
/* eslint-disable no-undef */
import path from "path";
import { defineConfig } from "vite";
import dts from "vite-plugin-dts";
export default defineConfig({
build: {
lib: {
entry: {
index: path.resolve(__dirname, "src/index.ts"),
},
formats: ["es"],
},
rollupOptions: {
external: [
// Solo dependencias específicas del workspace si las hay
"@pnpmworkspace/types",
],
output: {
preserveModules: true,
preserveModulesRoot: "src",
entryFileNames: "[name].js",
},
},
minify: process.env.NODE_ENV === "production",
},
plugins: [
dts({
include: ["src/**/*"],
exclude: ["**/*.test.ts", "**/*.spec.ts", "src/test-utils/**/*"],
insertTypesEntry: true,
copyDtsFiles: true,
rollupTypes: true,
}),
],
resolve: {
alias: {
"@": path.resolve(__dirname, "./src"),
},
},
});

{
"name": "my-microfrontend",
"private": true,
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "npm run lint && vite --host",
"build": "npm run lint && vue-tsc -b && vite build",
"builddev": "npm run lint && vue-tsc -b && vite build --mode development",
"lint": "eslint . --report-unused-disable-directives --max-warnings 0",
"type-check": "vue-tsc --noEmit",
"clean": "rm -rf dist node_modules/.vite"
},
"dependencies": {
"vue": "catalog:",
"pinia": "catalog:",
"i18next": "catalog:",
"i18next-vue": "catalog:",
"@lottiefiles/dotlottie-vue": "catalog:"
},
"devDependencies": {
"@pnpmworkspace/types": "workspace:*",
"@pnpmworkspace/utils": "workspace:*",
"@pnpmworkspace/vue-utils": "workspace:*",
"@pnpmworkspace/vue-modal": "workspace:*"
}
}
{
"name": "@pnpmworkspace/vue-components",
"private": true,
"version": "0.0.0",
"type": "module",
"main": "./dist/index.js",
"module": "./dist/index.js",
"types": "./dist/index.d.ts",
"exports": {
".": {
"import": "./dist/index.js",
"types": "./dist/index.d.ts"
}
},
"files": ["dist"],
"scripts": {
"dev": "npm run lint && vite build --watch",
"build": "npm run lint && vue-tsc -b && vite build",
"builddev": "npm run lint && vue-tsc -b && vite build --mode development",
"lint": "eslint . --report-unused-disable-directives --max-warnings 0"
},
"dependencies": {
"vue": "catalog:"
},
"devDependencies": {
"@pnpmworkspace/types": "workspace:*"
}
}
{
"name": "@pnpmworkspace/utils",
"private": true,
"version": "0.0.0",
"type": "module",
"main": "./dist/index.js",
"module": "./dist/index.js",
"types": "./dist/index.d.ts",
"exports": {
".": {
"import": "./dist/index.js",
"types": "./dist/index.d.ts"
},
"./http": {
"import": "./dist/services/http/index.js",
"types": "./dist/services/http/index.d.ts"
}
},
"files": ["dist"],
"scripts": {
"build": "npm run lint && tsc -b && vite build",
"builddev": "npm run lint && tsc -b && vite build --mode development",
"lint": "eslint . --report-unused-disable-directives --max-warnings 0"
},
"dependencies": {},
"devDependencies": {
"typescript": "catalog:"
}
}

Terminal window
VITE_USE_MOCKS = "false"
VITE_IS_DEBUG = "true"
VITE_I18_PATH = "https://test.cdn.com/i18n/{micro-name}"
VITE_I18_VERSION = "1"
VITE_API_URL = "https://test-api-xxxxxx.com/api"
VITE_CDN_BASE_URL = "https://test.cdn.com/{micro-name}/"
Terminal window
VITE_USE_MOCKS = "false"
VITE_IS_DEBUG = "false"
VITE_I18_PATH = "https://cdn.com/i18n/{micro-name}"
VITE_I18_VERSION = "1"
VITE_API_URL = "https://api.xxxxxx.com/api"
VITE_CDN_BASE_URL = "https://cdn.com/{micro-name}/"

<script setup lang="ts">
// 1. 📥 IMPORTS
import { computed, onMounted, ref } from "vue";
import { storeToRefs } from "pinia";
import { useMyStore } from "@/stores/myStore";
// 2. 🏷️ INTERFACES Y TIPOS
interface Props {
title: string;
count?: number;
}
interface Emits {
"update:count": [value: number];
}
// 3. 📡 PROPS Y EMITS
const props = withDefaults(defineProps<Props>(), {
count: 0,
});
const emit = defineEmits<Emits>();
// 4. 💉 INJECTIONS Y COMPOSABLES
const store = useMyStore();
const { data, isLoading } = storeToRefs(store);
// 5. 📊 REACTIVE STATE
const localState = ref<string>("");
const selectedItems = ref<Item[]>([]);
// 6. 🧮 COMPUTED PROPERTIES
const displayTitle = computed(() => `${props.title} (${props.count})`);
const isValid = computed(() => localState.value.length > 0);
// 7. ⚡ METHODS Y FUNCTIONS
async function handleSubmit(): Promise<void> {
// Implementation
}
function updateCount(newValue: number): void {
emit("update:count", newValue);
}
// 8. 🔄 LIFECYCLE HOOKS
onMounted(async () => {
await store.initialize();
});
</script>
<script setup lang="ts">
// ✅ Props con tipos explícitos
interface Props {
title: string;
user: {
id: string;
name: string;
email?: string;
};
config: AppConfig; // Importado de @pnpmworkspace/types
count?: number;
}
const props = withDefaults(defineProps<Props>(), {
count: 0,
});
</script>
stores/userStore.ts
import { defineStore } from "pinia";
import type { User, ApiResponse } from "@pnpmworkspace/types";
interface UserState {
currentUser: User | null;
isAuthenticated: boolean;
preferences: UserPreferences;
}
export const useUserStore = defineStore("user", {
state: (): UserState => ({
currentUser: null,
isAuthenticated: false,
preferences: getDefaultPreferences(),
}),
getters: {
// Tipo inferido automáticamente como string
displayName: (state): string => state.currentUser?.name ?? "Guest",
// Tipo explícito para lógica compleja
permissionLevel: (state): "guest" | "user" | "admin" => {
if (!state.currentUser) return "guest";
return state.currentUser.role === "admin" ? "admin" : "user";
},
},
actions: {
// Tipos explícitos en parámetros y retorno
async login(credentials: LoginCredentials): Promise<ApiResponse<User>> {
// Implementation con tipo checking completo
},
},
});

import type { ReviewData } from "@/review/types/types";
declare global {
interface Window {
__params: Params;
}
}
export interface Params {
reviewData: ReviewData;
config: Config;
}
export interface ConfigEnv {
UseMocks: boolean;
IsDebug: boolean;
I18Path: string;
I18Version: string;
FlightApiUrl: string;
}
export interface Config {
baseUrl: string;
showPoints: boolean;
currency: string;
language: string;
checkoutPath: string;
listPath: string;
lottieUrl: string;
siteUri: string;
}
export const configEnv = {
UseMocks: import.meta.env.VITE_USE_MOCKS === "true",
IsDebug: import.meta.env.VITE_IS_DEBUG === "true",
I18Path: import.meta.env.VITE_I18_PATH,
I18Version: import.meta.env.VITE_I18_VERSION || "1",
FlightApiUrl: import.meta.env.VITE_FLIGHT_API_URL,
};

config.window.ts (solo microfrontends integrados)

Section titled “config.window.ts (solo microfrontends integrados)”
import type { Params } from "@/global";
export const configWindow = window.__params as Params;
composables/useApiClient.ts
import { WebRequestService } from "@pnpmworkspace/utils/http";
import { inject } from "vue";
import type { ConfigEnv } from "@/global";
export function useApiClient() {
const configEnv = inject("configEnv") as ConfigEnv;
const apiClient = new WebRequestService({
baseURL: configEnv.ApiUrl,
timeout: 10000,
});
return {
apiClient,
// Helpers específicos
async fetchProducts(categoryId: string) {
return apiClient.get<Product[]>(`/products/${categoryId}`);
},
async updateReservation(id: string, data: Partial<ReservationData>) {
return apiClient.put<ReservationData>(`/reservations/${id}`, data);
},
};
}

packages:
- ./@apps/**
- ./packages/**
catalog:
"@lottiefiles/dotlottie-vue": 0.7.2
"@originjs/vite-plugin-federation": ^1.3.0
"@vue/test-utils": ^2.4.0
i18next: ^24.2.1
i18next-http-backend: ^3.0.1
i18next-vue: ^5.0.0
pinia: ^2.3.0
typescript: ~5.8.3
vite-plugin-dts: ^4.5.4
vitest: ^2.1.0
vue: ^3.5.13
vue-router: ^4.5.0
{
"name": "root",
"private": true,
"scripts": {
"app-list": "pnpm --filter list",
"app-review": "pnpm --filter review",
"utils": "pnpm --filter utils",
"vue-utils": "pnpm --filter vue-utils",
"vue-modal": "pnpm --filter vue-modal",
"types": "pnpm --filter types",
"build": "pnpm -r build",
"builddev": "pnpm -r builddev",
"lint": "eslint .",
"format": "prettier --write ."
}
}

{
"printWidth": 120,
"tabWidth": 3,
"vueIndentScriptAndStyle": true,
"singleAttributePerLine": true
}
import path from "node:path";
import { fileURLToPath } from "node:url";
import { FlatCompat } from "@eslint/eslintrc";
import js from "@eslint/js";
import simpleImportSort from "eslint-plugin-simple-import-sort";
import globals from "globals";
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
const compat = new FlatCompat({
baseDirectory: __dirname,
recommendedConfig: js.configs.recommended,
allConfig: js.configs.all,
});
export default [
{
ignores: ["**/dist", "**/.eslintrc.cjs", "**/drop"],
},
...compat.extends(
"plugin:@typescript-eslint/recommended",
"eslint:recommended",
"plugin:vue/vue3-recommended",
"prettier",
),
{
plugins: { "simple-import-sort": simpleImportSort },
languageOptions: {
parserOptions: {
parser: "@typescript-eslint/parser",
},
globals: {
...globals.browser,
},
ecmaVersion: "latest",
sourceType: "module",
},
rules: {
"simple-import-sort/imports": "error",
"simple-import-sort/exports": "error",
"vue/no-v-html": "off",
"no-unused-vars": [
"error",
{
argsIgnorePattern: "^_",
},
],
"@typescript-eslint/no-unused-vars": [
"error",
{
argsIgnorePattern: "^_",
},
],
},
},
];

DependenciaVersiónPropósitoUso
vue^3.5.13Framework principalTodos los proyectos
typescript~5.8.3Tipado estáticoTodos los proyectos
pinia^2.3.0State managementMicrofrontends
vite^7.0.0Build toolTodos los proyectos
DependenciaVersiónPropósitoUso
@lottiefiles/dotlottie-vue0.7.2AnimacionesLoading states
i18next^24.2.1InternacionalizaciónBase i18n
i18next-vue^5.0.0Vue i18n integrationTodos los microfrontends
i18next-http-backend^3.0.1Carga remota de traduccionesMicrofrontends
DependenciaVersiónPropósitoUso
vite-plugin-dts^4.5.4Generación tipos .d.tsLibrerías
@vue/test-utils^2.4.0Testing de componentesTesting (futuro)
vitest^2.1.0Test runnerTesting (futuro)
PackagePropósitoDependencias
@pnpmworkspace/typesTipos compartidosNinguna
@pnpmworkspace/utilsUtilidades sin VueNinguna
@pnpmworkspace/vue-utilsUtilidades Vuevue, i18next
@pnpmworkspace/vue-modalComponentes compartidosvue

  • Vue Language Features (Volar) - VS Code extension
  • TypeScript Vue Plugin (Volar) - VS Code extension
  • Vue DevTools - Browser extension
  • ESLint + Prettier - Ya configurados en el workspace