You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
In 0.0.27 gen-pages started emitting @import "#module/<pkg>/styles.css" into modules.generated.css. That specifier can only resolve if the host's committed, hand-editablehost/client_app/vite.config.ts builds a matching Vite alias — and existing hosts never receive that change, because vite.config.ts is scaffold output, not a package file.
Upgrading simple_module_* 0.0.26 → 0.0.27 therefore breaks vite build in any app scaffolded earlier, with an error naming a specifier that appears nowhere in the app's own sources.
Reproduction
An app scaffolded at 0.0.26 (host + a wheel-installed dashboard, which ships styles.css):
# bump simple_module_* to 0.0.27 in host/pyproject.toml
uv sync --all-packages
make gen-pages
make build
✗ Build failed in 21ms
error during build:
[@tailwindcss/vite:generate:build] Can't resolve '#module/dashboard/styles.css'
in '<app>/host/client_app'
file: <app>/host/client_app/styles.css
Versions: simple_module_hosting==0.0.27, simple_module_cli==0.0.27, vite 6.4.3, @tailwindcss/vite 4.x, Python 3.12.
Why this is awkward rather than just a migration step
modules.generated.css is generated on every build (and gitignored in our app). vite.config.ts is scaffolded once and then owned and edited by the app — ours carries a base override for serving the bundle under /static/dist/. So the generated artifact and the config that has to resolve it are versioned independently, and a Python-only dependency bump silently invalidates the config.
There's also an internal inconsistency in the emitter that makes this look avoidable. render_modules_css in simple_module_hosting/assets.py emits, into the same file:
@source — absolute paths (e.pages_dir.as_posix())
@import — alias specifiers (#module/<pkg>/...)
The docstring explains the alias as avoiding ../../../.venv/lib/python3.12/site-packages/<pkg>/styles.css, which is fair for a relative path. But the @source lines right above are already absolute and interpreter-path-bearing, so absolute @import paths would be no worse and would need no host config at all.
Second, related problem: the template drops aliases the modules still need
The 0.0.27 vite.config.ts template also removes the npm-package-name alias block that maps @simple-module-py/<pkg> onto a module's directory. But module .ts sources still import that way:
Following the new template verbatim, our workspace-member module fails to build:
[vite]: Rollup failed to resolve import
"@simple-module-py/pagebuilder/pagebuilder/components/blockRegistry"
from "modules/canopy_atlas/canopy_atlas/puck-blocks.ts".
This is the case in #156 — which is closed, but whose fix (moduleBareImportResolver no longer short-circuiting on fsRoot/projectRoot containment) is still under ## [Unreleased] in CHANGELOG.md and is not in 0.0.27. So the template change that depends on that fix shipped a release ahead of it. A fresh smpy new app with a workspace module importing pagebuilder hits this on day one.
We worked around both by keeping the package-name aliases alongside the new #module/* ones — the prefixes are disjoint, so they compose:
alias: [...moduleAliases, ...packageNameAliases],
Suggested fixes
Roughly in order of how much they'd help:
Emit absolute paths for @import, as @source already does. Removes the host-config dependency entirely and makes the generated CSS self-contained. The stated objection (ugly relative paths) doesn't apply to absolute ones.
If the alias is worth keeping, make gen-pages verify it resolves — it already writes modules.assets.json, so it can check vite.config.ts reads that file and fail with the required diff rather than letting Vite fail later on a specifier the app never wrote.
Add a doctor check for the same thing, so make doctor catches it before a build does.
Document it — a CHANGELOG entry for 0.0.27 saying "hosts must update vite.config.ts; here is the diff" would have turned a confusing build failure into a two-minute edit. As of 0.0.27 the CHANGELOG has no per-version entries between 0.0.1 and Unreleased.
Happy to send a PR for (1) or (4) if you have a preference.
Summary
In 0.0.27
gen-pagesstarted emitting@import "#module/<pkg>/styles.css"intomodules.generated.css. That specifier can only resolve if the host's committed, hand-editablehost/client_app/vite.config.tsbuilds a matching Vite alias — and existing hosts never receive that change, becausevite.config.tsis scaffold output, not a package file.Upgrading
simple_module_*0.0.26 → 0.0.27 therefore breaksvite buildin any app scaffolded earlier, with an error naming a specifier that appears nowhere in the app's own sources.Reproduction
An app scaffolded at 0.0.26 (host + a wheel-installed
dashboard, which shipsstyles.css):# bump simple_module_* to 0.0.27 in host/pyproject.toml uv sync --all-packages make gen-pages make buildmodules.generated.cssnow contains:and the build fails:
Versions:
simple_module_hosting==0.0.27,simple_module_cli==0.0.27,vite 6.4.3,@tailwindcss/vite 4.x, Python 3.12.Why this is awkward rather than just a migration step
modules.generated.cssis generated on every build (and gitignored in our app).vite.config.tsis scaffolded once and then owned and edited by the app — ours carries abaseoverride for serving the bundle under/static/dist/. So the generated artifact and the config that has to resolve it are versioned independently, and a Python-only dependency bump silently invalidates the config.There's also an internal inconsistency in the emitter that makes this look avoidable.
render_modules_cssinsimple_module_hosting/assets.pyemits, into the same file:@source— absolute paths (e.pages_dir.as_posix())@import— alias specifiers (#module/<pkg>/...)The docstring explains the alias as avoiding
../../../.venv/lib/python3.12/site-packages/<pkg>/styles.css, which is fair for a relative path. But the@sourcelines right above are already absolute and interpreter-path-bearing, so absolute@importpaths would be no worse and would need no host config at all.Second, related problem: the template drops aliases the modules still need
The 0.0.27
vite.config.tstemplate also removes the npm-package-name alias block that maps@simple-module-py/<pkg>onto a module's directory. But module.tssources still import that way:site-packages/news/puck-blocks.ts:10→@simple-module-py/pagebuilder/pagebuilder/components/blockRegistrysite-packages/news/components/NewsFeed.tsx:5→@simple-module-py/pagebuilder/.../article-cards-renderFollowing the new template verbatim, our workspace-member module fails to build:
This is the case in #156 — which is closed, but whose fix (
moduleBareImportResolverno longer short-circuiting onfsRoot/projectRootcontainment) is still under## [Unreleased]in CHANGELOG.md and is not in 0.0.27. So the template change that depends on that fix shipped a release ahead of it. A freshsmpy newapp with a workspace module importing pagebuilder hits this on day one.We worked around both by keeping the package-name aliases alongside the new
#module/*ones — the prefixes are disjoint, so they compose:Suggested fixes
Roughly in order of how much they'd help:
@import, as@sourcealready does. Removes the host-config dependency entirely and makes the generated CSS self-contained. The stated objection (ugly relative paths) doesn't apply to absolute ones.gen-pagesverify it resolves — it already writesmodules.assets.json, so it can checkvite.config.tsreads that file and fail with the required diff rather than letting Vite fail later on a specifier the app never wrote.doctorcheck for the same thing, somake doctorcatches it before a build does.vite.config.ts; here is the diff" would have turned a confusing build failure into a two-minute edit. As of 0.0.27 the CHANGELOG has no per-version entries between 0.0.1 and Unreleased.Happy to send a PR for (1) or (4) if you have a preference.