fix(installer): point at vite's actual outDir, stage gcode_viewer/

vite.config.ts sets outDir to '../static' so the bundle lands at
  <repo>/static/ — not frontend/dist/. Matches the runtime expectation
  in config.py where static_dir = _app_dir / "static".

  Also stage gcode_viewer/ next to static/ so the 3D preview iframe
  routes in main.py (resolved via static_dir.parent / "gcode_viewer")
  find their assets.

  Strip macOS metadata files (.DS_Store, ._.*) from both copies — they
  leak in from dev boxes and would only bloat the installer.
This commit is contained in:
maziggy
2026-06-10 12:29:07 +02:00
parent 1b502c359f
commit 77843547ca
+29 -4
View File
@@ -159,9 +159,15 @@ def install_requirements(python_dir: Path) -> None:
def build_frontend() -> Path:
"""Run ``npm ci && npm run build`` and return the dist path."""
"""Run ``npm ci && npm run build`` and return the build output path.
Vite is configured with ``outDir: '../static'`` (see
``frontend/vite.config.ts``), so the bundle lands at ``<repo>/static/``
— NOT ``frontend/dist/``. The path matches the runtime expectation in
``backend/app/core/config.py`` (``static_dir = _app_dir / "static"``).
"""
frontend = REPO_ROOT / "frontend"
dist = frontend / "dist"
dist = REPO_ROOT / "static"
log("running npm ci in frontend/")
npm = shutil.which("npm")
if not npm:
@@ -198,9 +204,28 @@ def stage_backend(frontend_dist: Path) -> None:
),
)
# Frontend bundle — FastAPI's StaticFiles mounts from app/static
# Frontend bundle — FastAPI's StaticFiles mounts from app/static.
# Strip macOS metadata files (.DS_Store, ._.*) that the dev box leaks
# in; they'd just bloat the installer and never be served anyway.
log("staging frontend bundle")
shutil.copytree(frontend_dist, app / "static")
shutil.copytree(
frontend_dist,
app / "static",
ignore=shutil.ignore_patterns(".DS_Store", "._*"),
)
# gcode_viewer/ is a vendored 3D-preview iframe served via explicit
# routes in main.py (looked up via static_dir.parent / "gcode_viewer").
# In the staged layout STAGING/app/static/'s sibling is STAGING/app/,
# so place the directory next to static/ to match runtime resolution.
gcode_viewer_src = REPO_ROOT / "gcode_viewer"
if gcode_viewer_src.exists():
log("staging gcode_viewer/")
shutil.copytree(
gcode_viewer_src,
app / "gcode_viewer",
ignore=shutil.ignore_patterns(".DS_Store", "._*"),
)
def stage_nssm() -> None: