首页 > 解决方案 > Angular 12.2 导致 Typescript 出现优化问题。所有类型都具有相同的名称并启用了优化

问题描述

创建了一个简单的示例程序来显示在更大的应用程序中出现的问题。在 angular.json 中启用 buildOptimizer 和 Optimization 时,类型名称变为相同的字符。

当按下按钮时,这个简单的应用程序会在主应用程序模板中注入一个动态组件。它为从基础组件派生的每个组件都有一个工厂。第三个工厂只存储最后一个使用的。

import {
  Component,
  ComponentFactory,
  ComponentFactoryResolver,
  OnInit,
  ViewChild,
  ViewContainerRef,
} from '@angular/core';
import { AbcComponent } from './abc.component';
import { BaseComponent } from './base.component';
import { XyzComponent } from './xyz.component';

@Component({
  selector: 'app-root',
  template: `<div>
      <ng-container #panelContainer></ng-container>
    </div>
    <div>
      <button (click)="switchComponents()">Switch</button>
    </div>`,
})
export class AppComponent {
  constructor(private componentFactoryResolver: ComponentFactoryResolver) {
    this.abcFactory =
      this.componentFactoryResolver.resolveComponentFactory(AbcComponent);
    this.xyzFactory =
      this.componentFactoryResolver.resolveComponentFactory(XyzComponent);
    this.currentFactory = this.xyzFactory;
  }

  abcFactory: ComponentFactory<AbcComponent>;
  xyzFactory: ComponentFactory<XyzComponent>;
  currentFactory: ComponentFactory<BaseComponent>;

  @ViewChild('panelContainer', { read: ViewContainerRef }) panelContainerRef:
    | ViewContainerRef
    | undefined;

  public switchComponents() {
    console.log(
      'this.currentFactory.componentType.name',
      this.currentFactory.componentType.name
    );
    if (this.currentFactory.componentType.name == AbcComponent.name) {
      this.currentFactory = this.xyzFactory;
    } else {
      this.currentFactory = this.abcFactory;
    }
    this.panelContainerRef?.detach();
    this.panelContainerRef?.createComponent(this.currentFactory);
  }
}

成分:

import { Component, OnInit } from '@angular/core';

@Component({
  selector: 'app-base',
  template: '',
})
export class BaseComponent implements OnInit {
  constructor() {}

  ngOnInit(): void {}
}
import { Component, OnInit } from '@angular/core';
import { BaseComponent } from './base.component';

@Component({
  selector: 'app-abc',
  template: '<p>abc works!</p>',
})
export class AbcComponent extends BaseComponent implements OnInit {
  constructor() {
    super();
  }

  ngOnInit(): void {}
}
import { Component, OnInit } from '@angular/core';
import { BaseComponent } from './base.component';

@Component({
  selector: 'app-xyz',
  template: '<p>xyz works!</p>',
})
export class XyzComponent extends BaseComponent implements OnInit {
  constructor() {
    super();
  }

  ngOnInit(): void {}
}

Angular.json 如果我禁用 buildOptimizer 或优化选项,一切正常。

{
  "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
  "cli": {
    "analytics": "d4d75b0f-c55f-4714-97d7-e08572c4c65f"
  },
  "version": 1,
  "newProjectRoot": "projects",
  "projects": {
    "esbuildTestApp": {
      "projectType": "application",
      "schematics": {
        "@schematics/angular:component": {
          "style": "scss"
        },
        "@schematics/angular:application": {
          "strict": true
        }
      },
      "root": "",
      "sourceRoot": "src",
      "prefix": "app",
      "architect": {
        "build": {
          "builder": "@angular-devkit/build-angular:browser",
          "options": {
            "outputPath": "dist/esbuildTestApp",
            "index": "src/index.html",
            "main": "src/main.ts",
            "polyfills": "src/polyfills.ts",
            "tsConfig": "tsconfig.app.json",
            "inlineStyleLanguage": "scss",
            "assets": ["src/favicon.ico", "src/assets"],
            "styles": ["src/styles.scss"],
            "scripts": []
          },
          "configurations": {
            "production": {
              "budgets": [
                {
                  "type": "initial",
                  "maximumWarning": "500kb",
                  "maximumError": "1mb"
                },
                {
                  "type": "anyComponentStyle",
                  "maximumWarning": "2kb",
                  "maximumError": "4kb"
                }
              ],
              "fileReplacements": [
                {
                  "replace": "src/environments/environment.ts",
                  "with": "src/environments/environment.prod.ts"
                }
              ],
              "outputHashing": "all"
            },
            "development": {
              "buildOptimizer": false,
              "optimization": true,
              "vendorChunk": true,
              "extractLicenses": false,
              "sourceMap": true,
              "namedChunks": true,
              "aot": true
            }
          },
          "defaultConfiguration": "production"
        },
        "serve": {
          "builder": "@angular-devkit/build-angular:dev-server",
          "configurations": {
            "production": {
              "browserTarget": "esbuildTestApp:build:production"
            },
            "development": {
              "browserTarget": "esbuildTestApp:build:development"
            }
          },
          "defaultConfiguration": "development"
        },
        "extract-i18n": {
          "builder": "@angular-devkit/build-angular:extract-i18n",
          "options": {
            "browserTarget": "esbuildTestApp:build"
          }
        },
        "test": {
          "builder": "@angular-devkit/build-angular:karma",
          "options": {
            "main": "src/test.ts",
            "polyfills": "src/polyfills.ts",
            "tsConfig": "tsconfig.spec.json",
            "karmaConfig": "karma.conf.js",
            "inlineStyleLanguage": "scss",
            "assets": ["src/favicon.ico", "src/assets"],
            "styles": ["src/styles.scss"],
            "scripts": []
          }
        }
      }
    }
  },
  "defaultProject": "esbuildTestApp"
}

在禁用优化之一的情况下进行调试

1

this.currentFactory.componentType.name s
app.component.ts:40 this.currentFactory.componentType.name o
app.component.ts:40 this.currentFactory.componentType.name s
app.component.ts:40 this.currentFactory.componentType.name o

如果启用两者,如下所示:

 "development": {
              "buildOptimizer": true,
              "optimization": true,
              "vendorChunk": true,
              "extractLicenses": false,
              "sourceMap": true,
              "namedChunks": true,
              "aot": true
            }

输出显示所有类的名称相同。所有优化: 2

app.component.ts:40 this.currentFactory.componentType.name e
app.component.ts:40 this.currentFactory.componentType.name e
app.component.ts:40 this.currentFactory.componentType.name e

标签: angulartypescriptesbuild

解决方案


推荐阅读