日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

为什么我们需要给 Angular library 创建多重入口 multiple entry point

發(fā)布時(shí)間:2023/12/19 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 为什么我们需要给 Angular library 创建多重入口 multiple entry point 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

原文:Creating Secondary Entry Points for your Angular Library

自從 Angular 庫(kù)功能(從 Angular 7 開始)發(fā)布以來,現(xiàn)在開發(fā) Angular 庫(kù)比以往任何時(shí)候都容易。 Angular 庫(kù)本身配備了一個(gè)名為 ng-packagr 的社區(qū)驅(qū)動(dòng)包,它幾乎是核心。 在本文中,我們將看看如何利用 ng-packagr 輔助入口點(diǎn)進(jìn)一步拆分我們的 Angular 庫(kù)!

Why do we need secondary entry points?

我們希望擁有輔助入口點(diǎn)的原因之一是使我們能夠拆分我們的依賴項(xiàng)。 讓我們看一個(gè)例子,其中一個(gè)模塊有 peerDependencies,而另一個(gè)沒有。

假設(shè)我們有如下的 library 文件夾結(jié)構(gòu):

library 名稱:my-awesome-lib
兩個(gè) module,awesome-plain 和 awesome-time

查看 awesome-plain Component 的實(shí)現(xiàn):

import { Component } from '@angular/core'; @Component({selector: 'awesome-plain',template: `<div>Hey I'm just a plain text with no dependencies!</div>` }) export class AwesomePlainComponent {}

以及 awesome-time Component 的實(shí)現(xiàn):

import { Component } from '@angular/core'; import * as moment_ from 'moment'; const moment = moment_; @Component({selector: 'awesome-time',template: `<div>Hey, Awesome Time:</div><div>{{ time }}</div>` }) export class AwesomeTimeComponent {time: string;constructor() {this.time = moment().format();} }

其中 plain Component 沒有任何依賴,而 time Component 依賴于 moment.

moment 依賴的定義在 library 的 package.json 里:

{"name": "my-awesome-lib","version": "0.0.1","peerDependencies": {"@angular/common": "^8.2.14","@angular/core": "^8.2.14","moment": "^2.26.0"} }

請(qǐng)注意,這些 peerDependencies 放在庫(kù) my-awesome-lib 的范圍內(nèi),而不是放在單個(gè)模塊(庫(kù)內(nèi)的文件)上。

最后,以下是在 my-awesome-lib/src/public-api.ts 下如何導(dǎo)出 awesome-plain 和 awesome-time:

export * from './awesome-plain/awesome-plain.component'; export * from './awesome-plain/awesome-plain.module'; export * from './awesome-time/awesome-time.component'; export * from './awesome-time/awesome-time.module';

The problem: Client needs to install ALL peer dependencies from the library

上面這樣設(shè)計(jì)的問題是什么?

假設(shè)我們有一個(gè) Angular 應(yīng)用程序想要使用 my-awesome-lib。 客戶端應(yīng)用程序(Angular 應(yīng)用程序)需要做的第一件事是安裝庫(kù):

npm i my-awesome-lib

安裝后,客戶端應(yīng)用程序然后繼續(xù)導(dǎo)入和使用,例如只有 awesome-plain 組件。 這是客戶端應(yīng)用程序中的代碼可能看起來很像:

// app.module.ts import { AwesomePlainModule } from 'my-awesome-lib'; @NgModule({...,imports: [...,AwesomePlainModule,],bootstrap: [AppComponent] }) export class AppModule {} // app.component.html <awesome-plain></awesome-plain>

然而,ng serve 命令行會(huì)導(dǎo)致如下錯(cuò)誤:

ERROR in ./node_modules/my-awesome-lib/fesm2015/my-awesome-lib.js Module not found: Error: Can’t resolve ‘moment’ in ‘/app-showcase-v8/node_modules/my-awesome-lib/fesm2015’

它說它找不到安裝在客戶端應(yīng)用程序中的時(shí)刻。 嗯,這就是發(fā)生的事情。 盡管客戶端應(yīng)用程序僅導(dǎo)入并使用 awesome-plain,但 Angular 編譯器仍會(huì)要求安裝 my-awesome-lib 中定義的所有 peerDependencies,這在本例中很重要。

如果客戶端應(yīng)用程序同時(shí)使用 awesome-plain 和 awesome-time,當(dāng)前情況可能會(huì)很好。 然而,想象一下,如果庫(kù)變大并且有不止 2 個(gè)模塊,假設(shè)有 10 個(gè)模塊。 讓我們?cè)倏浯笠稽c(diǎn); 如果 10 個(gè)模塊中有 5 個(gè)具有不同的 peerDependencies 會(huì)怎樣? 如果有一個(gè)客戶端應(yīng)用程序使用這個(gè)庫(kù)并且只使用 1 個(gè)沒有任何 peerDependencies 的模塊,那么客戶端應(yīng)用程序仍然需要安裝所有 5 個(gè) peerDependencies! 當(dāng)然,應(yīng)該有比這更好的方法,對(duì)吧?

