Skip to content

Build fix#334

Merged
ucswift merged 1 commit intomasterfrom
develop
Apr 20, 2026
Merged

Build fix#334
ucswift merged 1 commit intomasterfrom
develop

Conversation

@ucswift
Copy link
Copy Markdown
Member

@ucswift ucswift commented Apr 20, 2026

Summary by CodeRabbit

  • Chores
    • Optimized JavaScript asset serving and caching strategy for improved load performance.
    • Modernized the frontend build pipeline infrastructure.

@request-info
Copy link
Copy Markdown

request-info Bot commented Apr 20, 2026

Thanks for opening this, but we'd appreciate a little more information. Could you update it with more details?

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 20, 2026

📝 Walkthrough

Walkthrough

Modified static file serving configuration in Startup.cs to transition from legacy WebOptimizer bundling to Vite ESM asset serving under /js/ng. Implemented per-request cache-control headers for chunk files and other assets, with differing immutability policies. Added required namespaces for file provider support.

Changes

Cohort / File(s) Summary
Static File Serving Configuration
Web/Resgrid.Web/Startup.cs
Replaced WebOptimizer JavaScript bundling with direct static file serving for Vite ESM assets under /js/ng. Added conditional middleware to serve static files with per-request cache-control strategies: chunk files receive long-lived caching (max-age=31536000,immutable), while other assets receive no-cache headers. Added System.IO and Microsoft.Extensions.FileProviders using directives.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

  • Build fix #333 — Modifies the same Startup.cs file to adjust JavaScript asset handling in the build/serve pipeline, specifically around bundling and minification strategies.
🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Title check ❓ Inconclusive The title 'Build fix' is vague and generic, using a non-descriptive term that doesn't convey meaningful information about what specific build issue was addressed. Replace with a more descriptive title that specifies the nature of the fix, such as 'Configure static file serving for Vite ESM assets' or 'Update Startup.cs to handle Angular/Vite JavaScript bundling'.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch develop

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@Web/Resgrid.Web/Startup.cs`:
- Around line 596-603: The cache policy currently marks only "/js/ng/chunks" as
immutable; update the OnPrepareResponse logic to also treat "/js/ng/assets" as
immutable by checking both path segments (e.g., include "/js/ng/assets"
alongside "/js/ng/chunks" when computing cacheControl) so fingerprinted assets
under assets/[name]-[hash][extname] get
"public,max-age=31536000,immutable,no-transform" while non-hashed entries like
react-elements.js remain "no-cache,no-transform"; modify the conditional in the
OnPrepareResponse delegate accordingly.
- Around line 592-605: The Cache-Control decision in the OnPrepareResponse
lambda for clientApp.UseStaticFiles only marks "/js/ng/chunks" as immutable;
update the conditional in that lambda (the cacheControl assignment using
context.Context.Request.Path.StartsWithSegments) to also treat "/js/ng/assets"
as long-lived (e.g., use StartsWithSegments("/js/ng/chunks") ||
StartsWithSegments("/js/ng/assets")) so both content-hashed chunks and assets
get "public,max-age=31536000,immutable,no-transform" while leaving unhashed
entries (like react-elements.js) using "no-cache,no-transform".
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 85f11027-d174-4b20-abca-a3289e60ecd9

📥 Commits

Reviewing files that changed from the base of the PR and between d3406e9 and 192e363.

📒 Files selected for processing (1)
  • Web/Resgrid.Web/Startup.cs

Comment on lines +592 to +605
clientApp.UseStaticFiles(new StaticFileOptions
{
FileProvider = new PhysicalFileProvider(Path.Combine(env.WebRootPath, "js", "ng")),
RequestPath = "/js/ng",
OnPrepareResponse = context =>
{
var cacheControl = context.Context.Request.Path.StartsWithSegments("/js/ng/chunks")
? "public,max-age=31536000,immutable,no-transform"
: "no-cache,no-transform";

context.Context.Response.Headers["Cache-Control"] = cacheControl;
}
});
});
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Confirm whether the Vite output directory is expected to always exist at Configure-time
# (e.g. checked in, produced by an msbuild target, or a pre-run step).
fd -t d -u '^ng$' | rg -n 'wwwroot/js/ng'
rg -nP --type=xml -C2 '(js[/\\\\]ng|vite|npm (run )?build)' -g '*.csproj'
rg -nP -C2 '(js[/\\\\]ng|vite\s+build|npm\s+run\s+build)' -g '!node_modules' -g '!*.min.*' -g '!*.map'

Repository: Resgrid/Core

Length of output: 6521


🏁 Script executed:

#!/bin/bash

# Check if wwwroot/js/ng exists in git (not gitignored)
git ls-files | grep -E 'wwwroot/js/ng'

# Check .gitignore patterns that might exclude this directory
cat .gitignore 2>/dev/null | grep -E '(wwwroot|js|ng|/dist)' || echo "No gitignore patterns found matching"

# Check if wwwroot itself is gitignored
git check-ignore -v 'Web/Resgrid.Web/wwwroot' 2>/dev/null || echo "wwwroot is not gitignored"
git check-ignore -v 'Web/Resgrid.Web/wwwroot/js/ng' 2>/dev/null || echo "wwwroot/js/ng is not gitignored"

# List what's actually in the directory in git
echo "=== Files in wwwroot/js/ng in git ==="
git ls-files | grep 'wwwroot/js/ng' | head -20 || echo "No files found in git"

Repository: Resgrid/Core

Length of output: 2726


Cache-Control headers should apply immutable to all content-hashed assets, not just chunks.

Per vite.config.ts, both /js/ng/chunks/ and /js/ng/assets/ output are content-hashed ([name]-[hash] pattern), making them safe for long-lived caching. Currently only chunks receive immutable, max-age=31536000; assets still get no-cache, which undermines the caching benefit of the hash. The unhashed entry react-elements.js correctly stays at no-cache.

Update the cache-control logic to treat all hashed assets uniformly.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Web/Resgrid.Web/Startup.cs` around lines 592 - 605, The Cache-Control
decision in the OnPrepareResponse lambda for clientApp.UseStaticFiles only marks
"/js/ng/chunks" as immutable; update the conditional in that lambda (the
cacheControl assignment using context.Context.Request.Path.StartsWithSegments)
to also treat "/js/ng/assets" as long-lived (e.g., use
StartsWithSegments("/js/ng/chunks") || StartsWithSegments("/js/ng/assets")) so
both content-hashed chunks and assets get
"public,max-age=31536000,immutable,no-transform" while leaving unhashed entries
(like react-elements.js) using "no-cache,no-transform".

