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文件。
- 根package.json文件
这是工作区的依赖文件,运行或构建应用程序或项目所需的任何软件包都必须在此处声明。\ 当时用ng add <包名>或者npm命令时,添加的包依赖都会添加到根下的package.json。
- 库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组件库进行二次封装
- 在应用中按照Angular接入dev组件库配置教程文档进行正常配置
- 将以下内容配置到库的package.json文件中
"peerDependencies": {
"devextreme": "^21.1.4",
"devextreme-angular": "^21.1.4",
"devextreme-aspnet-data-nojquery": "^2.8.4"
}
- 在库中正常引入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
使用的话,按正常的第三方正常引入即可。