81 lines
2.8 KiB
TypeScript
81 lines
2.8 KiB
TypeScript
import { defineConfig, type Plugin, type ResolvedConfig } from 'vite'
|
|
import react from '@vitejs/plugin-react'
|
|
import tailwindcss from '@tailwindcss/vite'
|
|
import { createHash } from 'node:crypto'
|
|
import { existsSync, readFileSync, readdirSync, writeFileSync } from 'node:fs'
|
|
import { resolve } from 'node:path'
|
|
|
|
// PWA: inyecta en dist/sw.js (1) una versión de caché única por build y
|
|
// (2) la lista de assets con hash a precachear. La versión es un hash del
|
|
// index.html, el manifest y los nombres de los assets, así que cambia
|
|
// exactamente cuando cambia el bundle (y el SW descarta las cachés viejas
|
|
// en `activate`). No toca el pipeline `tsc -b && vite build`.
|
|
function pwaServiceWorker(): Plugin {
|
|
let outDir = 'dist'
|
|
return {
|
|
name: 'skeen-pwa-service-worker',
|
|
apply: 'build',
|
|
configResolved(config: ResolvedConfig) {
|
|
outDir = config.build.outDir
|
|
},
|
|
closeBundle() {
|
|
const dir = resolve(process.cwd(), outDir)
|
|
const swPath = resolve(dir, 'sw.js')
|
|
if (!existsSync(swPath)) return
|
|
|
|
const listAssets = (sub: string): string[] => {
|
|
const abs = resolve(dir, sub)
|
|
if (!existsSync(abs)) return []
|
|
return readdirSync(abs)
|
|
.filter((f) => /\.(js|css|woff2?|png|jpe?g|svg|webp|ico|json)$/i.test(f))
|
|
.map((f) => `/${sub}/${f}`)
|
|
.sort()
|
|
}
|
|
// Solo /assets (hash): los iconos ya van listados explícitamente en sw.js.
|
|
const assets = listAssets('assets')
|
|
|
|
const read = (file: string): Buffer =>
|
|
existsSync(resolve(dir, file)) ? readFileSync(resolve(dir, file)) : Buffer.from('')
|
|
const version = createHash('sha256')
|
|
.update(read('index.html'))
|
|
.update(read('manifest.webmanifest'))
|
|
.update(assets.join('|'))
|
|
.digest('hex')
|
|
.slice(0, 12)
|
|
|
|
let sw = readFileSync(swPath, 'utf8')
|
|
sw = sw.replace('__BUILD_VERSION__', version)
|
|
// JSON dentro de un literal de una sola comilla: se quitan comillas
|
|
// simples por seguridad (los nombres de Vite no las contienen).
|
|
sw = sw.replace('__PRECACHE_ASSETS__', JSON.stringify(assets).replace(/'/g, ''))
|
|
writeFileSync(swPath, sw)
|
|
|
|
this.warn(`PWA service worker: versión de caché ${version}, ${assets.length} assets precacheados`)
|
|
},
|
|
}
|
|
}
|
|
|
|
// https://vitejs.dev/config/
|
|
export default defineConfig({
|
|
plugins: [react(), tailwindcss(), pwaServiceWorker()],
|
|
server: {
|
|
port: 5173,
|
|
proxy: {
|
|
'/api/odoo': {
|
|
target: 'http://localhost:8069',
|
|
changeOrigin: true,
|
|
rewrite: (path) => path.replace(/^\/api\/odoo/, ''),
|
|
},
|
|
'/api/wacrm': {
|
|
target: 'http://localhost:3000',
|
|
changeOrigin: true,
|
|
rewrite: (path) => path.replace(/^\/api\/wacrm/, '/api/v1'),
|
|
},
|
|
},
|
|
},
|
|
build: {
|
|
outDir: 'dist',
|
|
sourcemap: false,
|
|
},
|
|
})
|