Enter the secondary entry points!

幸運(yùn)的是,很有可能優(yōu)化當(dāng)前的方法。 到目前為止,庫(kù)中使用的方法僅使用稱為主要入口點(diǎn)的東西。 這由 package.json 文件表示,該文件僅存在于 my-awesome-lib/package.json 下,其中定義了整個(gè)庫(kù)的所有 peerDependencies。

通過二級(jí)入口點(diǎn),我們可以進(jìn)一步將 peerDependencies 拆分到庫(kù)級(jí)別之外; 它使得在庫(kù)內(nèi)的文件夾或模塊中定義 peerDependencies 變得可行。

例如,通過將 awesome-time 設(shè)置為二級(jí)入口點(diǎn),我們可以在子目錄中創(chuàng)建另一個(gè) package.json 文件,該文件包含僅適用于 awesome-time 模塊的 peerDependencies。

因此,我們不再在庫(kù)級(jí)別定義 peerDependencies; 我們改為在
子目錄中定義它們。

此外,輔助入口點(diǎn)使我們能夠像下面這樣導(dǎo)入庫(kù):

// Primary entry points import { AwesomePlainModule } from 'my-awesome-lib'; // Secondary entry points import { AwesomeTimeModule } from 'my-awesome-lib/awesome-time';

這樣,如果 Client App 只使用 AwesomePlainModule,編譯器就不會(huì)再要求安裝 moment 了!

Implement secondary entry points

希望上面的解釋能讓大家對(duì)我們?yōu)槭裁匆褂幂o助入口點(diǎn)有一個(gè)大致的了解。

好消息是,實(shí)現(xiàn)二級(jí)入口點(diǎn)相當(dāng)簡(jiǎn)單明了,因?yàn)?ng-packagr 將在幕后完成大部分工作!

我們將使用 my-awesome-lib 作為以下實(shí)施指南的上下文。 在這種情況下,我們將設(shè)置 awesome-time 作為次要入口點(diǎn),而 awesome-plain 將保持原樣(仍然是主要入口點(diǎn))。

(1) Place the folders for secondary entry points directly under the library folder.

根據(jù) ng-packagr 文檔,輔助入口點(diǎn)的文件夾布局示例之一是如下所示:

有趣的是,這是@angular/common 包中使用的類似文件夾布局,它以@angular/common 作為主要入口點(diǎn),而@angular/common/testing 作為次要入口點(diǎn)。

文件夾結(jié)構(gòu)如下:

(2) Create additional package.json and public-api.ts files in secondary entry points folder.

要?jiǎng)?chuàng)建輔助入口點(diǎn),我們需要告訴 ng-packagr 要查找哪個(gè)文件夾。 這可以通過在 /my-awesome-lib/awesome-time 文件夾下創(chuàng)建另一個(gè) package.json 和 public-api.ts 文件來實(shí)現(xiàn),除了主入口點(diǎn)的文件。 僅通過這樣做,ng-packagr 將動(dòng)態(tài)發(fā)現(xiàn)輔助入口點(diǎn)。
/my-awesome-lib/awesome-time/package.json 的內(nèi)容可以是:

{"ngPackage": {"lib": {"entryFile": "public-api.ts","umdModuleIds": {"moment": "moment"}}},"peerDependencies": {"moment": "^2.26.0"} }

請(qǐng)注意,到目前為止,我們將 moment 作為 peerDependencies 放置在這里。 此外,“umdModuleIds”用于在構(gòu)建庫(kù)時(shí)從 ng-packagr 中刪除警告。

以及 /my-awesome-lib/awesome-time/public-api.ts 的內(nèi)容如下:

/** Public API Surface of my-awesome-lib/awesome-time*/ export * from './awesome-time.component'; export * from './awesome-time.module';

(3) Remove secondary entry points peer dependencies from the main package.json and secondary entry point exported files from the main public-api.ts.

{"name": "my-awesome-lib","version": "0.0.1","peerDependencies": {"@angular/common": "^8.2.14","@angular/core": "^8.2.14"} }

moment 包已被刪除,因?yàn)樗言?/my-awesome-lib/awesome-time/package.json 中定義。

此外,我們將刪除在主 my-awesome-lib/src/public-api.ts 中導(dǎo)出的 awesome-time 文件。 該文件現(xiàn)在應(yīng)該只導(dǎo)出 awesome-plain 文件,如下所示:

/** Public API Surface of my-awesome-lib*/ export * from './awesome-plain/awesome-plain.component'; export * from './awesome-plain/awesome-plain.module';

(4) Build the library.

現(xiàn)在一切都已設(shè)置完畢,我們現(xiàn)在可以嘗試通過執(zhí)行命令 ng build my-awesome-lib 來構(gòu)建庫(kù)。 如果正確完成,您應(yīng)該在終端中看到以下內(nèi)容:

另外,如果打開庫(kù)構(gòu)建文件夾 dist/my-awesome-library,文件夾內(nèi)應(yīng)該還有一些名為 my-awesome-lib-awesome-time..js 的文件,例如 dist/fesm2015 和 dist/bundles . 如果將它與沒有輔助入口點(diǎn)的那個(gè)進(jìn)行比較,構(gòu)建文件夾通常只包含 my-awesome-lib..js,這是僅針對(duì)庫(kù)本身的構(gòu)建。

(5) Install and import the library in the Client App.

最后一步是最終在 Angular 應(yīng)用程序中使用它。 由于我們從主要入口點(diǎn)移動(dòng)了 awesome-time,因此導(dǎo)入路徑會(huì)略有變化。 要在客戶端應(yīng)用程序中使用新的庫(kù)文件夾結(jié)構(gòu),它應(yīng)該如下所示:

// Primary entry points import { AwesomePlainModule } from 'my-awesome-lib'; // Secondary entry points import { AwesomeTimeModule } from 'my-awesome-lib/awesome-time';

現(xiàn)在,如果客戶端應(yīng)用程序只使用 AwesomePlainModule,我們應(yīng)該可以在不安裝 moment 的情況下運(yùn)行應(yīng)用程序(僅在 AwesomeTimeModule 中使用)。

請(qǐng)記住,實(shí)施輔助入口點(diǎn)可能會(huì)導(dǎo)致您的 Angular 庫(kù)發(fā)生重大變化。 原因是因?yàn)槭褂媚膸?kù)的客戶端應(yīng)用程序必須更新導(dǎo)入路徑。 否則,他們的應(yīng)用程序?qū)⒅袛?#xff0c;因?yàn)楝F(xiàn)在不再?gòu)摹皔our-lib”導(dǎo)入輔助入口點(diǎn)文件。 因此,此更改不向后兼容。

Should there be any primary entry points at all? Is it okay to only have secondary entry points for the library?

您可能想知道,我們甚至應(yīng)該使用主要入口點(diǎn)嗎? 在我看來,只有次要入口點(diǎn)是可以的,主要是因?yàn)?#64;angular/material 只使用次要入口點(diǎn)。 另一方面,對(duì)于邏輯上相似的功能或特性,一般也建議使用主要入口點(diǎn)。 以下是在 Angular Package Format 文檔中編寫的:

Angular Package Format 的一般規(guī)則是為最小的邏輯連接代碼集生成 FESM 文件。 例如,Angular 包有一個(gè)用于@angular/core 的 FESM。 當(dāng)開發(fā)人員使用來自@angular/core 的 Component 符號(hào)時(shí),他們很可能也會(huì)直接或間接使用諸如 Injectable、Directive、NgModule 等符號(hào)。 因此,所有這些部分都應(yīng)該捆綁到一個(gè)單一的 FESM 中。 對(duì)于大多數(shù)庫(kù)情況,應(yīng)該將單個(gè)邏輯組組合到一個(gè) NgModule 中,并且所有這些文件應(yīng)該捆綁在一起作為包中的單個(gè) FESM 文件,代表 npm 包中的單個(gè)入口點(diǎn)。

此外,就我而言,經(jīng)驗(yàn)法則是將某些模塊作為輔助入口點(diǎn),如果它們具有不同的 peerDependencies。 這是為了防止客戶端應(yīng)用程序被迫手動(dòng)安裝所有依賴項(xiàng),盡管它們并未使用所有依賴項(xiàng)。

Conclusions

總而言之,次要入口點(diǎn)是一個(gè)巧妙的功能,它允許我們進(jìn)一步拆分 Angular 庫(kù),尤其是在處理 peerDependencies 時(shí)。 它也很容易實(shí)現(xiàn),因?yàn)?ng-packagr 將通過子目錄的 package.json 動(dòng)態(tài)發(fā)現(xiàn)輔助入口點(diǎn)。

好處之一是它會(huì)減少客戶端應(yīng)用程序被迫安裝所有依賴項(xiàng)的機(jī)會(huì),即使該應(yīng)用程序沒有導(dǎo)入/使用依賴于已安裝依賴項(xiàng)的任何庫(kù)函數(shù)。

更多Jerry的原創(chuàng)文章,盡在:“汪子熙”:

總結(jié)

以上是生活随笔為你收集整理的为什么我们需要给 Angular library 创建多重入口 multiple entry point的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。