angular創建本地庫

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>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章