Repository navigation
fix(vite-plugin-angular): preserve compiler roots and lifecycle across Vite versions #2520
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
5277af9
47ca5f2
b3482e5
3e0d047
52ec53a
1a3c400
cf97576
e767273
fe128cb
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1 +1 @@ | ||
| 24.14.1 | ||
| 24.15.0 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| .node-version |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| import { expect, test } from '@playwright/test'; | ||
|
|
||
| test('caller hints cannot disable SSR on an enabled route', async ({ | ||
| request, | ||
| }) => { | ||
| for (const supplied of [false, true]) { | ||
| const response = await request.get('/products/1?ssr-policy=1', { | ||
| headers: supplied ? { 'x-analog-no-ssr': 'true' } : {}, | ||
| }); | ||
| expect(response.status()).toBe(200); | ||
| const html = await response.text(); | ||
| expect(html).toContain('Product Details'); | ||
| expect(html).toContain('ng-server-context'); | ||
| } | ||
| }); | ||
|
|
||
| test('caller hints cannot enable SSR on a configured client route', async ({ | ||
| request, | ||
| }) => { | ||
| const response = await request.get('/cart', { | ||
| headers: { 'x-analog-no-ssr': 'false' }, | ||
| }); | ||
| expect(response.status()).toBe(200); | ||
| expect(await response.text()).not.toContain('ng-server-context'); | ||
| }); |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,9 +1,10 @@ | ||
| # Angular Compilation | ||
|
|
||
| The AnalogJS Vite Plugin (`@analogjs/vite-plugin-angular`) compiles your Angular components, directives, and pipes to Ivy definitions during the Vite build. It provides two compilation paths: | ||
| The AnalogJS Vite Plugin (`@analogjs/vite-plugin-angular`) compiles your Angular components, directives, and pipes to Ivy definitions during the Vite build. It provides these compilation paths: | ||
|
|
||
| - **Default compilation**: Angular's own compiler (`ngtsc`), with full compile-time type checking. | ||
| - **Default compilation**: Angular's own compiler (`NgtscProgram`), with optional compile-time type checking. | ||
| - **Fast compile**: an in-tree single-pass compiler that produces the same Ivy output much faster. | ||
| - **Experimental Compilation API**: Angular's build compilation API, enabled explicitly with a compatible `@angular/build` installation. | ||
|
|
||
| Both emit identical Ivy code and identical runtime behavior, because both ultimately call the same `@angular/compiler` lowering APIs. | ||
|
|
||
|
|
@@ -25,7 +26,31 @@ export default defineConfig({ | |
| }); | ||
| ``` | ||
|
|
||
| The default path runs Angular's compiler through the Angular Compilation API. It performs **full TypeScript and template type checking** (including `strictTemplates`), emits declaration files, and supports i18n message extraction. Use it when you want compile-time safety: wrong template bindings, missing inputs, and type mismatches fail the build. | ||
| The default path uses `NgtscProgram`; `experimental.useAngularCompilationAPI` defaults to `false`. Set `disableTypeChecking: false` and enable `strictTemplates` in your Angular compiler options when TypeScript and template errors must fail the build. Type checking is disabled by default for build throughput. | ||
|
|
||
| ```ts | ||
| angular({ disableTypeChecking: false }); | ||
| ``` | ||
|
Comment on lines
+31
to
+33
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win Show The preceding text requires both As per path instructions, this documentation review prioritizes copy-paste accuracy. 🤖 Prompt for AI AgentsSource: Path instructions |
||
|
|
||
| ## Experimental Compilation API | ||
|
|
||
| With an `@angular/build` version that exposes `createAngularCompilation` through `@angular/build/private`, opt into Angular's build compilation API: | ||
|
|
||
| ```ts | ||
| angular({ | ||
| experimental: { useAngularCompilationAPI: true }, | ||
| disableTypeChecking: false, | ||
| include: ['src/integrations/**/*.ts'], | ||
| }); | ||
| ``` | ||
|
|
||
| Configured TypeScript roots, integration-provided includes, and expanded project roots are combined before compilation. The normal compiler also includes file-replacement targets, so replacement components outside the original tsconfig are AOT-compiled instead of falling through to a generic TypeScript transform. | ||
|
|
||
| The Angular version alone does not establish availability: for example, `@angular/build@20.1.0` does not expose this factory. Unsupported installations fail during configuration with an actionable diagnostic. Leave the option disabled to use normal compilation on those versions. | ||
|
|
||
| For Vite library builds, the experimental API emits JavaScript only. Generate `.d.ts` files in a separate declaration step. Angular's compilation API returns one result per source file, so enabling declaration emit there would overwrite the JavaScript result with declaration text. The repository's package builds use their own declaration-emission step. | ||
|
|
||
| Both paths wait for active compilation before transforming emitted modules. Experimental compilation shares its emitted modules with the HMR middleware; template-only changes invalidate the affected component and deliver Angular's replacement metadata. Compiler shutdown waits for active work before disposing its worker. Plugin setup and stylesheet errors preserve the original exception as `cause` together with the plugin/file context. | ||
|
|
||
| ## Fast compile | ||
|
|
||
|
|
@@ -50,13 +75,15 @@ export default defineConfig({ | |
| ``` | ||
|
|
||
| :::note | ||
| In an Analog application, configure the plugin through `@analogjs/platform` instead. Its `analog()` plugin forwards the same `fastCompile` option: | ||
| In an Analog v3 application, configure compilation on `angular()` alongside the platform plugin: | ||
|
|
||
| ```ts | ||
| import analog from '@analogjs/platform'; | ||
| import angular from '@analogjs/vite-plugin-angular'; | ||
| import { nitro } from 'nitro/vite'; | ||
|
|
||
| export default defineConfig({ | ||
| plugins: [analog({ fastCompile: true })], | ||
| plugins: [analog(), angular({ fastCompile: true }), nitro()], | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win Import The code block calls As per path instructions, this documentation review prioritizes copy-paste accuracy. 🤖 Prompt for AI AgentsSource: Path instructions |
||
| }); | ||
| ``` | ||
|
|
||
|
|
@@ -157,15 +184,27 @@ Fast compile is validated against Angular `17`, `18`, `19`, `20`, `21`, `22`, an | |
|
|
||
| For overall Angular/Analog/Vite version support, see [Version Compatibility](/docs/guides/compatibility). | ||
|
|
||
| ### Compiler contributor checks | ||
|
|
||
| The compiler compatibility workflow separates compiler API tests from installed-package consumer builds. The consumer matrix uses Angular 17.3, 18.2, 19.0, 20.0, and 20.1 with Vite 6; Angular 21 with Vite 7; and Angular 22 with Vite 6, 7, and 8. It is a representative matrix, not every possible cross-product. The experimental path is checked when the installed build package exposes it; other tuples verify the explicit rejection as well as normal and fast compilation. | ||
|
|
||
| Run one tuple from the repository root: | ||
|
|
||
| ```bash | ||
| pnpm exec nx run vite-plugin-angular:compat-smoke --vite=8.0.8 --angular=22.0.0 | ||
| ``` | ||
|
|
||
| The target builds and packs the package, installs it into an isolated consumer, and checks normal compilation, additional roots/replacements, and fast full/partial compilation. It also checks experimental Compilation API output on supported Angular versions. Angular 22 tuples additionally use Chromium to verify template HMR preserves component state in both compiler modes, and that boot/manual reload works with Angular HMR disabled. Each run retains its exact installed versions, lockfile, and result under `dist/compiler-vite-smoke/`. | ||
|
|
||
| ### Default vs fast compile | ||
|
|
||
| | | Default | Fast compile | | ||
| | ----------------------------------- | ----------------------- | ------------------------------------- | | ||
| | Ivy output | Full | Identical | | ||
| | Cold build / hot rebuild | Standard | Significantly faster | | ||
| | Compile-time template type checking | Yes (`strictTemplates`) | No (use the Angular Language Service) | | ||
| | i18n message extraction | Yes | `$localize` emitted | | ||
| | Library / partial builds | Yes | Yes (`fastCompileMode: 'partial'`) | | ||
| | | Default | Fast compile | | ||
| | ----------------------------------- | -------------------------------------------------------------- | ------------------------------------- | | ||
| | Ivy output | Full | Identical | | ||
| | Cold build / hot rebuild | Standard | Significantly faster | | ||
| | Compile-time template type checking | Opt in with `disableTypeChecking: false` and `strictTemplates` | No (use the Angular Language Service) | | ||
| | i18n message extraction | Yes | `$localize` emitted | | ||
| | Library / partial builds | Yes | Yes (`fastCompileMode: 'partial'`) | | ||
|
|
||
| ## Trade-offs | ||
|
|
||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.