新聞中心
創(chuàng)建庫
對于如何創(chuàng)建和發(fā)布新庫,以擴展 Angular 的功能,本頁面提供了一個概念性的總覽

成都創(chuàng)新互聯(lián)公司專注于中大型企業(yè)的成都網(wǎng)站建設、做網(wǎng)站和網(wǎng)站改版、網(wǎng)站營銷服務,追求商業(yè)策劃與數(shù)據(jù)分析、創(chuàng)意藝術(shù)與技術(shù)開發(fā)的融合,累計客戶上千家,服務滿意度達97%。幫助廣大客戶順利對接上互聯(lián)網(wǎng)浪潮,準確優(yōu)選出符合自己需要的互聯(lián)網(wǎng)運用,我們將一直專注成都品牌網(wǎng)站建設和互聯(lián)網(wǎng)程序開發(fā),在前進的路上,與客戶一起成長!
如果你發(fā)現(xiàn)自己要在多個應用中解決同樣的問題(或者要把你的解決方案分享給其它開發(fā)者),你就有了一個潛在的庫。簡單的例子就是一個用來把用戶帶到你公司網(wǎng)站上的按鈕,該按鈕會包含在你公司構(gòu)建的所有應用中。
快速上手
使用 Angular CLI,用以下命令在新的工作區(qū)中生成一個新庫的骨架:
ng new my-workspace --no-create-application
cd my-workspace
ng generate library my-lib
命名你的庫
如果你想稍后在公共包注冊表(比如 npm)中發(fā)布它,則在選擇庫名稱時應該非常小心。
避免使用以 ?
ng-? 為前綴的名稱,比如 ?
ng-library?。?
ng-? 前綴是 Angular 框架及其庫中使用的保留關鍵字。首選 ?
ngx-? 前綴作為用于表示該庫適合與 Angular 一起使用的約定。這也是注冊表的使用者區(qū)分不同 JavaScript 框架庫的優(yōu)秀指示器。
?ng generate? 命令會在你的工作區(qū)中創(chuàng)建 ?projects/my-lib? 文件夾,其中包含帶有一個組件和一個服務的 NgModule。
可以使用單一倉庫(monorepo)模式將同一個工作區(qū)用于多個項目。
當你生成一個新庫時,該工作區(qū)的配置文件 ?angular.json? 中也增加了一個 'library' 類型的項目。
"projects": {
…
"my-lib": {
"root": "projects/my-lib",
"sourceRoot": "projects/my-lib/src",
"projectType": "library",
"prefix": "lib",
"architect": {
"build": {
"builder": "@angular-devkit/build-angular:ng-packagr",
…
可以使用 CLI 命令來構(gòu)建、測試和 lint 這個項目:
ng build my-lib --configuration development
ng test my-lib
ng lint my-lib
注意,該項目配置的構(gòu)建器與應用類項目的默認構(gòu)建器不同。此構(gòu)建器可以確保庫永遠使用 AoT 編譯器構(gòu)建。
要讓庫代碼可以復用,你必須為它定義一個公共的 API。這個“用戶層”定義了庫中消費者的可用內(nèi)容。該庫的用戶應該可以通過單個的導入路徑來訪問公共功能(如 NgModules、服務提供者和工具函數(shù))。
庫的公共 API 是在庫文件夾下的 ?public-api.ts? 文件中維護的。當你的庫被導入應用時,從該文件導出的所有內(nèi)容都會公開。請使用 NgModule 來暴露這些服務和組件。
你的庫里應該提供一些文檔(通常是 README 文件)來指導別人安裝和維護。
把應用中的部分內(nèi)容重構(gòu)成一個庫
為了讓你的解決方案可供復用,你需要對它進行調(diào)整,以免它依賴應用特有的代碼。在將應用的功能遷移到庫中時,需要注意以下幾點。
- 組件和管道之類的可聲明對象應該設計成無狀態(tài)的,這意味著它們不依賴或修改外部變量。如果確實依賴于狀態(tài),就需要對每種情況進行評估,以決定它是應用的狀態(tài)還是庫要管理的狀態(tài)。
- 組件內(nèi)部訂閱的所有可觀察對象都應該在這些組件的生命周期內(nèi)進行清理和釋放
- 組件對外暴露交互方式時,應該通過輸入?yún)?shù)來提供上下文,通過輸出參數(shù)來將事件傳給其它組件
- 檢查所有內(nèi)部依賴。
- 對于在組件或服務中使用的自定義類或接口,檢查它們是否依賴于其它類或接口,它們也需要一起遷移
- 同樣,如果你的庫代碼依賴于某個服務,則需要遷移該服務
- 如果你的庫代碼或其模板依賴于其它庫(比如 Angular Material),你就必須把它們配置為該庫的依賴
- 考慮如何為客戶端應用提供服務。
- 服務應該自己聲明提供者(而不是在 NgModule 或組件中聲明提供者),以便它們是可搖樹優(yōu)化的。這樣,如果服務器從未被注入到導入該庫的應用中,編譯器就會把該服務從該 bundle 中刪除。
- 如果你在多個 NgModules 注冊全局服務提供者或提供者共享,使用?
forRoot()? 和 ?forChild()? 設計模式提供?RouterModule? - 如果你的庫中提供的可選服務可能并沒有被所有的客戶端應用所使用,那么就可以通過輕量級令牌設計模式為這種情況支持正確的樹狀結(jié)構(gòu)了
使用代碼生成原理圖與 CLI 集成
一個庫通常都包含可復用的代碼,用于定義組件,服務,以及你剛才導入到項目中的其他 Angular 工件(管道,指令等等)。庫被打包成一個 npm 包,用于發(fā)布和共享。這個包還可以包含一些原理圖,它提供直接在項目中生成或轉(zhuǎn)換代碼的指令,就像 CLI 用 ?ng generate component? 創(chuàng)建一個通用的新 ?component?。比如,用庫打包的原理圖可以為 Angular CLI 提供生成組件所需的信息,該組件用于配置和使用該庫中定義的特定特性或一組特性。這方面的一個例子是 Angular Material 的導航原理圖,它用來配置 CDK 的 BreakpointObserver 并把它與 Material 的 MatSideNav 和 MatToolbar 組件一起使用。
創(chuàng)建并包含以下幾種原理圖。
- 包含一個安裝原理圖,以便 ?
ng add? 可以把你的庫添加到項目中。 - 在庫中包含了生成原理圖,以便 ?
ng generate? 可以為項目中的已定義工件(組件,服務,測試等)提供支持。 - 包含一個更新的原理圖,以便 ?
ng update? 可以更新你的庫的依賴,并提供一些遷移來破壞新版本中的更改。
你的庫中所包含的內(nèi)容取決于你的任務。比如,你可以定義一個原理圖來創(chuàng)建一個預先填充了固定數(shù)據(jù)的下拉列表,以展示如何把它添加到一個應用中。如果你想要一個每次包含不同傳入值的下拉列表,那么你的庫可以定義一個原理圖來用指定的配置創(chuàng)建它。然后,開發(fā)人員可以使用 ?ng generate? 為自己的應用配置一個實例。
假設你要讀取配置文件,然后根據(jù)該配置生成表單。如果該表單需要庫的用戶進行額外的自定義,它可能最適合用作 schematic。但是,如果這些表單總是一樣的,開發(fā)人員不需要做太多自定義工作,那么你就可以創(chuàng)建一個動態(tài)的組件來獲取配置并生成表單。通常,自定義越復雜,schematic 方式就越有用。
發(fā)布你的庫
使用 Angular CLI 和 npm 包管理器來構(gòu)建你的庫并發(fā)布為 npm 包。
Angular CLI 使用一個名為 ?ng-packagr? 的工具從已編譯的代碼中創(chuàng)建可以發(fā)布到 npm 的軟件包。
你應該總是使用 ?production ?配置來構(gòu)建用于分發(fā)的庫。這樣可以確保所生成的輸出對 npm 使用了適當?shù)膬?yōu)化和正確的軟件包格式。
ng build my-lib
cd dist/my-lib
npm publish
管理庫中的資產(chǎn)(assets)
對于 Angular 庫,可分發(fā)文件中可包含一些額外的資產(chǎn),如主題文件、Sass mixins 或文檔(如變更日志)。欲知詳情,請參見在構(gòu)建時將資產(chǎn)復制到庫中和將資產(chǎn)嵌入到組件樣式中。
當包含額外的資產(chǎn)(如 Sass mixins 或預編譯的 CSS)時,你需要將這些手動添加到主入口點的 ?
package.json? 中的條件化 ?
"exports"? 部分。
?
ng-packagr? 會將手寫的 ?
"exports"? 與自動生成的 ?
"exports"? 合并,以便讓庫作者配置額外的導出子路徑或自定義條件。"exports": { ".": { "sass": "./_index.scss", }, "./theming": { "sass": "./_theming.scss" }, "./prebuilt-themes/indigo-pink.css": { "style": "./prebuilt-themes/indigo-pink.css" } }以上是 @angular/material 可分發(fā)文件的摘錄。
同級依賴
各種 Angular 庫應該把自己依賴的所有 ?@angular/*? 都列為同級依賴。這確保了當各個模塊請求 Angular 時,都會得到完全相同的模塊。如果某個庫在 ?dependencies ?列出 ?@angular/core? 而不是用 ?peerDependencies?,它可能會得到一個不同的 Angular 模塊,這會破壞你的應用。
在應用中使用你自己的庫
如果要在同一個工作空間中使用某個庫,你不必把它發(fā)布到 npm 包管理器,但你還是得先構(gòu)建它。
要想在應用中使用你自己的庫:
- 構(gòu)建該庫。在構(gòu)建之前,無法使用庫。
ng build my-lib
import { myExport } from 'my-lib';
構(gòu)建和重建你的庫
如果你沒有把庫發(fā)布為 npm 包,然后把它從 npm 安裝到你的應用中,那么構(gòu)建步驟就是必要的。比如,如果你克隆了 git 倉庫并運行了 ?npm install?,編輯器就會把 ?my-lib? 的導入顯示為缺失狀態(tài)(如果你還沒有構(gòu)建過該庫)。
當你在 Angular 應用中從某個庫導入一些東西時,Angular 就會尋找?guī)烀痛疟P上某個位置之間的映射關系。當你用 npm 包安裝該庫時,它就映射到 ?
node_modules?目錄下。當你自己構(gòu)建庫時,它就會在 ?
tsconfig?路徑中查找這個映射。
用 Angular CLI 生成庫時,會自動把它的路徑添加到 ?
tsconfig?文件中。Angular CLI 使用 ?
tsconfig?路徑告訴構(gòu)建系統(tǒng)在哪里尋找這個庫。
欲知詳情,參見 路徑映射概覽。
如果你發(fā)現(xiàn)庫中的更改沒有反映到應用中,那么你的應用很可能正在使用這個庫的舊版本。
每當你對它進行修改時,都可以重建你的庫,但這個額外的步驟需要時間。增量構(gòu)建功能可以改善庫的開發(fā)體驗。每當文件發(fā)生變化時,都會執(zhí)行局部構(gòu)建,并修補一些文件。
增量構(gòu)建可以作為開發(fā)環(huán)境中的后臺進程運行。要啟用這個特性,可以在構(gòu)建命令中加入 ?--watch? 標志:
ng build my-lib --watch
CLI 的 ?
build?命令為庫使用與應用不同的構(gòu)建器,并調(diào)用不同的構(gòu)建工具。
- 應用的構(gòu)建體系(?
@angular-devkit/build-angular?)基于 ?webpack?,并被包含在所有新的 Angular CLI 項目中。- 庫的構(gòu)建體系基于 ?
ng-packagr?。只有在使用 ?ng generate library my-lib? 添加庫時,它才會添加到依賴項中。這兩種構(gòu)建體系支持不同的東西,即使它們支持相同的東西,它們的執(zhí)行方式也不同。這意味著同一套 TypeScript 源碼在生成庫時生成的 JavaScript 代碼可能與生成應用時生成的 JavaScript 代碼也不同。
因此,依賴于庫的應用應該只使用指向
內(nèi)置庫的 TypeScript 路徑映射。TypeScript 的路徑映射
不應該指向庫的 ?
.ts? 源文件。
發(fā)布庫
發(fā)布庫時可以使用兩種分發(fā)格式:
|
分發(fā)格式 |
詳情 |
|---|---|
|
部分 Ivy(推薦) |
包含可移植代碼,從 v12 開始,使用任何版本的 Angular 構(gòu)建的 Ivy 應用都可以使用這些可移植代碼。 |
|
完全 Ivy |
包含專用的 Angular Ivy 指令,不能保證它們可在 Angular 的不同版本中使用。這種格式要求庫和應用使用完全相同的 Angular 版本構(gòu)建。這種格式對于直接從源代碼構(gòu)建所有庫和應用代碼的環(huán)境很有用。 |
對于發(fā)布到 npm 的庫,請使用 partial-Ivy 格式,因為它在 Angular 的各個補丁版本之間是穩(wěn)定的。
如果要發(fā)布到 npm,請避免使用完全 Ivy 的方式編譯庫,因為生成的 Ivy 指令不屬于 Angular 公共 API 的一部分,因此在補丁版本之間可能會有所不同。
確保庫版本兼容性
用于構(gòu)建應用的 Angular 版本應始終與用于構(gòu)建其任何依賴庫的 Angular 版本相同或更大。比如,如果你有一個使用 Angular 13 版的庫,則依賴于該庫的應用應該使用 Angular 13 版或更高版本。Angular 不支持為該應用使用早期版本。
如果打算將庫發(fā)布到 npm,請通過在 ?tsconfig.prod.json? 的 ?"compilationMode": "partial"? 來使用部分 Ivy 代碼進行編譯。這種部分格式在不同版本的 Angular 之間是穩(wěn)定的,因此可以安全地發(fā)布到 npm。這種格式的代碼在應用程序構(gòu)建期間會使用相同版本的 Angular 編譯器進行處理,以確保應用程序及其所有庫使用的是同一個版本的 Angular。
如果要發(fā)布到 npm,請避免使用完全 Ivy 代碼來編譯庫,因為生成的 Ivy 指令不屬于 Angular 公共 API 的一部分,因此在補丁版本之間可能會有所不同。
如果你以前從未在 npm 中發(fā)布過軟件包,則必須創(chuàng)建一個用戶帳戶。在發(fā)布 npm 程序包中了解更多信息。
在 Angular CLI 之外使用部分 Ivy 代碼
應用將 npm 中的許多 Angular 庫安裝到其 ?node_modules ?目錄中。但是,這些庫中的代碼不能與已編譯的應用直接捆綁在一起,因為它尚未完全編譯。要完成編譯,可以使用 Angular 鏈接器。
對于不使用 Angular CLI 的應用程序,此鏈接器可用作 Babel 插件。該插件要從 ?@angular/compiler-cli/linker/babel? 導入。
Angular 鏈接器的 Babel 插件支持構(gòu)建緩存,這意味著鏈接器只需一次處理庫,而與其他 npm 操作無關。
下面的例子借助 babel-loader 把此鏈接器注冊為 Babel 插件,從而將此插件集成到自定義 Webpack 構(gòu)建中。
import linkerPlugin from '@angular/compiler-cli/linker/babel';
export default {
// ...
module: {
rules: [
{
test: /\.m?js$/,
use: {
loader: 'babel-loader',
options: {
plugins: [linkerPlugin],
compact: false,
cacheDirectory: true,
}
}
}
]
}
// ...
}
Angular CLI 自動集成了鏈接器插件,因此,如果你這個庫的使用方也在使用 CLI,則他們可以從 npm 安裝 Ivy 原生庫,而無需任何其他配置。
網(wǎng)站題目:創(chuàng)新互聯(lián)Angular教程:Angular創(chuàng)建庫
標題來源:http://fisionsoft.com.cn/article/cdjhijh.html


咨詢
建站咨詢
