40 lines
1.3 KiB
Python
40 lines
1.3 KiB
Python
"""Vite manifest reader — maps a source entry to its hashed dist path (Ch05)."""
|
|
from __future__ import annotations
|
|
|
|
import json
|
|
from pathlib import Path
|
|
|
|
from flask import Flask
|
|
|
|
|
|
class ManifestNotFound(RuntimeError):
|
|
"""app/static/dist/manifest.json is missing — `npm run build` hasn't been run."""
|
|
|
|
|
|
def _load_manifest(static_dist_dir: Path) -> dict:
|
|
for candidate in (static_dist_dir / ".vite" / "manifest.json", static_dist_dir / "manifest.json"):
|
|
if candidate.exists():
|
|
return json.loads(candidate.read_text())
|
|
raise ManifestNotFound(f"No Vite manifest under {static_dist_dir} — run `npm run build`.")
|
|
|
|
|
|
def register_asset_helper(app: Flask) -> None:
|
|
"""Register `asset(name)` as a Jinja global (Chapter 05)."""
|
|
static_dist_dir = Path(app.static_folder) / "dist"
|
|
|
|
@app.context_processor
|
|
def inject_asset_helper():
|
|
def asset(name: str) -> str:
|
|
try:
|
|
manifest = _load_manifest(static_dist_dir)
|
|
except ManifestNotFound:
|
|
if app.debug:
|
|
return f"/static/dist/{name}" # tolerate an unbuilt dev checkout
|
|
raise
|
|
entry = manifest.get(name)
|
|
if entry is None:
|
|
raise KeyError(f"{name!r} not in Vite manifest.")
|
|
return f"/static/dist/{entry['file']}"
|
|
|
|
return {"asset": asset}
|