Skip to content

fix: scaffolded-project path assumptions (#283, #284, #287, #288) - #289

Open
antosubash wants to merge 2 commits into
mainfrom
worktree-fix-scaffold-path-issues
Open

fix: scaffolded-project path assumptions (#283, #284, #287, #288)#289
antosubash wants to merge 2 commits into
mainfrom
worktree-fix-scaffold-path-issues

Conversation

@antosubash

Copy link
Copy Markdown
Owner

Fixes #283, fixes #284, fixes #287, fixes #288.

Four reports filed against a sm new project scaffold, all one root cause: the framework assumed its own monorepo layout, where a module's directory and assembly are both SimpleModule.<Module>. sm new module scaffolds a bare <Module> for both.

#287 — page bundle 404 on every page load

The client built the bundle URL as _content/SimpleModule.<Module>/…, but an RCL serves its assets under its AssemblyName, so every scaffolded module 404'd before the fallback probe found it.

HtmlFileInertiaPageRenderer now declares the module-name → assembly-name mapping in the page shell, and resolvePage reads it, so the first request goes to the path that actually serves the bundle. Probing stays as a fallback for shells that predate the map, and for an unparseable one.

The same prefix assumption also meant a bare-named module's stylesheet was never linkedBuildModuleCssLinks only matched _content/SimpleModule.*. Module CSS discovery now consults the same mapping.

#283 / #284types.ts written into a directory no project owns

extract-ts-types.mjs hardcoded SimpleModule.<Module> as the output project and mkdirSync'd it unconditionally. It now resolves the project directory that actually exists and skips modules with no local source, so:

Also removes modules/Identity/src/SimpleModule.Identity/, which held only a generated types.ts for a contracts-only module and belonged to no project — the exact artifact #284 describes, committed here.

#288 — Tailwind never recompiled for new pages

Styles/app.css declares the module pages as @source globs, but TailwindBuild did not treat them as inputs, so a new page's utility classes were silently never generated. Module Pages//Views/, the host ClientApp, and the staged module bundles are now inputs, with @(TailwindExtraSourceFiles) as an extension point for hosts that add @source directives of their own.

Verification

Note for a follow-up

The scaffold's HostTemplates.AppCss() strips the @source "./_scan/" line, so a scaffolded host never scans the staged bundles of packaged modules — their utility classes would be missing for the same silent reason as #288. Left alone here since it is a separate change to the CLI templates.

Four reports from a `sm new project` scaffold, all the same root cause: the
framework assumed its own monorepo layout, where a module's directory and
assembly are both `SimpleModule.<Module>`. `sm new module` scaffolds a bare
`<Module>` for both.

Page bundle 404 (#287)
  The client guessed `_content/SimpleModule.<Module>/`, but an RCL serves its
  assets under its AssemblyName, so every scaffolded module 404'd on first
  load. The renderer now declares the module name -> assembly name mapping in
  the page shell and the resolver reads it, so the first request goes to the
  path that actually serves the bundle. Probing remains as a fallback for
  shells that predate the map. The same prefix assumption also kept a bare-named
  module's stylesheet from ever being linked; module CSS discovery now consults
  the same mapping.

types.ts written to a directory no project owns (#283, #284)
  extract-ts-types.mjs hardcoded `SimpleModule.<Module>` as the output project
  and created it unconditionally. It now resolves the project directory that
  actually exists and skips modules with no local source, so NuGet-installed
  modules no longer materialise phantom source trees in a consumer's repo and
  deleting a module no longer resurrects one. Removes the orphan
  modules/Identity/src/SimpleModule.Identity/, which held only a generated
  types.ts for a contracts-only module and belonged to no project.

Tailwind never recompiled for new pages (#288)
  Styles/app.css declares module pages as @source globs, but the MSBuild target
  did not treat them as inputs, so a new page's utility classes were silently
  never generated. Module Pages/Views, the host ClientApp, and the staged module
  bundles are now inputs, with @(TailwindExtraSourceFiles) as an extension point.

Verified: reproduced the stale-CSS failure on unmodified main and confirmed the
fix compiles the class; exercised the extraction script against both layouts and
a package-only module; confirmed the shell mapping and a single 200 for the page
bundle in a browser. Full suite green (20 assemblies), npm run check clean.
…s error

Follow-up to the review on #289.

Tailwind up-to-date check was still incomplete. `Styles/app.css` declares five
@source roots; only the module pages and ClientApp were tracked, so editing
`packages/SimpleModule.UI` — the most-edited shared code in the repo — left the
compiled CSS stale with exactly the #288 symptom. Adds the UI and client package
roots (via `SimpleModuleUiDir`/`SimpleModuleClientDir`, which resolve to the npm
packages in a scaffold and to `packages/` in the monorepo) and tracks
`docs/design-system/` through the `@(TailwindExtraSourceFiles)` extension point.

Moves the `Styles/_scan/**/*.js` glob into `CollectModuleAssets`. It was in an
evaluation-time ItemGroup, but those files are staged during execution, so on the
first build after installing a packaged module the glob expanded to nothing and
`TailwindBuild` was judged up to date. Declaring the item in the target that
stages them means the Inputs check, which runs afterwards, sees them.

Anchors the module glob to `*/src/*/Pages/**` instead of `**/Pages/**` so
evaluation no longer walks every module's bin/ and obj/ on every build, including
design-time builds.

`resolvePage` now reports the declared candidate's error rather than the last
probe's. With the declaration authoritative, a real failure in the module's own
bundle was being buried under a 404 from a fallback URL that was never going to
resolve.

Notes the scaffold's stripped `@source "./_scan/"` (#290) where the staging
target could otherwise be misread as covering packaged modules everywhere.
@antosubash

Copy link
Copy Markdown
Owner Author

Addressed the review in 10bc18b. Four of six findings fixed; two declined with reasons.

Fixed

  • Untracked @source roots — correct, and the more serious of the two Tailwind findings. app.css declares five roots; I had tracked two. Editing packages/SimpleModule.UI left the CSS stale with exactly the Tailwind build does not re-run when module Pages change, so new utility classes silently never compile #288 symptom, in the repo's most-edited shared code. Added the UI and client package roots via new SimpleModuleUiDir/SimpleModuleClientDir properties (npm packages in a scaffold, packages/ in the monorepo), and wired docs/design-system/ through @(TailwindExtraSourceFiles) — which also exercises the extension point.
  • _scan glob evaluated too early — correct. Moved the item declaration into CollectModuleAssets, after the Copy. Verified by deleting Styles/_scan/ and rebuilding: TailwindBuild runs in that same build (zero Skipping target "TailwindBuild") and the bundles are re-staged, rather than being missed until a second build.
  • Unanchored glob walking bin//obj/ — correct. Anchored to */src/*/Pages/**, which matches both the framework layout and sm new module's. Confirmed module pages are still tracked.
  • Fallback probe burying the real error — correct. resolvePage now reports the declared candidate's error instead of the last probe's. Checked all four cases; with {"Invoicing":"Invoicing"} declared, a failure now reports the error from _content/Invoicing/ rather than the 404 from the SimpleModule.Invoicing fallback.

Declined

  • Duplicate [Module] name last-write-wins — unreachable. SM0040 is a generator diagnostic with DiagnosticSeverity.Error, so two modules sharing a name fail the build. A runtime throw or warning would be dead code.
  • Scaffold strips @source "./_scan/" — a real bug, and the review is right that it is the reason those staged files go unscanned in a scaffold. It is a CLI template change with its own failure mode (a fresh scaffold has no Styles/_scan/, and Tailwind errors on a missing @source path), so it needs the scaffold to create the directory and wants its own verification against a real sm new project. Filed as Scaffolded host strips @source "./_scan/", so packaged modules' Tailwind classes are never compiled #290 and referenced from the comment on CollectModuleAssets so the staging target cannot be misread as covering packaged modules everywhere.

One correction to my own verification. My first attempt to reproduce the untracked-UI-root gap reported a false pass — a leftover mtime from a previous probe, then incidental input churn that reruns Tailwind on many builds in this repo. A clean before/after via timestamps is not reliable here. The finding is settled by inspection instead (none of the committed globs cover packages/SimpleModule.UI), plus MSBuild's own Skipping target "TailwindBuild" after touching that file on the pre-fix tree. After the fix, all five roots report tracked.

Full suite green (20 assemblies, 0 failures), npm run check clean, dotnet build 0 warnings.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment