fix(ui): integrate PWA build and avoid api caching
Move PWA config into the default Vite build, ensure the PWA icon source is generated, and restrict Workbox caching to static assets only. Update server UI build wiring and clarify TLS requirements in docs.
This commit is contained in:
4618
package-lock.json
generated
4618
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -71,7 +71,8 @@ When running as a server CodeNomad can also be installed as a PWA from any suppo
|
||||
|
||||
> **TLS requirement**
|
||||
> Browsers require a secure (`https://`) connection for PWA installation.
|
||||
> If you host CodeNomad on a remote machine, serve it behind a reverse proxy (e.g. Caddy, nginx) with a valid TLS certificate — self-signed certificates will not work.
|
||||
> If you host CodeNomad on a remote machine, serve it behind a reverse proxy (e.g. Caddy, nginx) with a valid TLS certificate.
|
||||
> Self-signed certificates generally won't work unless they are explicitly trusted by the device/browser (e.g., via a custom CA).
|
||||
|
||||
### Data Storage
|
||||
- **Config**: `~/.config/codenomad/config.json`
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
},
|
||||
"scripts": {
|
||||
"build": "npm run build:ui && npm run prepare-ui && tsc -p tsconfig.json && node ./scripts/copy-auth-pages.mjs && npm run prepare-config",
|
||||
"build:ui": "npm run build:pwa --prefix ../ui",
|
||||
"build:ui": "npm run build --prefix ../ui",
|
||||
"prepare-ui": "node ./scripts/copy-ui-dist.mjs",
|
||||
"prepare-config": "node ./scripts/copy-opencode-config.mjs",
|
||||
"dev": "cross-env CODENOMAD_DEV=1 CODENOMAD_SERVER_PASSWORD=codenomad-dev CLI_UI_DEV_SERVER=http://localhost:3000 tsx src/index.ts",
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
"scripts": {
|
||||
"dev": "vite dev",
|
||||
"build": "vite build",
|
||||
"build:pwa": "vite build -c vite.config.pwa.ts",
|
||||
"preview": "vite preview",
|
||||
"typecheck": "tsc --noEmit -p tsconfig.json"
|
||||
},
|
||||
|
||||
@@ -1,61 +0,0 @@
|
||||
import { copyFileSync } from "fs"
|
||||
import { defineConfig } from "vite"
|
||||
import { VitePWA } from "vite-plugin-pwa"
|
||||
import { resolve } from "path"
|
||||
import baseConfig from "./vite.config"
|
||||
|
||||
export default defineConfig({
|
||||
...baseConfig,
|
||||
plugins: [
|
||||
...(baseConfig.plugins ?? []),
|
||||
{
|
||||
name: "copy-pwa-source-icon",
|
||||
buildStart() {
|
||||
// vite-pwa-assets requires the source image inside public/
|
||||
copyFileSync(
|
||||
resolve(__dirname, "src/images/CodeNomad-Icon.png"),
|
||||
resolve(__dirname, "src/renderer/public/logo.png"),
|
||||
)
|
||||
},
|
||||
},
|
||||
VitePWA({
|
||||
registerType: "autoUpdate",
|
||||
injectRegister: "auto",
|
||||
pwaAssets: {
|
||||
preset: "minimal-2023",
|
||||
image: "public/logo.png",
|
||||
},
|
||||
manifest: {
|
||||
name: "CodeNomad",
|
||||
short_name: "CodeNomad",
|
||||
id: "/",
|
||||
start_url: "/",
|
||||
display: "standalone",
|
||||
display_override: ["window-controls-overlay", "standalone"],
|
||||
background_color: "#1a1a1a",
|
||||
theme_color: "#1a1a1a",
|
||||
},
|
||||
workbox: {
|
||||
navigateFallback: null,
|
||||
runtimeCaching: [
|
||||
{
|
||||
urlPattern: /^\/api\/.*$/i,
|
||||
handler: "NetworkFirst",
|
||||
options: {
|
||||
cacheName: "api-cache",
|
||||
expiration: { maxEntries: 50, maxAgeSeconds: 60 },
|
||||
},
|
||||
},
|
||||
{
|
||||
urlPattern: /.*\.(?:js|css|png|jpg|jpeg|svg|webp|woff2?)$/i,
|
||||
handler: "CacheFirst",
|
||||
options: {
|
||||
cacheName: "asset-cache",
|
||||
expiration: { maxEntries: 200, maxAgeSeconds: 60 * 60 * 24 * 30 },
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
}),
|
||||
],
|
||||
})
|
||||
@@ -1,6 +1,7 @@
|
||||
import fs from "fs"
|
||||
import { defineConfig } from "vite"
|
||||
import solid from "vite-plugin-solid"
|
||||
import { VitePWA } from "vite-plugin-pwa"
|
||||
import { resolve } from "path"
|
||||
|
||||
const uiPackageJson = JSON.parse(fs.readFileSync(resolve(__dirname, "package.json"), "utf-8")) as { version?: string }
|
||||
@@ -20,6 +21,55 @@ export default defineConfig({
|
||||
})
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "prepare-pwa-source-icon",
|
||||
apply: "build",
|
||||
buildStart() {
|
||||
// vite-pwa-assets requires the source image inside root/public/
|
||||
const source = resolve(__dirname, "src/images/CodeNomad-Icon.png")
|
||||
const publicDir = resolve(__dirname, "src/renderer/public")
|
||||
const dest = resolve(publicDir, "logo.png")
|
||||
fs.mkdirSync(publicDir, { recursive: true })
|
||||
fs.copyFileSync(source, dest)
|
||||
},
|
||||
},
|
||||
VitePWA({
|
||||
registerType: "autoUpdate",
|
||||
injectRegister: "auto",
|
||||
pwaAssets: {
|
||||
preset: "minimal-2023",
|
||||
image: "public/logo.png",
|
||||
},
|
||||
manifest: {
|
||||
name: "CodeNomad",
|
||||
short_name: "CodeNomad",
|
||||
id: "/",
|
||||
start_url: "/",
|
||||
display: "standalone",
|
||||
display_override: ["window-controls-overlay", "standalone"],
|
||||
background_color: "#1a1a1a",
|
||||
theme_color: "#1a1a1a",
|
||||
},
|
||||
workbox: {
|
||||
// Preserve server-side auth redirects (e.g., /login) instead of serving cached index.html.
|
||||
navigateFallback: null,
|
||||
// Only cache static UI assets; never cache API traffic.
|
||||
runtimeCaching: [
|
||||
{
|
||||
urlPattern: ({ url, request }) => {
|
||||
if (url.pathname.startsWith("/api/")) return false
|
||||
return ["script", "style", "image", "font"].includes(request.destination)
|
||||
},
|
||||
handler: "CacheFirst",
|
||||
options: {
|
||||
cacheName: "asset-cache",
|
||||
expiration: { maxEntries: 200, maxAgeSeconds: 60 * 60 * 24 * 30 },
|
||||
cacheableResponse: { statuses: [0, 200] },
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
}),
|
||||
],
|
||||
css: {
|
||||
postcss: "./postcss.config.js",
|
||||
|
||||
Reference in New Issue
Block a user