pnpm在angular的monorepo项目中的应用

背景

在angular多应用和多库的monorepo项目工程中使用pnpm的尝试。

安装pnpm和angular-cli

要安装pnpm的v6.32.8版本,nodejs版本要大于12.17,因此要更新nodejs版本至12.17以上,我这里使用的nvm进行node版本管理

1
2
$ nvm install v12.22.12
$ nvm use v12.22.12

然后全局安装pnpm

1
$ npm i -g pnpm

接着安装angular-cli

1
$ pnpm install -g @angular/cli

创建angular应用

找到一个目录创建一个新的angular工程,我们要建的是多个应用的工程,因此要加上create-application参数;并且创建两个库和两个应用,具体样式和路由根据实际情况选择。

1
2
3
4
5
$ ng new pnpm-demo --create-application=false
$ ng g lib lib-a --skip-install=true
$ ng g lib lib-b --skip-install=true
$ ng g app app-one --skip-install=true
$ ng g app app-two --routing=true --skip-install=true --style=less

演示的应用和库依赖关系如下:

1
2
3
app-one -> lib-a -> lib-b

app-two -> lib-b

配置pnpm的workspace

pnpm的workspace就是monorepo的管理方式, 接下来在工程根目录下新增一个yaml配置文件pnpm-workspace.yaml,内容如下

1
2
packages:
- 'projects/**'

添加lib-blib-a的依赖中, 其中--workspace参数表示仅从workspace中安装依赖,--filter参数表示选择lib-a库作为应用范围

1
$ pnpm add --workspace lib-b --fitler "lib-a"

安装依赖

1
$ pnpm install

angular工程中引用库组件

app-one应用中引用lib-a模块和lib-a组件

projects/app-one/src/app/app.module.ts文件的imports中引入LibAModule

1
2
3
4
5
6
7
8
9
10
11
12
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
AppRoutingModule,
LibAModule,
],
providers: [],
bootstrap: [AppComponent]
})

projects/app-one/src/app/app.component.html文件中引入lib-lib-a组件

1
<lib-lib-a></lib-lib-a>

lib-a模块中引用lib-b组件

projects/lib-a/src/lib/lib-a.module.ts文件的imports中引入LibBModule

1
2
3
4
5
6
7
8
9
10
11
@NgModule({
declarations: [
LibAComponent
],
imports: [
LibBModule,
],
exports: [
LibAComponent
]
})

projects/lib-a/src/lib/lib-a.component.ts文件中引入lib-b组件

1
2
3
4
5
6
7
8
9
10
11
12
13
@Component({
selector: 'lib-lib-a',
template: `
<p>
lib-a works!
test
</p>

<lib-lib-b></lib-lib-b>
`,
styles: [
]
})

app-two引用中引用lib-b模块和lib-b组件

projects/app-two/src/app/app.module.ts文件的imports中引入LibBModule

1
2
3
4
5
6
7
8
9
10
11
12
@NgModule({
declarations: [
AppComponent
],
imports: [
BrowserModule,
AppRoutingModule,
LibBModule
],
providers: [],
bootstrap: [AppComponent]
})

projects/app-two/src/app/app.component.html文件中引入lib-b组件

1
<lib-lib-b></lib-lib-b>

运行

在运行前,要配置根目录下的package.json的运行脚本,添加内容如下

1
2
3
4
5
6
7
8
9
10
"scripts": {
"ng": "ng",
"start:app-one": "ng run app-one:serve",
"start:app-two": "ng run app-two:serve",
"build": "ng build lib-a && ng build lib-b && ng build app-one && ng build app-two",
"build:lib-a": "ng build lib-a",
"build:lib-b": "ng build lib-b",
"watch": "ng build --watch --configuration development",
"test": "ng test"
},

接下来,通过命令分别启动app-one和app-two, 在浏览器中访问localhost:4200即可看到两个应用中显示对应引用的组件内容

1
2
$ pnpm start:app-one
$ pnpm start:app-two

调试完成后,进入打包的过程, 运行以下命令针对工程中的两个应用和两个库进行打包

1
$ pnpm build

对于库如何发包,暂时没有研究,后续再更新。

完整的代码参考github仓库

参考

pnpm在angular的monorepo项目中的应用

https://blog.bookcell.org/angular-monorepo-project-by-pnpm/

作者

潘绳杰

发布于

2022-04-17

更新于

2025-01-19

许可协议

评论