Skip to content

Feature/angular zoneless support - #1274

Open
vorobey wants to merge 15 commits into
DevExpress:masterfrom
vorobey:feature/angular-zoneless-support
Open

vorobey wants to merge 15 commits into
DevExpress:masterfrom
vorobey:feature/angular-zoneless-support

Conversation

@vorobey

@vorobey vorobey commented Nov 6, 2026 •

Copy link
Copy Markdown
Contributor

Angular apps created by the CLI are now zoneless (Angular 21 default).

  • add-layout: detects zone-based projects and renders provideZoneChangeDetection in app.config.ts from the template; zone.js dependency/polyfill are added only for them
  • Template services are providedIn: 'root', so app.config.ts only registers the router
  • Layout and auth templates use signals
  • @angular/cdk version derived from the project's @angular/core; globalNgCliVersion removed
  • e2e: verify generated apps contain no zone.js

Merge and release after devextreme@26.2 is released.

@vorobey
vorobey requested a review from a team November 6, 2026 09:00
@vorobey vorobey self-assigned this Nov 6, 2026

Copilot AI left a comment

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.

🟡 Changes recommended

The provider merge can generate invalid router syntax, override custom authentication, and insert required services into the wrong configuration object.

4 open issues
What changed in this PR

Adds zoneless Angular support to the DevExtreme CLI and generated application templates, with release intended after DevExtreme 26.2.

Changes:

  • Converts template state to signals so asynchronous updates trigger rendering without Zone.js.
  • Merges layout providers into existing application configuration and stops forcing Zone.js.
  • Selects CDK versions from Angular core and adds zoneless generation checks.
File Description
packages/​devextreme-schematics/​src/​utility/​change.ts Applies only insertion changes.
packages/​devextreme-schematics/​src/​utility/​angular-version.ts Uses tolerant Angular version parsing.
packages/​devextreme-schematics/​src/​add-layout/​schema.json Removes the global CLI version option.
packages/​devextreme-schematics/​src/​add-layout/​README.md Removes a trailing blank line.
packages/​devextreme-schematics/​src/​add-layout/​index.ts Merges providers, selects CDK versions, and stops adding Zone.js.
packages/​devextreme-schematics/​src/​add-layout/​index_spec.ts Tests provider preservation, zoneless setup, and CDK selection.
packages/​devextreme-schematics/​src/​add-layout/​files/​src/​app/​shared/​services/​screen.service.ts Tracks screen sizes with a signal.
packages/​devextreme-schematics/​src/​add-layout/​files/​src/​app/​shared/​components/​reset-password-form/​reset-password-form.component.ts Converts loading state to a signal.
packages/​devextreme-schematics/​src/​add-layout/​files/​src/​app/​shared/​components/​reset-password-form/​reset-password-form.component.html Reads the loading signal.
packages/​devextreme-schematics/​src/​add-layout/​files/​src/​app/​shared/​components/​login-form/​login-form.component.ts Converts loading state to a signal.
packages/​devextreme-schematics/​src/​add-layout/​files/​src/​app/​shared/​components/​login-form/​login-form.component.html Reads the loading signal.
packages/​devextreme-schematics/​src/​add-layout/​files/​src/​app/​shared/​components/​header/​header.component.ts Stores asynchronously loaded user data in a signal.
packages/​devextreme-schematics/​src/​add-layout/​files/​src/​app/​shared/​components/​create-account-form/​create-account-form.component.ts Converts loading state to a signal.
packages/​devextreme-schematics/​src/​add-layout/​files/​src/​app/​shared/​components/​create-account-form/​create-account-form.component.html Reads the loading signal.
packages/​devextreme-schematics/​src/​add-layout/​files/​src/​app/​shared/​components/​change-password-form/​change-password-form.component.ts Converts loading state to a signal.
packages/​devextreme-schematics/​src/​add-layout/​files/​src/​app/​shared/​components/​change-password-form/​change-password-form.component.html Reads the loading signal.
packages/​devextreme-schematics/​src/​add-layout/​files/​src/​app/​layouts/​side-nav-outer-toolbar/​side-nav-outer-toolbar.component.ts Converts navigation and layout state to signals.
packages/​devextreme-schematics/​src/​add-layout/​files/​src/​app/​layouts/​side-nav-outer-toolbar/​side-nav-outer-toolbar.component.html Updates bindings for signal-based state.
packages/​devextreme-schematics/​src/​add-layout/​files/​src/​app/​layouts/​side-nav-inner-toolbar/​side-nav-inner-toolbar.component.ts Converts navigation and layout state to signals.
packages/​devextreme-schematics/​src/​add-layout/​files/​src/​app/​layouts/​side-nav-inner-toolbar/​side-nav-inner-toolbar.component.html Updates bindings for signal-based state.
packages/​devextreme-schematics/​src/​add-layout/​files/​src/​app/​app.config.ts Removes explicit zone-based change detection.
packages/​devextreme-schematics/​src/​add-app-template/​schema.json Removes the global CLI version option.
packages/​devextreme-schematics/​src/​add-app-template/​index.ts Stops forwarding the removed version option.
packages/​devextreme-cli/​testing/​verifying.js Checks generated Angular apps for Zone.js usage.
packages/​devextreme-cli/​src/​utility/​ng-version.js Removes public CLI version lookup helpers.
packages/​devextreme-cli/​src/​applications/​application.angular.js Stops disabling zoneless mode and forwarding CLI versions.

Review effort: Balanced

Copilot AI left a comment

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.

🟡 Changes recommended

Unresolved merge defects can overwrite custom provider configuration and introduce conflicting imports that prevent compilation.

2 open issues
1 previously missed issue

In code that hasn't changed since last review

Medium severity Resolve import aliases when matching and inserting providers

packages/​devextreme-schematics/​src/​add-layout/​index.ts:331

Provider matching ignores import aliases: AuthService as AppAuth with { provide: AppAuth, useClass: CustomAuthService } is treated as missing AuthService, so the merge appends a default registration for an already configured token. The same issue affects an aliased provideRouter. Resolve imported symbols when comparing providers, and reuse their local bindings when inserting references.

4 resolved since last review

Review effort: Balanced

Copilot AI left a comment

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.

🔵 Needs a closer look

Angular release-candidate versions now select stable-only CDK ranges, causing dependency installation to fail before the corresponding stable CDK release is available.

No open issues 🎉

2 resolved since last review

Review effort: Balanced

@vorobey
vorobey requested a review from a team November 9, 2026 16:19
vorobey and others added 2 commits November 10, 2026 11:25
Reverts 6dbfeab, 8cd6e68, d9fcabd, 0dbe244, 7e244c8.
The team decided to keep overwriting app.config.ts with the template.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
providers: [<% if (!zoneless) { %>
provideZoneChangeDetection({ eventCoalescing: true }),<% } %>
provideRouter(routes, withHashLocation()),
AuthGuardService,

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Why are you removing our services?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

i've added for our services @Injectable({ providedIn: 'root' }). So here no reason to left them in providers array. It's debatable decision.
Leaving them in providers array is more transparent choice and matches our previous generated apps. But it seems @Injectable({ providedIn: 'root' }) is current angular convention because ng generate service does the same thing.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Plus - smaller app.config might be easier to restore by user if we overwrite smth

Copilot AI left a comment

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.

🟡 Changes recommended

The changes remove Angular 20’s required zoneless provider, causing affected apps to fail at bootstrap, and convert Angular RC ranges to unavailable stable CDK versions, causing dependency installation failures.

1 open issue

Review effort: Balanced

This branch has not been deployed

No deployments
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.

4 participants