Angular Package Format (APF) v12.0 介绍
官網(wǎng)
本文檔描述了 npm 上當(dāng)前可用的 Angular 框架包的結(jié)構(gòu)和格式。 這種格式適用于分發(fā) Angular 組件的包(如 Angular Material)以及在@angular 命名空間下發(fā)布的核心框架包,如@angular/core 和@angular/forms。
此處描述的格式使用獨(dú)特的文件布局和元數(shù)據(jù)配置,使包能夠在使用 Angular 的大多數(shù)常見(jiàn)場(chǎng)景下無(wú)縫工作,并使其與 Angular 團(tuán)隊(duì)和社區(qū)本身提供的工具兼容。 出于這個(gè)原因,也強(qiáng)烈鼓勵(lì)第三方庫(kù)開(kāi)發(fā)人員遵循相同的結(jié)構(gòu)。
格式的版本控制與 Angular 本身的版本控制一致,我們希望格式以向前兼容(forward-compatible)的方式發(fā)展,以支持 Angular 組件和工具生態(tài)系統(tǒng)的需求。
Package format 的目的
在當(dāng)今的 JavaScript 環(huán)境中,開(kāi)發(fā)人員將以多種不同的方式使用包。 例如,有些可能使用 SystemJS,有些可能使用 Webpack。 盡管如此,其他人可能會(huì)在 Node 或?yàn)g覽器中使用包作為 UMD 包或通過(guò)全局變量訪問(wèn)。
Angular 分發(fā)包支持所有常用的開(kāi)發(fā)工具和工作流,并強(qiáng)調(diào)優(yōu)化,從而縮小應(yīng)用程序有效負(fù)載大小或加快開(kāi)發(fā)迭代周期(構(gòu)建時(shí)間)。
Library File layout
庫(kù)一般應(yīng)該使用相同的布局,但庫(kù)中存在與 Angular 框架不同的特性。
通常,庫(kù)是在組件或功能級(jí)別拆分的。我們以 Angular 的 Material 項(xiàng)目為例。
Angular Material 發(fā)布了組件集,例如 Button(單個(gè)組件)、Tabs(一組協(xié)同工作的組件)等。共同點(diǎn)是將這些功能區(qū)域綁定在一起的 NgModule。 Button 有一個(gè) NgModule,Tabs 有另一個(gè),依此類推。
Angular Package Format 的一般規(guī)則是為最小的邏輯連接代碼集生成 FESM 文件。例如,Angular 包有一個(gè)用于@angular/core 的 FESM。當(dāng)開(kāi)發(fā)人員使用來(lái)自@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)。
以下是 Angular Material 項(xiàng)目在這種格式下的外觀示例:
再看 Spartacus core build 出來(lái)的輸出:
Primary Entry point
包的主要入口點(diǎn)是模塊 id 與包名稱匹配的模塊(例如,對(duì)于“@angular/core”包,從主要入口點(diǎn)導(dǎo)入的內(nèi)容如下: import {Component, …} from ‘@angular/core’)。
Secondary Entry point
除了主要入口點(diǎn),包可以包含零個(gè)或多個(gè)次要入口點(diǎn)(例如@angular/common/http)。 這些包含我們不想與主入口點(diǎn)中的符號(hào)組合在一起的符號(hào),原因有兩個(gè):
(1)用戶通常認(rèn)為它們與主要符號(hào)組不同,并且如果它們與主要符號(hào)組相關(guān),那么他們就已經(jīng)在那里了。
(2)次要組中的符號(hào)通常僅用于特定場(chǎng)景(例如,在編寫和運(yùn)行測(cè)試時(shí))。 可能不會(huì)在主入口點(diǎn)中包含這些符號(hào),因此我們減少了它們被意外錯(cuò)誤使用的機(jī)會(huì)(例如,在@angular/core/testing 中使用的生產(chǎn)代碼中使用測(cè)試模擬)。
輔助入口點(diǎn)導(dǎo)入的模塊 ID 將模塊加載器定向到輔助入口點(diǎn)名稱的目錄。 例如,“@angular/core/testing”解析為一個(gè)同名的目錄,“@angular/core/testing”。 該目錄包含一個(gè) package.json 文件,該文件將加載器定向到它正在尋找的正確位置。 這允許我們?cè)趩蝹€(gè)包中創(chuàng)建多個(gè)入口點(diǎn)。
Compilation and transpilation
為了生成所有必需的構(gòu)建工件,我們強(qiáng)烈建議您使用 Angular 編譯器 (ngc) 使用 tsconfig.json 中的以下設(shè)置編譯您的代碼:
{"compilerOptions": {..."declaration": true,"module": "es2015","target": "es2015"},"angularCompilerOptions": {"strictMetadataEmit": true,"skipTemplateCodegen": true,"flatModuleOutFile": "my-ui-lib.js","flatModuleId": "my-ui-lib",} }優(yōu)化相關(guān)
Flattening of ES Modules
我們強(qiáng)烈建議您在將構(gòu)建工件發(fā)布到 npm 之前,通過(guò)扁平化 ES 模塊來(lái)優(yōu)化構(gòu)建工件。這顯著減少了 Angular 應(yīng)用程序的構(gòu)建時(shí)間以及最終應(yīng)用程序包的下載和解析時(shí)間。
Angular 編譯器支持生成索引 ES 模塊文件,然后可以使用這些文件使用 Rollup 等工具生成扁平化模塊,從而生成我們稱為扁平化 ES 模塊或 FESM 的文件格式。
FESM 是一種文件格式,通過(guò)將所有可從入口點(diǎn)訪問(wèn)的 ES 模塊扁平化為單個(gè) ES 模塊。它是通過(guò)跟蹤包中的所有導(dǎo)入并將該代碼復(fù)制到單個(gè)文件中而形成的,同時(shí)保留所有公共 ES 導(dǎo)出并刪除所有私有導(dǎo)入。
縮寫名稱“FESM”(發(fā)音為“phesom”)后面可以有一個(gè)數(shù)字,例如“FESM5”或“FESM2015”。數(shù)字是指模塊內(nèi) JavaScript 的語(yǔ)言級(jí)別。所以 FESM5 文件將是 ESM+ES5(導(dǎo)入/導(dǎo)出語(yǔ)句和 ES5 源代碼)。
要生成扁平化的 ES 模塊索引文件,請(qǐng)?jiān)?tsconfig.json 文件中使用以下配置選項(xiàng):
{"compilerOptions": {..."module": "es2015","target": "es2015",...},"angularCompilerOptions": {..."flatModuleOutFile": "my-ui-lib.js","flatModuleId": "my-ui-lib"} }一旦索引文件(例如 my-ui-lib.js)由 ngc 生成,捆綁器和優(yōu)化器(如 Rollup)可用于生成扁平化的 ESM 文件。
Inlining of templates and stylesheets
組件庫(kù)通常使用存儲(chǔ)在單獨(dú)文件中的樣式表和 html 模板來(lái)實(shí)現(xiàn)。 雖然不是必需的,但我們建議組件作者通過(guò)將 styleUrls 和 templateUrl 分別替換為樣式和模板元數(shù)據(jù)屬性,將模板和樣式表內(nèi)聯(lián)到他們的 FESM 文件以及 *.metadata.json 文件中。 這簡(jiǎn)化了應(yīng)用程序開(kāi)發(fā)人員對(duì)組件的使用。
從 APF v10 開(kāi)始,我們建議添加 tslib 作為主要入口點(diǎn)的直接依賴項(xiàng),這是因?yàn)?tslib 版本與用于編譯庫(kù)的 TypeScript 版本相關(guān)聯(lián)。
一些術(shù)語(yǔ)
-
package: 發(fā)布到 NPM 并安裝在一起的最小文件集,例如 @angular/core。 該包包含一個(gè)名為 package.json 的清單、編譯后的源代碼、TypeScript files、源映射、元數(shù)據(jù)等。該包通過(guò) npm install @angular/core 安裝。
-
Symbols:包含在模塊中的類、函數(shù)、常量或變量,并可選擇通過(guò)模塊導(dǎo)出對(duì)外部世界可見(jiàn)。
-
module ID: 導(dǎo)入語(yǔ)句中使用的模塊的標(biāo)識(shí)符,例如 “@spartacus/core”。 ID 通常直接映射到文件系統(tǒng)上的路徑,但由于各種模塊解析策略,情況并非總是如此。
-
module format:模塊語(yǔ)法規(guī)范,至少涵蓋用于從文件導(dǎo)入和導(dǎo)出的語(yǔ)法。 常見(jiàn)的模塊格式是 CommonJS(CJS,通常用于 Node.js 應(yīng)用程序)或 ECMAScript 模塊(ESM)。 模塊格式僅表示單個(gè)模塊的封裝,而不表示用于構(gòu)成模塊內(nèi)容的 JavaScript 語(yǔ)言特性。 因此,Angular 團(tuán)隊(duì)經(jīng)常使用語(yǔ)言級(jí)別說(shuō)明符作為模塊格式的后綴,例如 ESM+ES5 指定模塊采用 ESM 格式并包含下級(jí)到 ES5 的代碼。 其他常用組合:ESM+ES2015、CJS+ES5、CJS+ES2015。
-
bundle: 由構(gòu)建工具生成的單個(gè) JS 文件形式的工件,例如 WebPack 或 Rollup,包含源自一個(gè)或多個(gè)模塊的符號(hào)。 捆綁包是一種特定于瀏覽器的解決方法,可減少瀏覽器開(kāi)始下載數(shù)百甚至數(shù)萬(wàn)個(gè)文件時(shí)可能造成的網(wǎng)絡(luò)壓力。 Node.js 通常不使用包。 常見(jiàn)的捆綁格式是 UMD 和 System.register。
-
language level: 代碼的語(yǔ)言(ES5 或 ES2015)。 獨(dú)立于模塊格式。
-
entry point: 打算由用戶導(dǎo)入的模塊。 它由唯一的模塊 ID 引用,并導(dǎo)出該模塊 ID 引用的公共 API。 一個(gè)例子是@angular/core 或@angular/core/testing。 @angular/core 包中存在兩個(gè)入口點(diǎn),但它們導(dǎo)出不同的符號(hào)。 一個(gè)包可以有許多入口點(diǎn)。
-
deep import: 從不是入口點(diǎn)的模塊中檢索符號(hào)的過(guò)程。 這些模塊 ID 通常被認(rèn)為是私有 API,它們可以在項(xiàng)目的生命周期內(nèi)或在創(chuàng)建給定包的包時(shí)更改。
-
top level import: 來(lái)自入口點(diǎn)的導(dǎo)入。 可用的頂級(jí)導(dǎo)入定義了公共 API,并在“@angular/name”模塊中公開(kāi),例如 @angular/core 或 @angular/common。
-
tree shaking: 識(shí)別和刪除應(yīng)用程序未使用的代碼的過(guò)程 - 也稱為死代碼消除。 這是使用 Rollup、Closure Compiler 或 Uglify 等工具在應(yīng)用程序級(jí)進(jìn)行操作。
更多Jerry的原創(chuàng)文章,盡在:“汪子熙”:
總結(jié)
以上是生活随笔為你收集整理的Angular Package Format (APF) v12.0 介绍的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: SAP Spartacus packag
- 下一篇: 理想汽车已支持苹果 Apple Watc