升级到Angular版本18

Sterling Store Engagement 已升级到 Angular 18 版本。 请确保将您的扩展程序迁移到Angular版本18。

开始之前

注: 如果您无法迁移到 Angular 版本 18,但又想在 Angular 版本 15 中修改扩展,则可以继续使用 24.3.9.2-10.0.2409.2 开发人员工具包构建自定义扩展。 要获得最新的功能、增强和修复,您必须升级到 Angular 18 版本。
  • 您必须从 24.3.9.2-10.0.2409.2 或任何 Angular 版本 15 开发人员工具包中获得 Angular 版本 15 工作区。
  • 请确保您使用的是 node.js 版本 18.20.0

关于此任务

迁移过程包括三个步骤。 首先,从Angular版本15升级到16,然后从版本16升级到17,最后从版本17升级到18。
注意 :请确保从 <WORKSPACE>/store-frontend-src 文件夹运行所有命令。

过程

  1. packages/libs/styles/package.jsonextensions/libs/styles/package.json 文件中,将node-sass更新为版本 8.0.0 ,然后运行以下命令之一:
    yarn bootstrap
  2. 通过运行以下命令将Angular核心和CLI升级到版本16:
    ng update @angular/core@16 @angular/cli@16 --allow-dirty --force
  3. 通过运行以下命令将Angular核心和CLI升级到版本17:
    ng update @angular/core@17 @angular/cli@17 --allow-dirty --force
  4. 通过运行以下命令将Angular核心和CLI升级到版本18:
    ng update @angular/core@18 @angular/cli@18 --allow-dirty --force
    注意: 运行此命令时,您会遇到一个可选的迁移,以使用应用程序生成器 use-application-builder ,请按回车键继续
  5. 在扩展目录中的所有 app.component.ts 构造方法中搜索并用新代码替换现有代码。 如果没有出现该代码段,请继续执行步骤 6。
    以下代码展示了现有代码:
    this.router.events.subscribe((event: RouterEvent) => {
        this.routingStateService.navigationInterceptor(event);
    });
    以下代码展示了新代码:
    this.router.events.pipe(
        filter((event: Event | RouterEvent): event is RouterEvent => event instanceof RouterEvent)
    ).subscribe((event: RouterEvent) => {
        this.routingStateService.navigationInterceptor(event);
    });
    然后,从 @angular/router 导入 Event ,从 rxjs/operators 导入 filter
    import { filter, take } from 'rxjs/operators';
    import { Router, RouterEvent, Event } from '@angular/router';
  6. 如果您有 extended packages/libs/common-components/src/lib/components/donut-chart/donut-chart.component.ts ,请搜索并用 donut-chart.component.ts 文件中的新代码替换现有代码。
    以下代码展示了现有代码:
    const pie = d3.pie().value((d) => d.count).sort(null);
    以下代码展示了新代码:
    const pie = d3.pie().value((d) => d?.['count']).sort(null);
  7. angular.json 文件中,搜索 browserTarget 并将其替换为 buildTarget
  8. 在最新的开发者工具包 25.1.3.0-10.0.2503.0 中,浏览到 extensions/libs/styles 目录,然后将 package.jsonwebpack.config.js 文件复制到扩展文件夹。
  9. 完成以下步骤,从最新的开发者工具包 25.1.3.0-10.0.2503.0 中设置新的工作区。
    1. angular.json 文件从之前的工作区复制到新的工作区。
    2. 将已迁移的扩展从旧工作区复制到新工作区。
    3. 重新运行以下命令以测试扩展:
      yarn bootstrap
      ln -s <store-temp>/store-cli/schematics/node_modules <store-temp>/store-cli/node_modules

      在此之前运行命令时,请确保使用绝对路径。

    4. 将从应用程序提供的代码中接收的更改与扩展合并,以确保您使用的是最新版本的代码,并避免出现任何编译错误。
    5. 在合并更改时,请考虑下一组步骤。
      1. RxJS 的最新版本中,如果没有提供下一个方法的参数, TypeScript 会显示错误信息。 如果不想传递参数,请使用 void 类型声明主题。 另外,如果主体从另一个来源发送值并被观察者整合,但您不想从一个来源发送任何值,可将 null 作为参数传递给 next 方法。 以下代码展示了现有代码:
        public addToCartSubject = new Subject<any>();
        this.refreshParentComponent.next();

        以下代码展示了新代码:

        public addToCartSubject = new Subject<void>();
        this.refreshParentComponent.next(null);
      2. ngbAccordion 在 版本的 ng-bootstrap 中从 更改为。 16.0.0 component directive 按照后面的示例,确保扩展名中出现的所有 ngbAccordion 都升级到 directive
        1. 如以下示例所示,更改 component.html 文件中的手风琴代码。 以下代码说明了旧代码:
          <ngb-accordion #acc="ngbAccordion" activeIds="{{activeIds}}"
                                 [attr.tid]="componentId+'filterStatus'">
                                 <ngb-panel id="ngb-panel-assignto">
                                     <ng-template ngbPanelTitle>
                                         <span
                                             [ngClass]="{' app-icon-open-chevron_down_14': isOpen(acc, 'ngb-panel-assignto'), 'app-icon-collapsed-chevron_right_14': !isOpen(acc, 'ngb-panel-assignto') }"
                                             class="app-glyphicons"></span>
                                         <span translate> filterOptions.LABEL_FilterGroupDisplayValueAssignTo</span>
                                     </ng-template>
                                     <ng-template ngbPanelContent>
                                         <isf-combo-box [attr.tid]="componentId+'filterAssignTo'"
                                             [searchText]="selectedUserName" [items]="userList" [columnName]="'name'"
                                             [selectedValues]="[selectedUserName]"
                                             [placeholder]="'filterOptions.LABEL_SelectAssociate'"
                                             [isItemSelected]="selectedUserName" (applySelection)="onSelection($event)"
                                             [resetValue]="resetComboBox"></isf-combo-box>
                                     </ng-template>
                                 </ngb-panel>
                </ngb-accordion>

          以下代码展示了新代码:

          <div ngbAccordion #acc="ngbAccordion"
                                 [attr.tid]="componentId+'filterStatus'">
                                 <div ngbAccordionItem="ngb-panel-assignto" id="ngb-panel-assignto" [collapsed]="!activeIds.includes('ngb-panel-assignto')">
                                     <div ngbAccordionHeader>
                                         <button ngbAccordionButton>
                                             <span
                                             [ngClass]="{' app-icon-open-chevron_down_14': isOpen(acc, 'ngb-panel-assignto'), 'app-icon-collapsed-chevron_right_14': !isOpen(acc, 'ngb-panel-assignto') }"
                                             class="app-glyphicons"></span>
                                         <span translate> filterOptions.LABEL_FilterGroupDisplayValueAssignTo</span>
                                         </button>
                                     </div>
                                     <div ngbAccordionCollapse>
                                         <div ngbAccordionBody>
                                             <ng-template>
                                                 <isf-combo-box [attr.tid]="componentId+'filterAssignTo'"
                                                     [searchText]="selectedUserName" [items]="userList" [columnName]="'name'"
                                                     [selectedValues]="[selectedUserName]"
                                                     [placeholder]="'filterOptions.LABEL_SelectAssociate'"
                                                     [isItemSelected]="selectedUserName" (applySelection)="onSelection($event)"
                                                     [resetValue]="resetComboBox"></isf-combo-box>
                                             </ng-template>
                                         </div>
                                     </div>
                                 </div>
           </div>
        2. component.ts 文件中,删除导入的 NgbAccordion ,并从 @ng-bootstrap/ng-bootstrap 中添加 NgbAccordionDirective
          import { NgbAccordionDirective } from '@ng-bootstrap/ng-bootstrap';
        3. component.ts 文件中,修改 isOpen 函数,如下面的代码示例所示。
          public isOpen(acc: NgbAccordion, panelId: string) {
              return (acc.activeIds.includes(panelId));
            }
          更改如下:
          public isOpen(acc: NgbAccordionDirective, panelId: string) {
            return acc.isExpanded(panelId)
          }
        4. PanelChange 事件已在最新的 ngbootsrap 中删除。 进行以下提到的更改:
          1. 如下例所示,在 component.html 文件中将 panelChange 替换为 show
            (panelChange)="setSelectedLocation($event)"
            替换如下:
            (show)="setSelectedLocation($event)"
          2. component.ts 文件中,更改 panelChange 事件处理函数,如下例所示:
            public setSelectedLocation(event: NgbPanelChangeEvent) {
                if (UIUtil.isNotVoid(event.nextState)) {
                  if (UIUtil.isNotVoid(event.panelId)) {
                    this.selectedLocationId = event.panelId;
                    this._setDefaultAttributeSet(this.selectedLocationId);
                  }
                } else {
                  this.selectedLocationId = '';
                }
              }
            更改为
            public setSelectedLocation(panelId: string) {
                if (UIUtil.isNotVoid(panelId)) {
                    this.selectedLocationId = panelId;
                    this._setDefaultAttributeSet(this.selectedLocationId);
                } else {
                  this.selectedLocationId = '';
                }
              }
      3. 如果在引导程序的 navbar 中使用 ngbDropdown ,请将 display 属性设置为 dynamic ,如图所示。
        <div ngbDropdown display="dynamic"></div>
  10. 运行以下命令启动应用程序:
    yarn start-app
    注意: 运行 yarn start-app 命令时遇到以下错误,请从工作区删除 .angular 文件夹,然后重新运行该命令。

    Module not found: Error: node_modules/@angular-devkit/build-angular/node_modules/@babel/runtime/helpers/esm/asyncToGenerator.js'

    注意: 如果使用 devqa cloud 实例作为远程服务器进行开发,则需要进行配置本地开发服务器中提到的更改。