如何使用 Bazel 将 Angular 应用程序集成到 Monorepo 中?
How to Integrate an Angular Application into a Monorepo with Bazel?
过去几周我一直在构建一个 Typescript monorepo,它可以使用 Bazel 构建并部署到 Kubernetes。但最后一个难题是 将 Angular 应用程序 集成到整个工作流程中,这让我非常头疼。
项目
├── WORKSPACE
├── BUILD.bazel
├── package.json
├── packages
│ ├── package1
│ ├── package2
│ └── package3
└── services
├── service1
├── service2
├── service3
+ └── angular-app
WORKSPACE
根目录中的文件
BUILD.bazel
根目录中的文件
- 根中只有一个
package.json
- 所有 packages/services 都是 Typescript 库
- 服务依赖包
- 每个 package/service 都有自己的
BUILD.bazel
文件
目标
最后,我希望能够为 Angular 应用程序添加 k8s_object
到根 BUILD.bazel
文件,如下所示:
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"
]
)
它应该在我 运行 bazel run :kubernets_deployment.apply
时将 Angular 应用程序部署到 Kubernetes。就像其他已经完美运行的服务一样。部署过程涉及:
- 创建源代码包
- 正在创建 Docker 图像
- 将 Docker 映像推送到注册表
- 正在将更改应用于 Kubernetes 集群
挑战
- 将 Angular Bazel 依赖项添加到我现有的
WORKSPACE
文件
- 可以通过
import { something } from '@project/package1';
将我的本地 packages 导入我的 Angular 源代码
- 所有 NPM 依赖项都应添加到根
package.json
而不是 Angular 项目中的
- 集成 NgRx(我的 Angular 应用使用 NgRx 进行状态管理)
- 集成 Angular Universal(用于服务器端呈现)
- 集成 Angular PWA(渐进式网络应用程序)
- 设置本地开发服务器
我试过的
rules_nodejs Angular 例子
我很惊讶地发现了一个类似于我的项目的工作示例:https://github.com/bazelbuild/rules_nodejs/tree/master/examples/angular。但事实证明,他们的 monorepo 的结构有些不同。他们还使用 scss
,我不是,也没有集成 NgRx 或 Angular Universal。所以我试着用它作为模板,但我无法让它工作。
带有 Angular CLI 的 Bazel
当然,我也尝试了将 Bazel 添加到 Angular 的记录方式:https://angular.io/guide/bazel,这似乎适用于一个干净的项目。使用 ng build --leaveBazelFilesOnDisk
可以访问 Bazel 文件。但是我收到错误消息,告诉我找不到 NgRx 和我的本地包。
更新
我已经完成了在干净的 angular 项目上设置所有内容的第一步:https://github.com/flolu/cents-ideas/tree/4d444240cbbe2f8b015c4b7c85746c473bc6842b/services/client
但是我收到一个我无法解决的错误:
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 { }
Florian,到目前为止进步很大:)
我建议仔细查看该 angular 示例中与 bazel 相关的文件,并将所有需要的规则/函数复制到您的项目中。这些文件是 .bazelrc
、WORKSPACE
、BUILD.bazel
(在每个子文件夹中)、rules_docker.patch
(它应用于 WORKSPACE 中的 http_archive)。
此外,/src
文件夹中有几个非常重要的文件(它们在 BUILD 文件中使用):rollup.config.js
、rxjs_shims.js
、main.dev.ts
、main.prod.ts
. example
文件夹中有两个 index.html
文件:一个用于生产,一个用于开发。
顺便说一句,这个例子已经包含了 ngrx,所以它可能很适合你,只需仔细查看 BUILD 文件中的 ng_module
规则及其依赖项。只需在此处添加您的部门(如 @npm//@ngrx/store
等)。
至于Angular Universal,貌似现在Bazel支持的还不是很好。这是要跟踪的问题:https://github.com/bazelbuild/rules_nodejs/issues/1126
至于 scss,如果你使用简单的 css,那很好,然后你可以将它插入到 ng_module
的 assets
字段中,你不需要不需要从 rules_sass (sass_binary, sass_library) 添加额外的编译步骤。从示例中复制规则时忽略它们。
关于项目结构,这里是我从Nx迁移到Bazel的例子:https://github.com/scalio/nx-bazel-starter。
它有点过时,所以最好以官方为导向。但您可能会在那里找到一些有用的功能,即文件夹在 Nx 中的结构。其实这个想法和你的非常相似:他们只是将服务称为应用程序,将包称为库并共享公共 package.json
.
过去几周我一直在构建一个 Typescript monorepo,它可以使用 Bazel 构建并部署到 Kubernetes。但最后一个难题是 将 Angular 应用程序 集成到整个工作流程中,这让我非常头疼。
项目
├── WORKSPACE
├── BUILD.bazel
├── package.json
├── packages
│ ├── package1
│ ├── package2
│ └── package3
└── services
├── service1
├── service2
├── service3
+ └── angular-app
WORKSPACE
根目录中的文件BUILD.bazel
根目录中的文件- 根中只有一个
package.json
- 所有 packages/services 都是 Typescript 库
- 服务依赖包
- 每个 package/service 都有自己的
BUILD.bazel
文件
目标
最后,我希望能够为 Angular 应用程序添加 k8s_object
到根 BUILD.bazel
文件,如下所示:
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"
]
)
它应该在我 运行 bazel run :kubernets_deployment.apply
时将 Angular 应用程序部署到 Kubernetes。就像其他已经完美运行的服务一样。部署过程涉及:
- 创建源代码包
- 正在创建 Docker 图像
- 将 Docker 映像推送到注册表
- 正在将更改应用于 Kubernetes 集群
挑战
- 将 Angular Bazel 依赖项添加到我现有的
WORKSPACE
文件 - 可以通过
import { something } from '@project/package1';
将我的本地 packages 导入我的 Angular 源代码
- 所有 NPM 依赖项都应添加到根
package.json
而不是 Angular 项目中的 - 集成 NgRx(我的 Angular 应用使用 NgRx 进行状态管理)
- 集成 Angular Universal(用于服务器端呈现)
- 集成 Angular PWA(渐进式网络应用程序)
- 设置本地开发服务器
我试过的
rules_nodejs Angular 例子
我很惊讶地发现了一个类似于我的项目的工作示例:https://github.com/bazelbuild/rules_nodejs/tree/master/examples/angular。但事实证明,他们的 monorepo 的结构有些不同。他们还使用 scss
,我不是,也没有集成 NgRx 或 Angular Universal。所以我试着用它作为模板,但我无法让它工作。
带有 Angular CLI 的 Bazel
当然,我也尝试了将 Bazel 添加到 Angular 的记录方式:https://angular.io/guide/bazel,这似乎适用于一个干净的项目。使用 ng build --leaveBazelFilesOnDisk
可以访问 Bazel 文件。但是我收到错误消息,告诉我找不到 NgRx 和我的本地包。
更新
我已经完成了在干净的 angular 项目上设置所有内容的第一步:https://github.com/flolu/cents-ideas/tree/4d444240cbbe2f8b015c4b7c85746c473bc6842b/services/client 但是我收到一个我无法解决的错误:
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 { }
Florian,到目前为止进步很大:)
我建议仔细查看该 angular 示例中与 bazel 相关的文件,并将所有需要的规则/函数复制到您的项目中。这些文件是 .bazelrc
、WORKSPACE
、BUILD.bazel
(在每个子文件夹中)、rules_docker.patch
(它应用于 WORKSPACE 中的 http_archive)。
此外,/src
文件夹中有几个非常重要的文件(它们在 BUILD 文件中使用):rollup.config.js
、rxjs_shims.js
、main.dev.ts
、main.prod.ts
. example
文件夹中有两个 index.html
文件:一个用于生产,一个用于开发。
顺便说一句,这个例子已经包含了 ngrx,所以它可能很适合你,只需仔细查看 BUILD 文件中的 ng_module
规则及其依赖项。只需在此处添加您的部门(如 @npm//@ngrx/store
等)。
至于Angular Universal,貌似现在Bazel支持的还不是很好。这是要跟踪的问题:https://github.com/bazelbuild/rules_nodejs/issues/1126
至于 scss,如果你使用简单的 css,那很好,然后你可以将它插入到 ng_module
的 assets
字段中,你不需要不需要从 rules_sass (sass_binary, sass_library) 添加额外的编译步骤。从示例中复制规则时忽略它们。
关于项目结构,这里是我从Nx迁移到Bazel的例子:https://github.com/scalio/nx-bazel-starter。
它有点过时,所以最好以官方为导向。但您可能会在那里找到一些有用的功能,即文件夹在 Nx 中的结构。其实这个想法和你的非常相似:他们只是将服务称为应用程序,将包称为库并共享公共 package.json
.