feat(desktop): self-contained — bundle the frontend
- build:renderer builds Fabric.Frontend with relative base and copies the static bundle into renderer/; dist/pack scripts run it first. - main.js: production loads renderer/index.html when present (falls back to offline.html); packaged app no longer needs a separate frontend server (still talks to Center/Guild backends, which the login screen points at — file:// origin is CORS-allowed). - package files += renderer/**; gitignore renderer/. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,2 +1,3 @@
|
||||
node_modules/
|
||||
dist/
|
||||
renderer/
|
||||
|
||||
6
main.js
6
main.js
@@ -4,7 +4,11 @@ const path = require('path')
|
||||
|
||||
const isDev = !!process.env.FABRIC_DESKTOP_URL
|
||||
const DEFAULT_DEV_URL = 'http://localhost:5173'
|
||||
const DEFAULT_PROD_ENTRY = path.join(__dirname, 'offline.html')
|
||||
// Self-contained: load the bundled frontend if present, else the placeholder.
|
||||
const BUNDLED_ENTRY = path.join(__dirname, 'renderer', 'index.html')
|
||||
const DEFAULT_PROD_ENTRY = fs.existsSync(BUNDLED_ENTRY)
|
||||
? BUNDLED_ENTRY
|
||||
: path.join(__dirname, 'offline.html')
|
||||
|
||||
let mainWindow = null
|
||||
let tray = null
|
||||
|
||||
14
package.json
14
package.json
@@ -12,11 +12,12 @@
|
||||
"scripts": {
|
||||
"start": "electron .",
|
||||
"start:dev": "FABRIC_DESKTOP_URL=http://localhost:5173 electron .",
|
||||
"pack": "electron-builder --dir",
|
||||
"dist": "electron-builder",
|
||||
"dist:linux": "electron-builder --linux AppImage deb tar.gz",
|
||||
"dist:mac": "electron-builder --mac dmg zip",
|
||||
"dist:win": "electron-builder --win nsis zip"
|
||||
"build:renderer": "node scripts/build-renderer.mjs",
|
||||
"pack": "npm run build:renderer && electron-builder --dir",
|
||||
"dist": "npm run build:renderer && electron-builder",
|
||||
"dist:linux": "npm run build:renderer && electron-builder --linux AppImage deb tar.gz",
|
||||
"dist:mac": "npm run build:renderer && electron-builder --mac dmg zip",
|
||||
"dist:win": "npm run build:renderer && electron-builder --win nsis zip"
|
||||
},
|
||||
"devDependencies": {
|
||||
"electron": "^37.2.1",
|
||||
@@ -34,7 +35,8 @@
|
||||
"preload.js",
|
||||
"offline.html",
|
||||
"package.json",
|
||||
"assets/**"
|
||||
"assets/**",
|
||||
"renderer/**"
|
||||
],
|
||||
"asar": true,
|
||||
"icon": "build/icon.png",
|
||||
|
||||
36
scripts/build-renderer.mjs
Normal file
36
scripts/build-renderer.mjs
Normal file
@@ -0,0 +1,36 @@
|
||||
#!/usr/bin/env node
|
||||
/**
|
||||
* Build the Fabric web frontend with a relative asset base and copy the
|
||||
* static bundle into Fabric.Desktop/renderer/ so the packaged Electron app
|
||||
* is self-contained (loaded via file://, no separate web server needed).
|
||||
*
|
||||
* Fabric.Frontend is the sibling submodule under the parent Fabric repo.
|
||||
*/
|
||||
import { execSync } from 'node:child_process'
|
||||
import fs from 'node:fs'
|
||||
import path from 'node:path'
|
||||
import { fileURLToPath } from 'node:url'
|
||||
|
||||
const __dirname = path.dirname(fileURLToPath(import.meta.url))
|
||||
const DESKTOP = path.resolve(__dirname, '..')
|
||||
const FRONTEND = path.resolve(DESKTOP, '..', 'Fabric.Frontend')
|
||||
const SRC = path.join(FRONTEND, 'dist-desktop')
|
||||
const DEST = path.join(DESKTOP, 'renderer')
|
||||
|
||||
if (!fs.existsSync(FRONTEND)) {
|
||||
console.error(`[build-renderer] Fabric.Frontend not found at ${FRONTEND}`)
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
console.log('[build-renderer] building frontend (relative base)…')
|
||||
execSync('npm install --no-audit --no-fund', { cwd: FRONTEND, stdio: 'inherit' })
|
||||
execSync('npm run build:desktop', { cwd: FRONTEND, stdio: 'inherit' })
|
||||
|
||||
if (!fs.existsSync(path.join(SRC, 'index.html'))) {
|
||||
console.error(`[build-renderer] expected ${SRC}/index.html after build`)
|
||||
process.exit(1)
|
||||
}
|
||||
|
||||
fs.rmSync(DEST, { recursive: true, force: true })
|
||||
fs.cpSync(SRC, DEST, { recursive: true })
|
||||
console.log(`[build-renderer] copied ${SRC} -> ${DEST}`)
|
||||
Reference in New Issue
Block a user