Skip to content
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

Upgrade to Angular 19 #19772

Open
wants to merge 26 commits into
base: develop-next-major
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
158766c
chore: Nx migration (all packages and their migration)
pawelfras Dec 12, 2024
f95bd2c
chore: Change Version Range Specifier For Typescript
pawelfras Dec 12, 2024
54ca560
fix: Build issues
pawelfras Dec 13, 2024
51ae9c4
chore: Update '@angular-builders/custom-webpack' to '19.0.0-beta.0'
pawelfras Dec 13, 2024
71152c8
fix: Issues In Unit Tests
pawelfras Dec 4, 2024
f77c7eb
chore: Update dependencies
pawelfras Dec 16, 2024
1126c06
fix: Fix issues with schematics and related unit tests
pawelfras Dec 17, 2024
e3e935d
chore: Fix linter issues
pawelfras Dec 17, 2024
4048f17
chore: Fix prettier issues
pawelfras Dec 17, 2024
34574a8
chore: Update NgRx to v19.0.0-beta.0
pawelfras Dec 17, 2024
b1bc98c
chore: Upgrade `@typescript-eslint` packages to 8.18.1
pawelfras Dec 17, 2024
6d1bf09
chore: Update package-lock file
pawelfras Dec 17, 2024
ccf37f2
chore: Upgrade NgRx to stable version 19.0.0
pawelfras Dec 18, 2024
c1fa528
chore: Update dependencies and package-lock file
pawelfras Dec 18, 2024
3984894
fix: Jest tests issues
pawelfras Dec 18, 2024
85526ca
Trigger Build
pawelfras Dec 19, 2024
a004277
Trigger Build
pawelfras Dec 19, 2024
8da6be2
chore: Initial migration docs
pawelfras Dec 24, 2024
ef4ede7
refactor: Adjust installation schematics for SSR to use `server/index…
pawelfras Dec 30, 2024
89b2d08
docs: Update migration docs
pawelfras Dec 31, 2024
1ec74e0
chore Upgrade '@angular-builders/custom-webpack' to version 19.0.0
pawelfras Jan 7, 2025
3fb0b3a
Add license header
github-actions[bot] Jan 7, 2025
587ce7b
Revert "Add license header"
pawelfras Jan 7, 2025
c304b34
Add license header
github-actions[bot] Jan 7, 2025
c59ccf8
Revert "Add license header"
pawelfras Jan 8, 2025
b5500cb
Merge branch 'develop-next-major' into epic/upgrade-to-angular-19
pawelfras Jan 8, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
2 changes: 1 addition & 1 deletion .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
],
"plugins": ["deprecation", "@typescript-eslint", "@nx", "@stylistic/ts"],
"rules": {
"@angular-eslint/no-host-metadata-property": "off",
"deprecation/deprecation": "warn",
"prefer-arrow/prefer-arrow-functions": "off",
"space-before-function-paren": "off",
Expand All @@ -30,6 +29,7 @@
"no-fallthrough": "off",
"prefer-const": "off",
"@angular-eslint/use-lifecycle-interface": "error",
"@angular-eslint/prefer-standalone": "off",
"@stylistic/ts/quotes": "off",
"@stylistic/ts/member-delimiter-style": [
"error",
Expand Down
15 changes: 12 additions & 3 deletions core-libs/setup/jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,18 @@ const { defaultTransformerOptions } = require('jest-preset-angular/presets');
/** @type {import('ts-jest/dist/types').JestConfigWithTsJest} */
module.exports = {
preset: 'jest-preset-angular',
moduleNameMapper: pathsToModuleNameMapper(compilerOptions.paths || {}, {
prefix: '<rootDir>/',
}),
moduleNameMapper: {
...pathsToModuleNameMapper(compilerOptions.paths || {}, {
prefix: '<rootDir>/',
}),
// mapping required to use `beasties` from node modules that has proper ES module format
// instead of the version internalized by the Angular Team which file format is not supported
// by Jest.
// for more, see: https://github.com/angular/angular-cli/pull/28228
// and: https://github.com/angular/angular-cli/pull/28726
'^../third_party/beasties/index.js$':
'<rootDir>/../../node_modules/beasties',
},
setupFilesAfterEnv: ['<rootDir>/setup-jest.ts'],
transform: {
'^.+\\.(ts|js|mjs|html|svg)$': [
Expand Down
6 changes: 3 additions & 3 deletions core-libs/setup/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,15 @@
"tslib": "^2.6.2"
},
"peerDependencies": {
"@angular/core": "^18.2.9",
"@angular/ssr": "^18.2.9",
"@angular/core": "^19.0.3",
"@angular/ssr": "^19.0.4",
"@spartacus/cart": "2211.32.0-1",
"@spartacus/core": "2211.32.0-1",
"@spartacus/order": "2211.32.0-1",
"@spartacus/user": "2211.32.0-1"
},
"optionalDependencies": {
"@angular/platform-server": "^18.2.9",
"@angular/platform-server": "^19.0.3",
"express": "^4.21.2"
},
"publishConfig": {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@
* SPDX-License-Identifier: Apache-2.0
*/

import { CommonEngineOptions, CommonEngineRenderOptions } from '@angular/ssr';
import {
CommonEngineOptions,
CommonEngineRenderOptions,
} from '@angular/ssr/node';
import { NgSetupOptions } from '../engine/ng-express-engine';
import {
OptimizedSsrEngine,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@ exports[`CxCommonEngine should handle APP_INITIALIZER errors the standard Angula

exports[`CxCommonEngine should handle errors propagated from SSR 1`] = `"test error"`;

exports[`CxCommonEngine should not override providers passed to options 1`] = `"<html data-critters-container><head></head><body><cx-token ng-version="18.2.9" ng-server-context="ssr">message:test</cx-token></body></html>"`;
exports[`CxCommonEngine should not override providers passed to options 1`] = `"<html data-beasties-container><head></head><body><cx-token ng-version="19.0.3" ng-server-context="ssr">message:test</cx-token></body></html>"`;

exports[`CxCommonEngine should return html if no errors 1`] = `"<html data-critters-container><head></head><body><cx-mock ng-version="18.2.9" ng-server-context="ssr">some template</cx-mock></body></html>"`;
exports[`CxCommonEngine should return html if no errors 1`] = `"<html data-beasties-container><head></head><body><cx-mock ng-version="19.0.3" ng-server-context="ssr">some template</cx-mock></body></html>"`;
8 changes: 7 additions & 1 deletion core-libs/setup/ssr/engine/cx-common-engine.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,11 @@ import { PROPAGATE_ERROR_TO_SERVER } from '../error-handling/error-response/prop
import { CxCommonEngine } from './cx-common-engine';

// Test how the CxCommonEngine handles successful server-side rendering
@Component({ selector: 'cx-mock', template: 'some template' })
@Component({
selector: 'cx-mock',
template: 'some template',
standalone: false,
})
export class SuccessComponent {}

@NgModule({
Expand All @@ -22,6 +26,7 @@ export class SuccessServerModule {}
@Component({
selector: 'cx-response',
template: ``,
standalone: false,
})
export class WithPropagatedErrorComponent {
constructor() {
Expand All @@ -43,6 +48,7 @@ export const SOME_TOKEN = new InjectionToken<string>('SOME_TOKEN');
@Component({
selector: 'cx-token',
template: `message:{{ someToken }}`,
standalone: false,
})
export class TokenComponent {
someToken = inject(SOME_TOKEN);
Expand Down
2 changes: 1 addition & 1 deletion core-libs/setup/ssr/engine/cx-common-engine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
CommonEngine,
CommonEngineOptions,
CommonEngineRenderOptions,
} from '@angular/ssr';
} from '@angular/ssr/node';
import { PROPAGATE_ERROR_TO_SERVER } from '../error-handling/error-response/propagate-error-to-server';

/**
Expand Down
14 changes: 12 additions & 2 deletions core-libs/setup/ssr/engine/ng-express-engine.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,11 @@ import { ngExpressEngine } from './ng-express-engine';
* - https://github.com/angular/universal/blob/e798d256de5e4377b704e63d993dc56ea35df97d/modules/express-engine/spec/mock.server.module.ts
*
*/
@Component({ selector: 'cx-mock', template: 'some template' })
@Component({
selector: 'cx-mock',
template: 'some template',
standalone: false,
})
export class MockComponent {}

/**
Expand Down Expand Up @@ -57,7 +61,11 @@ export class MockServerModule {}
* - https://github.com/angular/universal/blob/e798d256de5e4377b704e63d993dc56ea35df97d/modules/express-engine/spec/mock.server.module.ts
*
*/
@Component({ selector: 'cx-request', template: `url:{{ _req.url }}` })
@Component({
selector: 'cx-request',
template: `url:{{ _req.url }}`,
standalone: false,
})
export class RequestComponent {
constructor(@Inject(REQUEST) public readonly _req: any) {}
}
Expand Down Expand Up @@ -94,6 +102,7 @@ export class RequestServerModule {}
@Component({
selector: 'cx-response',
template: `statusCode:{{ _res.statusCode }}`,
standalone: false,
})
export class ResponseComponent {
constructor(@Inject(RESPONSE) public readonly _res: any) {}
Expand Down Expand Up @@ -144,6 +153,7 @@ export const SOME_TOKEN = new InjectionToken<string>('SOME_TOKEN');
@Component({
selector: 'cx-token',
template: `message:{{ _someToken.message }}`,
standalone: false,
})
export class TokenComponent {
constructor(@Inject(SOME_TOKEN) public readonly _someToken: any) {}
Expand Down
5 changes: 4 additions & 1 deletion core-libs/setup/ssr/engine/ng-express-engine.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@
*/

import { StaticProvider } from '@angular/core';
import { CommonEngineOptions, CommonEngineRenderOptions } from '@angular/ssr';
import {
CommonEngineOptions,
CommonEngineRenderOptions,
} from '@angular/ssr/node';
import { Request, Response } from 'express';
import { REQUEST, RESPONSE } from '../tokens/express.tokens';
import { CxCommonEngine } from './cx-common-engine';
Expand Down
5 changes: 4 additions & 1 deletion core-libs/setup/ssr/optimized-engine/rendering-cache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,10 @@ export class RenderingCache {
if (this.options?.cacheSize) {
this.renders.delete(key);
if (this.renders.size >= this.options.cacheSize) {
this.renders.delete(this.renders.keys().next().value);
const oldestKey = this.renders.keys().next().value;
if (oldestKey !== undefined) {
this.renders.delete(oldestKey);
}
}
}
// cache only if shouldCacheRenderingResult return true
Expand Down
38 changes: 0 additions & 38 deletions docs/migration/2211_ng18/migration.md

This file was deleted.

53 changes: 53 additions & 0 deletions docs/migration/2211_ng19/migration.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# (EARLY NOTES) Migrating a custom app to use Spartacus with Angular v18

Before upgrading Spartacus to the new version with Angular 18, you need to first:
- upgrade to the latest 2211.x of Spartacus
Copy link
Contributor

Choose a reason for hiding this comment

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

[MINOR] (can be changed later, but before doc freeze)
I guess it should be:

Suggested change
- upgrade to the latest 2211.x of Spartacus
- upgrade Spartacus to version 2211.32.1 <or whatever latest version will be available _just before_ Feb release>

- upgrade Angular to version v18 and then to v19

## Update Angular to 18 and 19

### Update Angular to 18 and 3rd party deps to be compatible with Angular 18

Follow the [Angular guidelines for upgrading from v17 to v18](https://angular.dev/update-guide?v=17.0-18.0&l=3) and bump the Angular version locally, and update other 3rd party dependencies from Angular ecosystem to versions compatible with Angular 18 (e.g. `@ng-select/ng-select@13`, `@ngrx/store@18`, `ngx-infinite-scroll@18`):

```bash
ng update @angular/core@18 @angular/cli@18 @ng-select/ng-select@13 @ngrx/store@18 ngx-infinite-scroll@18 --force
git add .
git commit -m "update angular 18 and 3rd party deps angular 18 compatible"
```
Note: Do not select `use-application-builder` migration when migrating to Angular 18. Applications created before SPA 2211.19 doesn't support this builder. Applications created starting from 2211.19 already supports it.

### Update Angular to 19 and 3rd party deps to be compatible with Angular 19

Follow the [Angular guidelines for upgrading from v18 to v19](https://angular.dev/update-guide?v=18.0-19.0&l=3) and bump the Angular version locally, and update other 3rd party dependencies from Angular ecosystem to versions compatible with Angular 19 (e.g. `@ng-select/ng-select@14`, `@ngrx/store@19`, `ngx-infinite-scroll@19`):

```bash
ng update @angular/cli@19 @angular/core@19 ngx-infinite-scroll@19 @ng-select/ng-select@14 @ngrx/store@19 angular-oauth2-oidc@19 --force
git add .
git commit -m "update angular 19 and 3rd party deps angular 19 compatible"
```

Note: Unselect `use-application-builder` migration when migrating to Angular 19. Applications created before SPA 2211.19 doesn't support this builder. Applications created starting from 2211.19 already supports it.
Copy link
Contributor

@Platonn Platonn Jan 8, 2025

Choose a reason for hiding this comment

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

[MEDIUM]
This is said too late. People had already run the command.
Instead let's put a bold warning before running the command (in line 23). Also I'd mention that you need to hit a SPACE bar to unselect this option, and only then enter.

Because it's easy to miss the small prompt during the installation, perhaps we might even attach 2 screenshots:

  • how the default preselected option looks like
  • how the option unselected with a SPACE bar looks like


## Run Spartacus update

After successfully updating the application to Angular 19, execute this command to initiate the Spartacus update process.

```bash
ng update @spartacus/schematics@latest
```

### If using Server Side Rendering (SSR) and `application` builder

For applications using `application` builder having SSR support, you need to adjust the `server.ts` file to be compatible with the output generated by the builder.
Copy link
Contributor

@Platonn Platonn Jan 8, 2025

Choose a reason for hiding this comment

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

[MEDIUM]
The phrase "application builder" is a short term that we know, but many customers might not know. So let's be explicit what it means in practice - the value in angular.json. Feel free to choose a different wording than the suggested one below:

Suggested change
For applications using `application` builder having SSR support, you need to adjust the `server.ts` file to be compatible with the output generated by the builder.
For applications with SSR support that use the Angular's `application` builder (i.e. having in `angular.json` the following value: `... "architect": { "build": { "builder": "@angular-devkit/build-angular:application", ...`), you need to adjust the `server.ts` file to be compatible with the output generated by this builder.


```diff
/* ... */
- const indexHtml = path.join(browserDistFolder, 'index.html');
+ const indexHtml = path.join(serverDistFolder, 'index.server.html');
```





7 changes: 6 additions & 1 deletion feature-libs/asm/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
{
"extends": "../../.eslintrc.json",
"ignorePatterns": ["schematics/**/*.d.ts"]
"ignorePatterns": ["schematics/**/*.d.ts"],
"overrides": [
{
"files": ["*.ts"]
}
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import {

@Pipe({
name: 'cxTranslate',
standalone: false,
})
class MockTranslatePipe implements PipeTransform {
transform(): any {}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ export enum BIND_CART_DIALOG_ACTION {
@Component({
selector: 'cx-asm-bind-cart-dialog',
templateUrl: './asm-bind-cart-dialog.component.html',
standalone: false,
})
export class AsmBindCartDialogComponent {
BIND_CART_ACTION = BIND_CART_DIALOG_ACTION;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ import createSpy = jasmine.createSpy;
@Component({
selector: 'cx-icon',
template: '',
standalone: false,
})
class MockCxIconComponent {
@Input() type: ICON_TYPE;
Expand Down Expand Up @@ -85,6 +86,7 @@ class MockActiveCartService implements Partial<ActiveCartFacade> {

@Pipe({
name: 'cxTranslate',
standalone: false,
})
class MockTranslatePipe implements PipeTransform {
transform(): any {}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ import { AsmComponentService } from '../services/asm-component.service';
selector: 'cx-asm-bind-cart',
templateUrl: './asm-bind-cart.component.html',
changeDetection: ChangeDetectionStrategy.OnPush,
standalone: false,
})
export class AsmBindCartComponent implements OnInit, OnDestroy {
activeCartValidator: ValidatorFn = (control) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ const duplicatedUidErrorResponse: HttpErrorModel = {
@Component({
selector: 'cx-icon',
template: '',
standalone: false,
})
class MockCxIconComponent {
@Input() type: ICON_TYPE;
Expand All @@ -99,6 +100,7 @@ class MockAsmCreateCustomerFacade implements Partial<AsmCreateCustomerFacade> {

@Directive({
selector: '[cxFocus]',
standalone: false,
})
export class MockKeyboadFocusDirective {
@Input('cxFocus') config: FocusConfig = {};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import { CreatedCustomer } from './asm-create-customer-form.model';
@Component({
selector: 'cx-asm-create-customer-form',
templateUrl: './asm-create-customer-form.component.html',
standalone: false,
})
export class AsmCreateCustomerFormComponent {
createdCustomer: CreatedCustomer;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ class MockAuthService implements Partial<AuthService> {
@Component({
selector: 'cx-icon',
template: '',
standalone: false,
})
class MockCxIconComponent {
@Input() type: ICON_TYPE;
Expand Down Expand Up @@ -103,18 +104,21 @@ class MockLaunchDialogService implements Partial<LaunchDialogService> {
@Component({
selector: 'cx-asm-toggle-ui',
template: '',
standalone: false,
})
class MockAsmToggleUiComponent {}

@Component({
selector: 'cx-asm-session-timer',
template: '',
standalone: false,
})
class MockAsmSessionTimerComponent {}

@Component({
selector: 'cx-customer-selection',
template: '',
standalone: false,
})
class MockCustomerSelectionComponent {
@Output()
Expand All @@ -123,6 +127,7 @@ class MockCustomerSelectionComponent {
@Component({
selector: 'cx-csagent-login-form',
template: '',
standalone: false,
})
class MockCSAgentLoginFormComponent {
@Output()
Expand All @@ -133,6 +138,7 @@ class MockCSAgentLoginFormComponent {
@Component({
template: '',
selector: 'cx-customer-emulation',
standalone: false,
})
class MockCustomerEmulationComponent {}

Expand Down
Loading
Loading