Comment on lines +596 to +603
OnPrepareResponse = context =>
{
var cacheControl = context.Context.Request.Path.StartsWithSegments("/js/ng/chunks")
? "public,max-age=31536000,immutable,no-transform"
: "no-cache,no-transform";

context.Context.Response.Headers["Cache-Control"] = cacheControl;
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Hashed /js/ng/assets/* files are missing the immutable cache policy.

The vite.config.ts referenced in context emits three output groups, but only one of them is being treated as immutable here:

  • react-elements.js — entry, not hashed → no-cache ✅ correct
  • chunks/[name]-[hash].js — hashed → immutable ✅ correct
  • assets/[name]-[hash][extname] — hashed → currently no-cache

/js/ng/assets/* is content-hashed just like chunks/*, so it's equally safe for long-term immutable caching. As written, browsers will revalidate those fingerprinted assets on every navigation, which negates the hashing strategy.

♻️ Suggested tweak
 OnPrepareResponse = context =>
 {
-	var cacheControl = context.Context.Request.Path.StartsWithSegments("/js/ng/chunks")
+	var path = context.Context.Request.Path;
+	var isHashed = path.StartsWithSegments("/js/ng/chunks")
+		|| path.StartsWithSegments("/js/ng/assets");
+	var cacheControl = isHashed
 		? "public,max-age=31536000,immutable,no-transform"
 		: "no-cache,no-transform";

 	context.Context.Response.Headers["Cache-Control"] = cacheControl;
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
OnPrepareResponse = context =>
{
var cacheControl = context.Context.Request.Path.StartsWithSegments("/js/ng/chunks")
? "public,max-age=31536000,immutable,no-transform"
: "no-cache,no-transform";
context.Context.Response.Headers["Cache-Control"] = cacheControl;
}
OnPrepareResponse = context =>
{
var path = context.Context.Request.Path;
var isHashed = path.StartsWithSegments("/js/ng/chunks")
|| path.StartsWithSegments("/js/ng/assets");
var cacheControl = isHashed
? "public,max-age=31536000,immutable,no-transform"
: "no-cache,no-transform";
context.Context.Response.Headers["Cache-Control"] = cacheControl;
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@Web/Resgrid.Web/Startup.cs` around lines 596 - 603, The cache policy
currently marks only "/js/ng/chunks" as immutable; update the OnPrepareResponse
logic to also treat "/js/ng/assets" as immutable by checking both path segments
(e.g., include "/js/ng/assets" alongside "/js/ng/chunks" when computing
cacheControl) so fingerprinted assets under assets/[name]-[hash][extname] get
"public,max-age=31536000,immutable,no-transform" while non-hashed entries like
react-elements.js remain "no-cache,no-transform"; modify the conditional in the
OnPrepareResponse delegate accordingly.

@ucswift
Copy link
Copy Markdown
Member Author

ucswift commented Apr 20, 2026

Approve

Copy link
Copy Markdown

@github-actions github-actions Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This PR is approved.

@ucswift ucswift merged commit 48e2a86 into master Apr 20, 2026
19 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant