angular创建本地库

3 篇文章 0 订阅
1 篇文章 0 订阅

Angular7 Library库的使用

创建 Angular 工作区

使用 –createApplication
这个 --createApplication 选项与 ng new 结合一起使用,设置它为 false 时,它会告诉 ng new 命令不要在工作区内创建初始化的 Angular 应用。

为了创建一个不包含初始化应用的 Angular 工作区,我们使用下面方法:

ng new module-library --createApplication=false

当你被询问 router 选择时,选择默认 No 即可,css 选择 less。

使用这个命令创建的 Angular 工作区,对比之前,工作区中的文件少了很多,尽管这个工作区显得很“空”,它仍然包含有一些重要的配置信息:

package.json 包含了所有 Angular 所需的所有常见依赖

angular.json 不包含 projects 配置项的 Angular 配置文件

README.md, tsconfig.json, tslint.json 以及 node_modules 文件都与以前保持一致。

你可能会注意到,这里没有 src 文件夹,之后 projects 文件夹将会在生成库项目或者测试应用项目时被添加。

自从我们设置 --createApplication 选项为 false 后,我们的工程就不是一个初始化的应用。因此,如果你试着去运行一些命令,例如:ng build 或者 ng serve 时,我们会看到下面错误:Could not determine a single project for the ‘build’ target

库项目
创建一个库模块
现在,我们有了 Angular 工作区,我们可以添加库项目到工作区之中。

cd module-library
ng generate library module-library --prefix=ma

这个命令添加了一个 projects 目录,并包含有一个 module-library 子目录,它就是我们新生成的 module-library Angular 库。

注意到我们在命令中使用了 --prefix 标签,其目的是让库组件变得更加有辨识度(注:就像 ng-zorro 所做的 nz-xxx 一样)。如果我们不对其进行配置,Angular CLI 将使用 lib 作为默认前缀标签。

注意!在创建 Library 时总是显示地使用 prefix 标签进行配置。

以下是对于生成 Library 指令行为结果的一个简单总结:

  • 在 angular.json 文件中为我们的库添加了一个新的 module-library 项目。

  • 将 ng-packagr 的依赖项添加到 package.json 文件中。

  • 在 tsconfig.json 文件中添加对 module-library 构建路径的引用

  • 在 projects/module-library 文件夹下创建库的初始源代码。

angular.json 文件中的 module-library 项目
查看 angular.json 文件会发现我们在 projects 对象下创建了一个名为 module-library 的新项目。

"projects": {
  "module-library": {
    "root": "projects/module-library",
    "sourceRoot": "projects/module-library/src",
    "projectType": "library",
    "prefix": "ma",
    "architect": {
      "build": {
        "builder": "@angular-devkit/build-ng-packagr:build",
        "options": {
          "tsConfig": "projects/module-library/tsconfig.lib.json",
          "project": "projects/module-library/ng-package.json"
        }
      },
      "test": {
        "builder": "@angular-devkit/build-angular:karma",
        "options": {
          "main": "projects/module-library/src/test.ts",
          "tsConfig": "projects/module-library/tsconfig.spec.json",
          "karmaConfig": "projects/module-library/karma.conf.js"
        }
      },
      "lint": {
        "builder": "@angular-devkit/build-angular:tslint",
        "options": {
          "tsConfig": [
            "projects/module-library/tsconfig.lib.json",
            "projects/module-library/tsconfig.spec.json"
          ],
          "exclude": [
            "**/node_modules/**"
          ]
        }
      }
    }
  }
},

这里需要注意一些关键元素:

  • root 其指向我们的库项目的根文件夹。

  • sourceRoot 其指向我们的库项目的源代码位置。

projectType 其特别指出了这是一个 library 项目,而不像是其他两个类型名称为 application 的应用项目。

prefix 这是将会用于我们的组件选择器的前缀标识符。记得我们在创建库时制定了 ma 作为指定前缀。你可能熟悉 app 的前缀,其标识出哪些组件属于主应用程序。

architect 此对象的内容用于指定 Angular CLI 如何处理项目的构建,测试和 lint。值得注意的是,构建部分中的构建器使用了 ng-packagr

package.json 文件中的 ng-packagr 依赖项
在生成 Library 时 Angular CLI 需要 ng-packagr 这个包,因此他将其添加到了工作区的 package.json 文件中 devDependencies 依赖中。

"ng-packagr": "^3.0.0-rc.2"

tsconfig.json 文件中的构建路径
当测试 module-library 时,我们希望能够像日常使用的方式那样引入他,而不是仅仅作为整个应用中的一组文件。通常,当我们使用第三方库时,我们使用 npm install 指令安装,并将其安装到我们的 node_modules 文件夹中。

即使在当前的情况下,module-library 不会安装到 node_modules 文件夹中,但是他会被构建到工作区的 dist 文件夹下的某个子文件夹中。Angular CLI 将这个文件夹添加到 tsconfig.json 文件中,这样 module-library 就可以像一个 Library 一样以常见的方式被测试应用所引用了。 下述是在 tsconfig.json 文件中添加的路径:

