书格前端

pnpm在angular的monorepo项目中的应用


pnpm在angular的monorepo项目中的应用

背景

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

安装pnpm和angular-cli

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

$ nvm install v12.22.12
$ nvm use v12.22.12

然后全局安装pnpm

$ npm i -g pnpm

接着安装angular-cli

$ pnpm install -g @angular/cli

创建angular应用

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

$ 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

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

app-one -> lib-a -> lib-b

app-two -> lib-b

配置pnpm的workspace

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

packages:
  - 'projects/**'

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

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

安装依赖

$ pnpm install

angular工程中引用库组件

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

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

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    LibAModule,
  ],
  providers: [],
  bootstrap: [AppComponent]
})

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

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

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

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

@NgModule({
  declarations: [
    LibAComponent
  ],
  imports: [
    LibBModule,
  ],
  exports: [
    LibAComponent
  ]
})

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

@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

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    LibBModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})

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

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

运行

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

  "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即可看到两个应用中显示对应引用的组件内容

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

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

$ pnpm build

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

完整的代码参考github仓库

参考