Frontend Asset Deployment Contract¶
This guide defines the deployment contract for Vite assets in lx-annotate.
Canonical Ownership¶
frontend/src/assets/owns source assets imported by the Vue application.static/owns non-Vite Django source assets and the published documentation tree understatic/docs/.staticfiles/is disposable deployment output produced by Vite,collectstatic, anddocs-publish; it is ignored by Git and packaged only after regeneration.
Do not create package-local copies under lx_annotate/static/ or
lx_annotate/staticfiles/. Django and third-party application assets are
collected from their installed packages, while the generated top-level
staticfiles/ tree is force-included in release artifacts.
Vite’s dependency cache under frontend/.vite/ is local and ignored. Legacy
dashboard bundles under static/assets/ must not be restored; the maintained
dashboard source is imported from frontend/src/assets/ and emitted by Vite.
Contract Summary¶
Build output directory:
frontend/vite.config.tswrites compiled assets to:<repo>/staticfilesManifest location: Vite manifest must exist at:
staticfiles/.vite/manifest.jsonDjango Vite config:
Dev:
lx_annotate/settings/settings_dev.pyreadsBASE_DIR/staticfiles/.vite/manifest.jsonProd:
lx_annotate/settings/settings_prod.pyreadsSTATIC_ROOT/.vite/manifest.json
Runtime startup guard:
devenv/management.nixvalidates:
manifest exists at
"$static_root/.vite/manifest.json"src/main.tsentry resolves to a file that exists at"$static_root/$entry_file"
Deployment Flow¶
Build frontend:
devenv shell -- vue-buildVerify manifest contract:
make verify-vite-manifestBuild distributable artifacts:
make package
make package forces a frontend rebuild, checks that committed frontend artifacts
did not drift, publishes Sphinx HTML into static/docs and staticfiles/docs,
and then fails if staticfiles/.vite/manifest.json is empty, invalid JSON,
missing the src/main.ts entry, or points at a missing asset. This prevents
stale or broken frontend artifacts from reaching wheel or sdist packaging and
ensures the frontend /documentation page can load the packaged docs bundle.
Why emptyOutDir Is Disabled¶
vite.config.ts uses emptyOutDir: false because staticfiles/ is a mixed
generated directory containing Vite output plus assets produced by
collectstatic and docs-publish. Auto-emptying this directory would risk
deleting output owned by the other build stages.
Smoke Tests¶
Run these checks after deployment changes:
Manifest exists:
ls -l staticfiles/.vite/manifest.jsonLegacy folder is gone:
test ! -d staticfiles/distEntry mapping is valid:
python - <<'PY' import json from pathlib import Path m = json.loads(Path('staticfiles/.vite/manifest.json').read_text()) entry = m['src/main.ts']['file'] print(entry, (Path('staticfiles') / entry).exists()) PY
Frame Annotation Integration Note¶
Frame annotation is rendered directly by
frontend/src/views/FrameAnnotation.vue without third-party runtime widget
scripts. Keep lx_annotate/templates/base.html free of ad-hoc global script
includes.