web-dev-qa-db-fra.com

Comment intégrer une Angular Application dans un Monorepo avec Bazel?

J'ai passé les dernières semaines à créer un monorepo TypeScript, qui peut être construit et déployé sur Kubernetes à l'aide de Bazel. Mais la dernière pièce du puzzle est l'intégration d'une Angular application dans tout le flux de travail, ce que je suis vraiment se bagarrant avec.

Le projet

 ├── WORKSPACE
 ├── BUILD.bazel
 ├── package.json
 ├── packages
 │   ├── package1
 │   ├── package2
 │   └── package3
 └── services
     ├── service1
     ├── service2
     ├── service3
+    └── angular-app
  • WORKSPACE fichier à la racine
  • BUILD.bazel fichier à la racine
  • seulement un package.json à la racine
  • tous les packages/services sont des bibliothèques TypeScript
  • les services dépendent des packages
  • chaque package/service a son propre BUILD.bazel fichier

Code source

Objectif

En fin de compte, je veux pouvoir ajouter un k8s_object pour l'application Angular app à la racine BUILD.bazel fichier comme celui-ci:

 load("@io_bazel_rules_k8s//k8s:objects.bzl", "k8s_objects")
 k8s_objects(
     name = "kubernetes_deployment",
     objects = [
         "//services/service1",
         "//services/service2",
         "//services/service3",
+        "//services/angular-app"
     ]
)

et il devrait déployer l'application Angular app sur Kubernetes lorsque j'exécute bazel run :kubernets_deployment.apply. Tout comme les autres services qui fonctionnent déjà parfaitement. Le processus de déploiement implique:

  • création de lots de code source
  • création d'une image Docker
  • pousser l'image Docker dans un registre
  • application des modifications au cluster Kubernetes

Défis

  1. Ajouter Angular dépendances Bazel à mon fichier WORKSPACE existant
  2. Rendre possible d'importer mes packages locaux dans mon Angular code source via import { something } from '@project/package1';
  3. Toutes les dépendances NPM doivent être ajoutées à la racine package.json au lieu de celui du projet Angular
  4. Intégration NgRx (mon Angular app utilise NgRx pour la gestion de l'état)
  5. Integrate Angular Universal (pour le rendu côté serveur)
  6. Intégrer Angular PWA (application Web progressive)
  7. Configurer un serveur de développement local

Ce que j'ai essayé

rules_nodejs Angular Exemple

J'ai été surpris de trouver un exemple fonctionnel de quelque chose qui ressemble à mon projet: https://github.com/bazelbuild/rules_nodejs/tree/master/examples/angular . Mais il s'est avéré que la structure de leur monorepo est quelque peu différente. Ils utilisent également scss, ce que je ne suis pas et il n'y a pas d'intégrations pour NgRx ou Angular Universal. J'ai donc essayé de l'utiliser un modèle par je ne pouvais tout simplement pas fais-le fonctionner.

Bazel avec Angular CLI

Bien sûr, j'ai également essayé la manière documentée d'ajouter Bazel à Angular: https://angular.io/guide/bazel , qui semble fonctionner pour un projet propre. Avec ng build --leaveBazelFilesOnDisk il est possible d'accéder aux fichiers Bazel par événement. Mais j'ai eu des erreurs me disant que NgRx et mes paquets locaux ne pouvaient pas être trouvés.


Mettre à jour

J'ai parcouru les premières étapes pour tout configurer sur un projet angular): https://github.com/flolu/cents-ideas/tree/4d444240cbbe2f8b015c4b7c85746c473bc6842b/services/client Mais j'obtiens une erreur que je ne parviens pas à résoudre:

ERROR: /home/flolu/Desktop/cents-ideas/services/client/src/app/BUILD.bazel:5:1: Compiling Angular templates (Ivy - prodmode) //src/app:app failed (Exit 1)
external/npm/node_modules/@angular/router/router.d.ts:2421:22 - error NG6002: Appears in the NgModule.imports of AppRoutingModule, but could not be resolved to an NgModule class.

This likely means that the library (@angular/router) which declares RouterModule has not been processed correctly by ngcc, or is not compatible with Angular Ivy. Check if a newer version of the library is available, and update if so. Also consider checking with the library's authors to see if the library is expected to be compatible with Ivy.

2421 export declare class RouterModule {
                          ~~~~~~~~~~~~
external/npm/node_modules/@angular/router/router.d.ts:2421:22 - error NG6003: Appears in the NgModule.exports of AppRoutingModule, but could not be resolved to an NgModule, Component, Directive, or Pipe class.

This likely means that the library (@angular/router) which declares RouterModule has not been processed correctly by ngcc, or is not compatible with Angular Ivy. Check if a newer version of the library is available, and update if so. Also consider checking with the library's authors to see if the library is expected to be compatible with Ivy.

2421 export declare class RouterModule {
                          ~~~~~~~~~~~~
external/npm/node_modules/@angular/platform-browser/platform-browser.d.ts:44:22 - error NG6002: Appears in the NgModule.imports of AppModule, but could not be resolved to an NgModule class.

This likely means that the library (@angular/platform-browser) which declares BrowserModule has not been processed correctly by ngcc, or is not compatible with Angular Ivy. Check if a newer version of the library is available, and update if so. Also consider checking with the library's authors to see if the library is expected to be compatible with Ivy.

44 export declare class BrowserModule {
                        ~~~~~~~~~~~~~
src/app/app-routing.module.ts:11:14 - error NG6002: Appears in the NgModule.imports of AppModule, but itself has errors

11 export class AppRoutingModule { }
6
Florian

Florian, de grands progrès jusqu'à présent :)

Je suggère de regarder de près les fichiers liés à bazel dans cet exemple angular) et de copier toutes les règles/fonctions nécessaires dans votre projet. Les fichiers sont .bazelrc, WORKSPACE, BUILD.bazel (dans chaque sous-dossier), rules_docker.patch (il est appliqué sur http_archive dans WORKSPACE).

En outre, plusieurs fichiers très importants dans /src dossier (ils sont utilisés dans le fichier BUILD): rollup.config.js, rxjs_shims.js, main.dev.ts, main.prod.ts. Et il y a deux index.html fichiers dans le dossier example: un pour prod et un pour dev.

Btw, cet exemple contient déjà ngrx, il peut donc vous convenir, regardez de près ng_module règles dans les fichiers BUILD et leurs déps. Ajoutez simplement vos adresses ici (smth comme @npm//@ngrx/store, etc).

Quant à Angular Universal, il semble qu'il ne soit pas bien pris en charge par Bazel maintenant. Voici le problème à suivre: https://github.com/bazelbuild/rules_nodejs/issues/1126

Et comme pour scss, c'est cool si vous utilisez un css simple, alors vous pouvez simplement l'insérer dans le champ assets de ng_module et vous n'avez pas besoin d'ajouter des étapes de compilation supplémentaires à partir de rules_sass (sass_binary, sass_library). Ignorez-les simplement lorsque vous copiez les règles de l'exemple.

Sur la structure du projet, voici mon exemple de migration de Nx vers Bazel: https://github.com/scalio/nx-bazel-starter . C'est un peu obsolète, donc mieux vaut s'orienter sur l'officiel. Mais vous pouvez y trouver des fonctionnalités utiles, à savoir comment les dossiers sont structurés dans le Nx. En fait, l'idée est très similaire à la vôtre: ils appellent simplement les services en tant qu'applications, les packages en tant que bibliothèques et partagent des package.json.

2
Ray