"paths": {
  "module-library": [
    "dist/module-library"
  ]
}

module-library 的源代码
库的 src 文件夹被包含在 projects/module-library 文件夹中。在库中,Angular CLI 创建了一个包含服务和组件的新模块。除此之外还包含了更多文件:

package.json

这是专门用于库的 package.json 文件,也是库作为 npm 包发布所使用的 package.json 文件。当用户通过 npm 安装库时,该文件用于指定其依赖项。

public_api.ts

该文件作为入口文件存在,他用于描述库中哪个部分是外部可见的。我们需要在我们的入口文件中添加要导出的类以告知 ng-packagr 这个类应该暴露给使用库的用户。

ng-package.json

这是 ng-packagr 的配置文件。在 CLI 和 ng-packagr 没有集成的时代我们需要尽可能地熟悉该文件的内容,但是现在,在拥有新版 Angular CLI 的情况下,我们只需要知道该文件是用于告知 ng-packagr 去哪找到入口文件以及去哪构建库的内容即可。

创建测试应用项目
最后,我们希望建立一个测试应用项目,能够调用我们建立的 Angular 库。我们使用这个项目来做库的测试或者文档等工作。

ng generate application module-library-tester

这条命令,在 project 文件夹下添加了 module-library-tester 目录。此外,Angular CLI 还添加了一个 module-library-tester-e2e 项目来用做 e2e 测试。

构建库
使用下面的命令来构建 module-library 库:

ng build module-library

向根目录下的 package.json 文件夹中添加一个 build_lib 脚本:

"scripts": {
  "build_lib": "ng build module-library"
},

现在我们可以通过 npm run build_lib 指令去构建库了。

该命令会将库构建于下述文件夹中:

module-library\dist\module-library

注意,从 v6.1 起,Angluar CLI 始终在生产模式下构建库,所以不需要额外指定 --prod 选项。

与构建库不同,构建一个应用,需要使用 --prod 选项:

ng build module-library-tester --prod

package.json 文件

在库构建完成后,当前工作区内已经有3个 package.json 文件:
  • 根目录下的 package.json 文件
    这个 package.json 是库工作区的主 package.json 文件。我们用该文件来列出主应用和库都需要的依赖项。运行和构建主应用和库所依赖的所有包都必须列举在该文件中。

当我们在开发过程中使用 npm install 指令时,新加入的包将会添加到该文件中。

  • 库项目中的 package.json 文件
    库项目中的 package.json 文件位于 projects\module-library 目录下,其用于告知 ng-packagr 将什么信息放入库项目的发布版 package.json 文件中。其 package.json 文件中有三个重要的部分需要注意:

1.名称
这里的名称是指库的名称。未来如果某位用户引入库中的模块,这个名称就是出现在 from 部分内的引号中的名称。举例来说大概就是:

import { MALibraryModule } from 'module-library';

2.版本号
版本号对于库而言格外重要,版本号能够帮助用户判断他们是否在使用库的最新版本。

3.依赖项
此项目中只包含用于运行库所必须的依赖项。因此,你将会看到 dependenciespeerDependencies,但是没有 devDependencies

同样应该在该 package.json 文件中添加那些常见的 npm 内容比如:License,作者,仓库地址等。

值得注意的是,当使用 npm install 指令时,新安装的包只会被添加到根目录下的 package.json 文件中而不是在库项目的 package.json 文件中。因此,当你安装一个库所需要的包时,你需要将包名称手动添加到库项目的 package.json 文件依赖项中。

4.库的发布版本 package.json 文件
当我们构建库时库的发布版本 package.json 文件 由 ng-packagr 生成于 dist\module-library 文件目录下。该 package.json 文件会随着我们的库一并发布。

使用我们的库的开发者将会使用 npm install 指令安装该文件中所涉及的那些依赖项。

因为发布版本的 package.json 文件由 ng-packagr 生成,故而我们不应直接对其进行修改。如果你希望对发布版本的 package.json 文件进行修改,需要更新 projects\module-library 目录下的 库项目的 package.json 文件。ng-packagr 以 库项目的 package.json 文件为基准去生成发布版本的package.json 文件。

记住!永远不要直接对发布版本的 package.json 文件作出修改

5.打包库
打包库是指将生成的发布文件进行打包以生成一个 tgz 文件用以手动分享或发布于 npm。

使用 npm pack 指令在根目录下的 package.json 文件中创建一个脚本,该脚本用于打包生成的库。

"scripts": {
  "npm_pack": "cd dist/module-library && npm pack"
},

现在我们只需要使用指令 npm run npm_pack 就可以完成对库的打包。这条命令用于将文件目录指向工作区的 dist 文件夹并执行 npm pack 指令,命令将会在同一目录下生成一个形如 module-library-0.0.1.tgz 的包文件。

