Веб-компонент Angular, созданный с помощью Angular Elements, переопределяет корневой каталог приложения Angular Shell Project

В настоящее время я пробую Angular Elements для создания веб-компонентов. Я создал веб-компонент, который работает на html-странице:

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>Test</title>
</head>
<body>
<nav-bar title="Test"></nav-bar>
<script type="text/javascript"
        src="https://dev-week-web-components.s3.eu-central-1.amazonaws.com/nav-bar.js"></script>
</body>
</html>

Веб-компонент отображается правильно, и атрибут title установлен.

Как только я встраиваю веб-компонент в приложение Angular, корневой компонент приложения больше не работает. Корневой компонент приложения всегда пуст, даже если в нем есть содержимое! Если я удалю тег скрипта для загрузки моего веб-компонента, корневой компонент приложения проекта оболочки снова заработает.

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>NgElementsShell</title>
  <base href="/">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="icon" type="image/x-icon" href="favicon.ico">
  <script type="text/javascript"
          src="https://dev-week-web-components.s3.eu-central-1.amazonaws.com/nav-bar.js"></script>
</head>
<body>
<nav-bar></nav-bar> 
<app-root></app-root> <!-- Always empty! -->
</body>
</html>

Чтобы создать веб-компонент, я следовал этому руководству: https://medium.com/comsystoreply/angular-elements-569025b65c69 (только на немецком языке).

Веб-компонент, созданный с помощью Angular Elements, является компонентом приложения другого проекта Angular.

@NgModule({
  declarations: [AppComponent],
  imports: [
    BrowserModule,
    NgbModule,
  ],
  entryComponents: [AppComponent]
})
export class AppModule {
  constructor(private injector: Injector) {
  }

  ngDoBootstrap() {
    if (!customElements.get('nav-bar')) {
      const navBarElement = createCustomElement(AppComponent, {injector: this.injector});
      customElements.define('nav-bar', navBarElement);
    }
  }
}

Проект Angular для веб-компонента содержит только один компонент:

@Component({
  // tslint:disable-next-line:component-selector
  selector: 'nav-bar',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss'],
  encapsulation: ViewEncapsulation.ShadowDom
})
export class AppComponent implements OnInit {
  @Input() title = 'Web-Component';

  constructor() { }

  ngOnInit(): void {
  }
}

Файл nav-bar.js представляет собой объединенный файл main.js, polyfill.js, runtime.js и vendor.js из созданного приложения Angular. В обучающих программах используется файл scripts.js. У меня нет этого файла. Если я оставлю файл vendor.js, веб-компонент не будет работать.

Что я делаю неправильно?


person Christian Wunder    schedule 09.04.2021    source источник
comment
У меня аналогичная проблема, я думаю, это проблема с веб-пакетом, но я не уверен   -  person ACeleghin    schedule 09.04.2021
comment
Спасибо за совет! Использование Webpack 5 решает эту проблему! :)   -  person Christian Wunder    schedule 09.04.2021


Ответы (1)


Благодаря подсказке user14649759 я смог решить проблему! :)

Необходимо использовать Webpack 5. Для этого я внес следующие изменения:

npm install -g yarn@latest
yarn add webpack@latest
yarn add copy-webpack-plugin@latest

Добавьте в package.json:

  "resolutions": {
    "webpack": "^5.31.0"
  },

Скажите Angular использовать пряжу:

ng config cli.packageManager yarn

Использование пряжи необходимо, потому что пряжа использует спецификацию resolutions.

Источники:

https://www.angulararchitects.io/aktuelles/the-microfrontend-revolution-part-2-module-federation-with-angular/

https://github.com/jhipster/generator-jhipster/issues/13642

person Christian Wunder    schedule 09.04.2021