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
{{ message }}
Repository navigation
Module-shipped .tsx pages need symlink + vite aliases + inline tsconfig boilerplate #73
Module pages live in modules/<m>/lacowiki_<m>/pages/<Name>.tsx (workspace member) or .venv/lib/python3.12/site-packages/<m>/pages/<Name>.tsx (wheel-installed). Vite's normal Node module resolution walks UP from the .tsx file looking for node_modules and fails because module dirs don't have one.
The framework currently requires three workarounds:
Symlink node_modules into every module dir. Each module's root needs node_modules → ../../host/client_app/node_modules. Without this, Vite can't resolve import { Button } from '@simple-module-py/ui/components/ui/button' from a module page.
Aliases in vite.config.ts. The host's vite config has to alias react/jsx-runtime, react, react-dom, etc. to absolute paths in host/client_app/node_modules/, otherwise module .tsx files can't resolve them.
Module-side tsconfig.json can't extend @simple-module-py/tsconfig. TypeScript's extends resolves relative to the tsconfig's location, but @simple-module-py/tsconfig lives in host/client_app/node_modules — TS can't find it from modules/<m>/tsconfig.json. Every module tsconfig has to inline the base config verbatim.
Reproduction
Generate a host, add a workspace module under modules/lacowiki_legends/.
Every module's tsconfig.json is a 19-line inline copy of the base.
Host's vite.config.ts has 8 alias entries.
Suggested fix
This is core to how module-shipped pages work — not a paper-cut. Options:
Have the framework's gen-pages step also create the symlinks when it walks the manifest. One-liner per module on regeneration; eliminates manual symlinking.
Publish @simple-module-py/tsconfig as a relative alias (e.g. via a per-module tsconfig template the framework writes alongside the symlink).
Ship a Vite plugin (@simple-module-py/vite-plugin) that handles the resolution differences between in-tree and wheel-installed module pages, including the React aliases. Then vite.config.ts becomes one plugins: [smPlugin()] line.
Impact
The "five-step boilerplate every new module needs" is documented in every plan in our project. New users hit at least three of these traps before the build compiles.
The module scaffold's tsconfig.json.tpl extends @simple-module-py/tsconfig/base.json via the workspace dep declared in package.json.tpl's devDependencies, so the inline copy is no longer needed.
server.fs.allow is auto-populated from modules.manifest.json (gen-pages), covering both workspace and wheel-installed module page directories.
Activity
fix: address framework papercuts (#66, #68, #71, #73, #75, #76, #81, #90
antosubash commentedon May 1, 2026
Closing — addressed by commit ade3e24 (PR #98) plus the existing scaffold/workspace setup:
node_modules, so module dirs no longer need a manualnode_modulessymlink.host/client_app/vite.config.tsnow usesresolve.dedupe+optimizeDepsforreact,react-dom, and the JSX runtimes, so wheel-installed module pages share React identity with the host (also resolves @vitejs/plugin-react 'can't detect preamble' on module-shipped .tsx pages #66).tsconfig.json.tplextends@simple-module-py/tsconfig/base.jsonvia the workspace dep declared inpackage.json.tpl'sdevDependencies, so the inline copy is no longer needed.server.fs.allowis auto-populated frommodules.manifest.json(gen-pages), covering both workspace and wheel-installed module page directories.Generated by Claude Code