创造一个新的脚本包含 build_libnpm_pack 两个脚本的内容。将下述内容加入到主目录下的 package.json 文件中的脚本对象中去:

"package": "npm run build_lib && npm run npm_pack"

现在看看主目录下的 package.json 文件,和构建打包相关的脚本如下:

"scripts": {
  "build_lib": "ng build module-library",
  "npm_pack": "cd dist/module-library && npm pack",
  "package": "npm run build_lib && npm run npm_pack"
},

注意,执行 package 脚本将会顺序执行 build_lib 脚本 和 npm_pack 脚本。

使用如下指令完成对你的库的构建和打包:

npm run package

package 脚本做了两件事:

dist/module-library 目录下构建了库。
在同一目录下使用 npm pack 指令将库打包为一个 npm 包,其形如:module-library-0.0.1.tgz
需要注意!即使生成的包是 tgz 文件,你也不能以 tgz 格式直接压缩 dist 目录作为包,必须使用 npm pack 创建 tgz 文件。

扩展库

以下是我们将要执行的步骤:

  • 在库中创造一个新的组件
  • 将新添加的组件加入到库模块的 exports 属性中
  • 将新添加的组件加入到入口文件中
  • 在执行完上述步骤后重新构建库

在应用中使用新的组件

  • 创建一个库组件
  • 当需要为库生成组件的时候我们需要使用 --project 标识来告诉 Angular CLI 在库项目中生成组件。现在我们在库里生成一个简单的组件并命名为 list:
ng generate component list --project=module-library
  • 现在我们的库拥有了一个新的组件,并且 Angular CLI 将其添加到了库模块文件projects\module-library\src\lib\module-library.module.ts 的 declarations 属性中。

  • 将组件从库的模块中导出
    将 ListComponent 添加到 module-library.module.ts 的 exports 数组中。而添加后的 MALibraryModule 文件应如下所示:

import { NgModule } from '@angular/core';
import { MALibraryComponent } from './module-library.component';
import { ListComponent } from './list/list.component';

@NgModule({
  imports: [
  ],
  declarations: [
    MALibraryComponent,
    ListComponent
  ],
  exports: [
    MALibraryComponent,
    ListComponent
  ]
})
export class MALibraryModule { }
  • 将组件添加到入口文件中
    在用于定义库 API 的入口文件 projects\module-library\src\public_api.ts 中,添加以下内容以告知 ng-packagr 这个组件类应该暴露给使用库的用户:
export * from './lib/list/list.component';
  • 现在 public_api.ts 入口文件应该像如下这样:
/*
 * Public API Surface of module-library
 */

export * from './lib/module-library.service';
export * from './lib/module-library.component';
export * from './lib/module-library.module';
export * from './lib/list/list.component';
  • 重新构建库
    在对库进行修改之后,我们需要重新构建库:
ng build module-library

迄今维持我们所有的操作都是纯手动的。事实上,Angular CLI 在 6.2 版本中增加了一个增量构建的功能。每当有文件发生了修改,Angular CLI 将会进行部分构建并抛出修改后的文件。使用这个新的观察功能你只需要执行如下指令:

ng build module-library --watch
  • 运行
    我们无法直接运行一个库项目,但可以运行创建的测试应用项目:
ng serve module-library-tester
  • 测试
    我们能够为创建的 Angular 库项目和测试应用项目运行单元测试。

库项目运行单元测试:

ng test module-library

测试应用项目运行单元测试:

ng test module-library-tester

在其他 Angular 应用中使用库

安装库

  • 希望在其他应用中使用库的内容。我们需要执行以下指令:
npm install ../module-library/dist/module-library/module-library-0.0.1.tgz
  • 引入库模块
    我们首先需要向 App module 中添加库的module和Http拦截器 。

为此我们需要在 src\app\app.module.ts 文件中作出两处修改:

引入 MALibraryModule 模块和 HttpInterceptorService

import { MALibraryModule, HttpInterceptorService } from 'module-library';

将 MALibraryModule 模块加入到 AppModule 的 imports 数组中,并用forRoot把environment引入库中,给库提供可配置的API地址。
现在 app.module.ts 应如下所示:

import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { HTTP_INTERCEPTORS } from '@angular/common/http';

import { AppComponent } from './app.component';
import { MALibraryModule, HttpInterceptorService } from 'module-library';
import { environment } from 'src/environments/environment';

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserModule,
    MALibraryModule.forRoot(environment)
  ],
  providers: [{
    provide: HTTP_INTERCEPTORS,
    useClass: HttpInterceptorService,
    multi: true
  }],
  bootstrap: [AppComponent]
})
export class AppModule { }

使用一个库中的组件
在应用中修改 AppComponent 组件的 html 模板文件并展示源自于库的 list 组件。修改后的 app.component.html 文件如下所示:

<div style="text-align:center">
  <h1>
    Welcome to {{ title }}!
  </h1>
  <ma-list></ma-list>
</div>
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值