自定义angular第三方库

42 阅读6分钟

angular库简介

Angular库是构建可重用代码的解决方案,我们可以将一些组件、指令、服务组合起来,构建成Angular库供任何Angular项目使用。并且可以直接打成npm包通过npm进行分发。\ Angular库不能直接运行,必须让其他Angular项目导入才能使用。

准备工作

首先使用cli创建一个Angular项目,这里指定createApplication="false"创建一个空的工作区。

ng new rdy-lib-workspace --createApplication="false"

进入工作区

cd rdy-lib-workspace

然后在工作区创建一个angular library。可以使用--prefix=<你的库的前缀>设置库中组件的前缀。

ng g library rdy-lib-ui --prefix="rdy"

为了方便展示lib中组件的效果,再创建一个application

ng g application rdy-demo-app --style="scss"

将库生成组件的样式文件从css替换成scss

ng config schematics.@schematics/angular:component.style scss

创建完成后项目结构如下,rdy-lib-ui就是我们的angular library,rdy-demo-app就是我们的angular应用。

使用cli创建angular库和应用后,有几个文件被更新,分别如下:

  • angular.json:添加新建立项目的基本信息,如build、test等选项
  • package.json:添加 ng-packagr 包的依赖
  • tsconfig.json:添加新建立项目的paths,用于编译后输出

其中angular.json的内容如下,projects中定义了工作区项目的配置,以及默认的项目。

{
  "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
  "cli": {
    "analytics": "9bacccd9-e640-40b8-9e98-6ef128a00107"
  },
  "version": 1,
  "newProjectRoot": "projects",
  "projects": {
    "rdy-lib-ui": {
      "projectType": "library",
      "root": "projects/rdy-lib-ui",
      "sourceRoot": "projects/rdy-lib-ui/src",
      "prefix": "rdy",
      "architect": {
        "build": {
          ...
        },
        "test": {
          ...
        }
      }
    },
    "rdy-demo-app": {
      "projectType": "application",
      "schematics": {
        "@schematics/angular:component": {
          "style": "scss"
        },
        "@schematics/angular:application": {
          "strict": true
        }
      },
      "root": "projects/rdy-demo-app",
      "sourceRoot": "projects/rdy-demo-app/src",
      "prefix": "app",
      "architect": {
        "build": {
          ...
        },
        "serve": {
          ...
        },
        "extract-i18n": {
          ...
        },
        "test": {
          ...
        }
      }
    }
  },
  "schematics": {
    "@schematics/angular:component": {
      "style": "scss"
    }
  },
  "defaultProject": "rdy-lib-ui"
}

我们最后修改angular.json中的默认项目为rdy-demo-app

"defaultProject": "rdy-demo-app"

angular库属于特殊的angular项目,可以使用cli去build、test它。angular库的build默认使用aot编译器,因此在构建时无需增加--prod参数。

angular库的结构

刚创建后,angular库的结构如下:

在库的根目录下,存在angular项目基础的配置文件,和普通angular项目不同的是多余了ng-package.json和README.MD文件,ng-package.json是ng-package包使用的文件,ng-packagr包将会将你的库转换为Angular Package Format。\ 其中entryFile是我们比较关注的属性,它是相对于angular库根目录下共API文件的创建路径,默认是src/public-api.ts。

{
  "$schema": "../../node_modules/ng-packagr/ng-package.schema.json",
  "dest": "../../dist/rdy-lib-ui",
  "lib": {
    "entryFile": "src/public-api.ts"
  }
}
<font style="color:rgb(51, 51, 51);">在angular库的</font><font style="color:rgb(199, 37, 78);background-color:rgb(249, 242, 244);">src</font><font style="color:rgb(51, 51, 51);">下存在两个配置文件和一个</font><font style="color:rgb(199, 37, 78);background-color:rgb(249, 242, 244);">lib</font><font style="color:rgb(51, 51, 51);">目录。</font><font style="color:rgb(199, 37, 78);background-color:rgb(249, 242, 244);">lib</font><font style="color:rgb(51, 51, 51);">中是cli默认生成的组件和服务。</font>

    * <font style="color:rgb(51, 51, 51);">test.ts:库的测试文件</font>
    * <font style="color:rgb(51, 51, 51);">public-api.ts:该angular库的公共api</font>

public-api.ts的内容如下,导出angular库中重用的组件和服务文件:

/*
 * Public API Surface of rdy-lib-ui
 */
export * from './lib/my-lib.service';
export * from './lib/my-lib.component';
export * from './lib/my-lib.module';

开发angular库

为angular库创建组件

使用cli创建angular库时默认生成一个组件,我们删除它,创建新的组件及其module。\ 这里创建了两个组件,并且将它们放到各自的module中,这样更方便管理。组件的内容自定义。

记得要在对应的module中导出组件:

// ui-input.module.ts
@NgModule({
  declarations: [
    UiInputComponent
  ],
  imports: [
    CommonModule
  ],
  exports: [
    UiInputComponent
  ]
})
export class UiInputModule { }

// ui-rate.module.ts
@NgModule({
  declarations: [
    UiRateComponent
  ],
  imports: [
    CommonModule
  ],
  exports: [
    UiRateComponent
  ]
})
export class UiRateModule { }

然后还需要在public-api.ts中导出组件文件:

// public-api.ts文件
export * from './ui-input/ui-input.component';
export * from  './ui-input/ui-input.module';

export * from './ui-rate/ui-rate.component';
export * from './ui-rate/ui-rate.module';

注意:****这两个导出是不同的,都要进行。一个是Angular模块的导出,一个是ts模块的导出。

为了方便,我们再创建一个总模块,导出库中所有组件。

内容如下:

import { NgModule } from '@angular/core';
import {UiInputModule} from "./ui-input/ui-input.module";
import {UiRateModule} from "./ui-rate/ui-rate.module";

const MODULES = [
  UiInputModule,
  UiRateModule
];

@NgModule({
  declarations: [],
  imports: [
    MODULES
  ],
  exports: [
    MODULES
  ]
})
export class RdyLibUiModule { }

在public-api.ts中导出总模块:

注意:总模块导出的,也要在public-api.ts文件中分别导出,否则构建时会报错。


理解package.json文件

package.json是管理项目依赖的文件。在上面,我们创建了一个空的工作区,然后创建另一个angular库,一个angular应用,现在项目中存在两个package.json文件。

  1. 根package.json文件

这是工作区的依赖文件,运行或构建应用程序或项目所需的任何软件包都必须在此处声明。\ 当时用ng add <包名>或者npm命令时,添加的包依赖都会添加到根下的package.json。

  1. 库package.json文件

这是angular库的依赖文件,告诉ng-packager什么样的包需要被打包。其内容如下:

{
  "name": "rdy-lib-ui",
  "version": "0.0.1",
  "peerDependencies": {
    "@angular/common": "^13.3.0",
    "@angular/core": "^13.3.0"
  },
  "dependencies": {
    "tslib": "^2.3.0"
  }
}
<font style="color:rgb(199, 37, 78);background-color:rgb(249, 242, 244);">name</font><font style="color:rgb(51, 51, 51);">就是库名,</font><font style="color:rgb(199, 37, 78);background-color:rgb(249, 242, 244);">version</font><font style="color:rgb(51, 51, 51);">是库版本,库版本的命名参考</font>[https://semver.org/](https://semver.org/)<font style="color:rgb(51, 51, 51);">。</font><font style="color:rgb(199, 37, 78);background-color:rgb(249, 242, 244);">peerDependencies</font><font style="color:rgb(51, 51, 51);">是库依赖的包。</font>

注意:当您使用npm install时,这些软件包只会添加到根package.json中,而不会添加到库项目中的该软件包中。因此,每当您安装库使用的新软件包时,都需要在此处手动添加它

也就是说,当库依赖其他库时,还需要手动更新当前库的package.json文件。

第三方库基于dev组件库进行二次封装

  1. 在应用中按照Angular接入dev组件库配置教程文档进行正常配置
  2. 将以下内容配置到库的package.json文件中
"peerDependencies": {
    "devextreme": "^21.1.4",
    "devextreme-angular": "^21.1.4",
    "devextreme-aspnet-data-nojquery": "^2.8.4"
}
  1. 在库中正常引入dev使用,进行二次封装等。

使用angular库

在当前工作区使用

在使用前,需要先build自定义库,使用ng build rdy-lib-ui即可。

构建完成有相关提示信息,并且会在工作区下生成一个dist文件夹,里面包含相关打包好的库代码。

angular库的使用和任意angular库一样,只需要导入对应的module即可,这里在rdy-demo-app的根模块导入自定义的库。

app.module.ts

发布angular库到公司服务器上

将目录切换到dist/rdy-lib-ui

发布包到服务器上

npm publish -registry 服务器地址

下载相关包

切换源

npm config set registry 服务器地址

下载包

npm i rdy-lib-ui --force

使用的话,按正常的第三方正常引入即可。