Atualizando para a versão 18 do Angular

O Sterling Store Engagement foi atualizado para a versão 18 do Angular. Certifique-se de migrar suas extensões para a versão 18 do Angular.

Antes de iniciar

Observação: se você não puder migrar para a versão 18 do Angular, mas quiser modificar suas extensões na versão 15 do Angular, poderá continuar a criar suas personalizações com o kit de ferramentas de desenvolvedor 24.3.9.2-10.0.2409.2. Para obter os recursos, aprimoramentos e correções mais recentes, você deve atualizar para a versão 18 do Angular.
  • Você deve ter o espaço de trabalho do Angular versão 15 no site 24.3.9.2-10.0.2409.2 ou em qualquer kit de ferramentas de desenvolvedor do Angular versão 15.
  • Certifique-se de que você está usando a versão node.js 18.20.0.

Sobre esta tarefa

O processo de migração envolve três etapas. Primeiro, atualize da versão 15 para a 16 do Angular, segundo atualize da versão 16 para a 17 e terceiro atualize da versão 17 para a 18.
Observação: Certifique-se de executar todos os comandos da pasta <WORKSPACE>/store-frontend-src .

Procedimento

  1. Atualize o node-sass para a versão 8.0.0 nos arquivos packages/libs/styles/package.json e extensions/libs/styles/package.json e, em seguida, execute um dos seguintes comandos:
    yarn bootstrap
  2. Atualize o núcleo do Angular e a CLI para a versão 16 executando o seguinte comando:
    ng update @angular/core@16 @angular/cli@16 --allow-dirty --force
  3. Atualize o núcleo do Angular e a CLI para a versão 17 executando o seguinte comando:
    ng update @angular/core@17 @angular/cli@17 --allow-dirty --force
  4. Atualize o núcleo do Angular e a CLI para a versão 18 executando o seguinte comando:
    ng update @angular/core@18 @angular/cli@18 --allow-dirty --force
    Observação: ao executar esse comando, você encontrará uma migração opcional para usar o Application Builder use-application-builder, pressione Enter para continuar
  5. Pesquise e substitua o código existente pelo novo código em todos os métodos do construtor app.component.ts no diretório da extensão. Se não houver nenhuma ocorrência desse trecho de código, prossiga para a etapa 6.
    O código a seguir ilustra o código existente:
    this.router.events.subscribe((event: RouterEvent) => {
        this.routingStateService.navigationInterceptor(event);
    });
    O código a seguir ilustra o novo código:
    this.router.events.pipe(
        filter((event: Event | RouterEvent): event is RouterEvent => event instanceof RouterEvent)
    ).subscribe((event: RouterEvent) => {
        this.routingStateService.navigationInterceptor(event);
    });
    Em seguida, importe Event de @angular/router e filter de rxjs/operators.
    import { filter, take } from 'rxjs/operators';
    import { Router, RouterEvent, Event } from '@angular/router';
  6. Se você tiver o site extended packages/libs/common-components/src/lib/components/donut-chart/donut-chart.component.ts, pesquise e substitua o código existente pelo novo código no arquivo donut-chart.component.ts .
    O código a seguir ilustra o código existente:
    const pie = d3.pie().value((d) => d.count).sort(null);
    O código a seguir ilustra o novo código:
    const pie = d3.pie().value((d) => d?.['count']).sort(null);
  7. No arquivo angular.json , procure por browserTarget e substitua-o por buildTarget.
  8. No kit de ferramentas do desenvolvedor mais recente 25.1.3.0-10.0.2503.0, navegue até o diretório extensions/libs/styles e copie os arquivos package.json e webpack.config.js para sua pasta de extensão.
  9. Configure um novo espaço de trabalho a partir do kit de ferramentas de desenvolvedor mais recente 25.1.3.0-10.0.2503.0, concluindo as etapas a seguir.
    1. Copie o arquivo angular.json do espaço de trabalho anterior para o novo espaço de trabalho.
    2. Copie as extensões migradas do espaço de trabalho anterior para o novo espaço de trabalho.
    3. Execute novamente os seguintes comandos para testar as extensões:
      yarn bootstrap
      ln -s <store-temp>/store-cli/schematics/node_modules <store-temp>/store-cli/node_modules

      Certifique-se de usar o caminho absoluto ao executar o comando antes disso.

    4. Mescle as alterações recebidas do código fornecido pelo aplicativo com extensões para garantir que você esteja na versão mais recente do código e para evitar erros de compilação.
    5. Considere o próximo conjunto de etapas enquanto mescla suas alterações.
      1. Com a versão mais recente de RxJS, TypeScript exibe uma mensagem de erro se o argumento para o próximo método não for fornecido. Se você não quiser passar um argumento, declare o assunto com um tipo void . Como alternativa, se o assunto estiver emitindo valores de outra fonte e integrado por observadores, mas você não quiser enviar nenhum valor de uma fonte, passe null como argumento para o método next . O código a seguir ilustra o código existente:
        public addToCartSubject = new Subject<any>();
        this.refreshParentComponent.next();

        O código a seguir ilustra o novo código:

        public addToCartSubject = new Subject<void>();
        this.refreshParentComponent.next(null);
      2. ngbAccordion foi alterado de component para directive na versão 16.0.0 do ng-bootstrap. Siga o exemplo a seguir para garantir que todas as ocorrências de ngbAccordion nas extensões sejam atualizadas para directive.
        1. Altere o código do acordeão no arquivo component.html , conforme ilustrado no exemplo a seguir. O código a seguir ilustra o código antigo:
          <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>

          O código a seguir ilustra o novo código:

          <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. No arquivo component.ts , remova a importação de NgbAccordion e adicione NgbAccordionDirective de @ng-bootstrap/ng-bootstrap.
          import { NgbAccordionDirective } from '@ng-bootstrap/ng-bootstrap';
        3. No arquivo component.ts , altere a função isOpen conforme mostrado no exemplo de código a seguir.
          public isOpen(acc: NgbAccordion, panelId: string) {
              return (acc.activeIds.includes(panelId));
            }
          Alterar como segue:
          public isOpen(acc: NgbAccordionDirective, panelId: string) {
            return acc.isExpanded(panelId)
          }
        4. O evento PanelChange foi removido no ngbootsrap mais recente. Prossiga com as alterações mencionadas a seguir:
          1. Substitua panelChange por show no arquivo component.html , conforme mostrado no exemplo a seguir:
            (panelChange)="setSelectedLocation($event)"
            Substitua da seguinte forma:
            (show)="setSelectedLocation($event)"
          2. No arquivo component.ts , altere a função do manipulador de eventos panelChange , conforme mostrado no exemplo a seguir:
            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 = '';
                }
              }
            Mudar para
            public setSelectedLocation(panelId: string) {
                if (UIUtil.isNotVoid(panelId)) {
                    this.selectedLocationId = panelId;
                    this._setDefaultAttributeSet(this.selectedLocationId);
                } else {
                  this.selectedLocationId = '';
                }
              }
      3. Se você usar ngbDropdown no navbar do bootstrap, defina o atributo display como dynamic , conforme mostrado.
        <div ngbDropdown display="dynamic"></div>
  10. Inicie o aplicativo executando o seguinte comando:
    yarn start-app
    Observação: quando você executar o comando yarn start-app e encontrar o seguinte erro, exclua a pasta .angular do espaço de trabalho e execute o comando novamente.

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

    Observação: se você usar a instância dev ou qa cloud como um servidor remoto para fins de desenvolvimento, precisará fazer as alterações mencionadas em Configuração do servidor de desenvolvimento local.