fix(vite-plugin-angular): bypass server.fs restrictions on ?raw template imports#2259
Conversation
✅ Deploy Preview for analog-blog ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
✅ Deploy Preview for analog-app ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
✅ Deploy Preview for analog-docs ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
📝 WalkthroughWalkthroughThe plugin is updated to work around Vite 7.3.2's security restrictions on Estimated code review effort🎯 2 (Simple) | ⏱️ ~12 minutes 🚥 Pre-merge checks | ✅ 4✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. 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. Comment |
60e335c to
314d0de
Compare
… ?raw template imports Vite 7.3.2 tightened server.fs enforcement for ?raw query parameters, blocking Angular JIT template imports with "Denied ID" errors. Replace ?raw with a custom ?analog-raw query parameter and handle template loading directly in the plugin's load hook, bypassing Vite's stricter security checks without weakening server.fs protections. Closes #2256 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
314d0de to
20d4dcb
Compare
There was a problem hiding this comment.
🧹 Nitpick comments (1)
packages/vite-plugin-angular/src/lib/angular-vite-plugin.ts (1)
780-787: Consider adding error handling for file read failures.If
resolveIdreturns a path for a file that doesn't exist (e.g., typo intemplateUrl), thereadFilecall will throw an unhandledENOENTerror with a raw stack trace. A descriptive error message would improve developer experience.💡 Optional: wrap with descriptive error
if (id.endsWith('?analog-raw')) { const filePath = id.slice(0, -'?analog-raw'.length); - const content = await fsPromises.readFile(filePath, 'utf-8'); - return `export default ${JSON.stringify(content)}`; + try { + const content = await fsPromises.readFile(filePath, 'utf-8'); + return `export default ${JSON.stringify(content)}`; + } catch (e) { + throw new Error( + `[`@analogjs/vite-plugin-angular`] Failed to load template: ${filePath}`, + { cause: e }, + ); + } }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@packages/vite-plugin-angular/src/lib/angular-vite-plugin.ts` around lines 780 - 787, The load hook's readFile call can throw unhandled ENOENT errors; wrap the fsPromises.readFile(filePath, 'utf-8') call inside a try/catch in the async load(id) function and handle failures by raising a descriptive error that includes the computed filePath and the original error message (use this.error(...) if the plugin context is available, otherwise throw a new Error). Ensure the catch only rethrows after attaching the descriptive context so consumers see a clear message when a templateUrl/path is missing.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@packages/vite-plugin-angular/src/lib/angular-vite-plugin.ts`:
- Around line 780-787: The load hook's readFile call can throw unhandled ENOENT
errors; wrap the fsPromises.readFile(filePath, 'utf-8') call inside a try/catch
in the async load(id) function and handle failures by raising a descriptive
error that includes the computed filePath and the original error message (use
this.error(...) if the plugin context is available, otherwise throw a new
Error). Ensure the catch only rethrows after attaching the descriptive context
so consumers see a clear message when a templateUrl/path is missing.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 842d9864-364d-4a93-878a-d92945677de6
📒 Files selected for processing (2)
packages/vite-plugin-angular/src/lib/angular-vite-plugin.spec.tspackages/vite-plugin-angular/src/lib/angular-vite-plugin.ts
PR Checklist
Vite 7.3.2 includes security fixes (GHSA-v2wj-q39q-566r, GHSA-4w7w-66w2-5vf9) that tighten
server.fsenforcement for?rawquery parameters. The plugin resolves AngulartemplateUrlreferences as?rawimports internally, which are now blocked with "Denied ID" errors — breaking Vitest tests and dev server for components with external templates.Closes #2256
Affected scope
Recommended merge strategy for maintainer [optional]
What is the new behavior?
resolveIdhook remapsangular:jit:templateimports from?rawto a custom?analog-rawquery parameterresolveIdhandler intercepts any.html?rawimport and remaps it to?analog-raw, preventing the ID from reaching Vite's stricter?rawsecurity checkloadhook handles?analog-rawIDs by reading the file directly withfsPromises.readFileand returning the content as a default export?rawtemplate imports (JITresolveId, transform hook markers, angular-compiler JIT transform) are covered without modifying any of themThis avoids the workaround of adding
server.fs.allowwhich weakens the security fix.Test plan
nx format:checkpnpm buildpnpm testtemplateUrlAdditional:
vite-plugin-angulartests pass (52/52)angular-compilertests pass (466/466)resolveIdremapsangular:jit:templateand.html?rawimports to?analog-raw.html?rawinterception works without JIT modeDoes this PR introduce a breaking change?
Other information
The
?analog-rawquery parameter is an internal implementation detail — no public API changes. Thejit-transform.tsand transform hook still emit?rawin generated code; the newresolveIdhandler intercepts these before Vite can block them.