99re热这里只有精品视频,7777色鬼xxxx欧美色妇,国产成人精品一区二三区在线观看,内射爽无广熟女亚洲,精品人妻av一区二区三区

Angular 包格式

2022-07-20 13:40 更新

Angular 包格式

本文檔描述了 Angular 包格式 (APF)。APF 是針對(duì) npm 包結(jié)構(gòu)和格式的 Angular 專用規(guī)范,所有第一方 Angular 包(?@angular/core? 、 ?@angular/material? 等)和大多數(shù)第三方 Angular 庫(kù)都使用了該規(guī)范。

APF 能讓包在使用 Angular 的大多數(shù)常見(jiàn)場(chǎng)景下無(wú)縫工作。使用 APF 的包與 Angular 團(tuán)隊(duì)提供的工具以及更廣泛的 JavaScript 生態(tài)系統(tǒng)兼容。建議第三方庫(kù)開(kāi)發(fā)者也都遵循這種格式。

APF 與 Angular 的其余部分一起進(jìn)行版本控制,每個(gè)主要版本都改進(jìn)了包格式。你可以在此 google doc 中找到 v13 之前版本的規(guī)范。

為什么要指定包格式?

在當(dāng)今的 JavaScript 環(huán)境中,開(kāi)發(fā)人員將使用多種不同的工具鏈(Webpack、rollup、esbuild 等)以多種不同的方式使用包。這些工具可能理解并需要不同的輸入 —— 一些工具能處理最新的 ES 語(yǔ)言版本,而其他工具也許要直接使用較舊的 ES 版本。

這種 Angular 分發(fā)格式支持所有常用的開(kāi)發(fā)工具和工作流,并著重于優(yōu)化,從而縮小應(yīng)用程序有效負(fù)載大小或縮短開(kāi)發(fā)迭代周期(構(gòu)建時(shí)間)。

開(kāi)發(fā)人員可以依靠 Angular CLI 和 ng-packagr(Angular CLI 使用的構(gòu)建工具)來(lái)生成 APF 格式的包。

文件布局

以下示例顯示了 ?@angular/core? 包文件布局的簡(jiǎn)化版本,并附有對(duì)包中每個(gè)文件的解釋。

此表描述了 ?node_modules/@angular/core? 下的文件布局,注釋為描述文件和目錄的用途:

文件

用途

README.md

包 README,由 npmjs web UI 使用。

package.json

主要的 package.json,描述包本身以及所有可用的入口點(diǎn)和代碼格式。此文件包含供運(yùn)行時(shí)使用的 "exports" 映射和一些用于執(zhí)行模塊解析的工具。

index.d.ts

主入口點(diǎn) @angular/core 捆綁的 .d.ts。

esm2020/
  ─ core.mjs
  ─ index.mjs
  ─ public_api.mjs

esm2020/
─ core.mjs
─ index.mjs
─ public_api.mjs

未展平的 ES2020 格式的 @angular/core 源代碼樹(shù)。

esm2020/testing/

未扁平化的 ES2020 格式的 @angular/core/testing 入口點(diǎn)的樹(shù)。

fesm2015/
  ─ core.mjs
  ─ core.mjs.map
  ─ testing.mjs
  ─ testing.mjs.map

扁平化 (FESM) ES2015 格式的所有入口點(diǎn)的代碼,以及源碼映射。

fesm2020/
  ─ core.mjs
  ─ core.mjs.map
  ─ testing.mjs
  ─ testing.mjs.map

扁平化 (FESM) ES2020 格式的所有入口點(diǎn)的代碼,以及源碼映射。

testing/

代表 testing 入口點(diǎn)的目錄。

testing/index.d.ts

為 @angular/core/testing 入口點(diǎn)打包的 .d.ts。

package.json

主 ?package.json? 包含重要的包元數(shù)據(jù),包括以下內(nèi)容:

  • 它把此包聲明為 EcmaScript 模塊 (ESM) 格式
  • 它包含一個(gè) ?"exports"? 字段,用于定義所有入口點(diǎn)的可用源碼格式
  • 它包含定義主入口點(diǎn) ?@angular/core? 的可用源碼格式的一些鍵,供不理解 ?"exports"? 的工具使用。這些鍵已棄用,隨著對(duì) ?"exports"? 的支持在整個(gè)生態(tài)系統(tǒng)中逐步退出,這些鍵將被刪除。
  • 它聲明此包是否包含副作用

ESM 聲明

頂級(jí) ?package.json? 包含此鍵:

{
  "type": "module"
}

這會(huì)通知解析器,此包中的代碼正在使用 EcmaScript 模塊而不是 CommonJS 模塊。

"exports"

?"exports"? 字段具有以下結(jié)構(gòu):

"exports": {
  "./schematics/*": {
    "default": "./schematics/*.js"
  },
  "./package.json": {
    "default": "./package.json"
  },
  ".": {
    "types": "./core.d.ts",
    "esm2020": "./esm2020/core.mjs",
    "es2020": "./fesm2020/core.mjs",
    "es2015": "./fesm2015/core.mjs",
    "node": "./fesm2015/core.mjs",
    "default": "./fesm2020/core.mjs"
  },
  "./testing": {
    "types": "./testing/testing.d.ts",
    "esm2020": "./esm2020/testing/testing.mjs",
    "es2020": "./fesm2020/testing.mjs",
    "es2015": "./fesm2015/testing.mjs",
    "node": "./fesm2015/testing.mjs",
    "default": "./fesm2020/testing.mjs"
  }
}

主要看 "." 和 "./testing" 這兩個(gè)鍵,它們分別定義了 @angular/core 主要入口點(diǎn)和 @angular/core/testing 次要入口點(diǎn)的可用代碼格式。對(duì)于每個(gè)入口點(diǎn),可用的格式為:

格式

詳情

類型定義(.d.ts 文件)

TypeScript 在依賴于給定包時(shí)使用 .d.ts 文件。

es2020

已展平為單個(gè)源文件的 ES2020 代碼。

es2015

已展平為單個(gè)源文件的 ES2015 代碼。

esm2020

未展平的源文件中的 ES2020 代碼

認(rèn)識(shí)這些鍵的工具可以優(yōu)先從 ?"exports"? 中選擇所需的代碼格式。其余 2 個(gè)鍵控制工具的默認(rèn)行為:

  • ?"node"? 在 Node.js 中加載包時(shí)選擇扁平化的 ES2015 代碼。
  • 使用這種格式是由于 ?zone.js? 的要求,因?yàn)樗恢С衷?nbsp;?async ?/ ?await ?ES2017 語(yǔ)法。因此,指示 Node 使用 ES2015 代碼,其中 ?async ?/ ?await ?結(jié)構(gòu)已降級(jí)為 Promises。

  • ?"default"? 為所有其他消費(fèi)者選擇扁平化的 ES2020 代碼。

庫(kù)可能希望公開(kāi)其他靜態(tài)文件,這些文件沒(méi)有被基于 JavaScript 的入口點(diǎn)(比如 Sass mixins 或預(yù)編譯的 CSS)的導(dǎo)出所捕獲。

舊版解析鍵

除了 ?"exports"? 之外,頂級(jí) ?package.json? 還為不支持 ?"exports"? 的解析器定義了舊模塊解析鍵。對(duì)于 ?@angular/core?,這些是:

{
  "fesm2020": "./fesm2020/core.mjs",
  "fesm2015": "./fesm2015/core.mjs",
  "esm2020": "./esm2020/core.mjs",
  "typings": "./core.d.ts",
  "module": "./fesm2015/core.mjs",
  "es2020": "./fesm2020/core.mjs",
}

如上,模塊解析器可以用這些鍵來(lái)加載特定的代碼格式。

注意:
與 ?"default"? 不同,?"module"? 是為 Node 以及任何未配置為使用特定鍵的工具選擇的格式。它基本和 ?"node"? 一樣,但由于 ZoneJS 的限制,選擇了 ES2015 代碼。

副作用

?package.json? 的最后一個(gè)功能是聲明此包是否有副作用。

{
  "sideEffects": false
}

大多數(shù) Angular 包不應(yīng)該依賴于頂級(jí)副作用,因此應(yīng)該包含這個(gè)聲明。

入口點(diǎn)和代碼拆分

APF 中的包,包含一個(gè)主要入口點(diǎn)和零到多個(gè)次要入口點(diǎn)(比如 ?@angular/common/http?)。入口點(diǎn)有多種功能。

  1. 它們定義了用戶要從中導(dǎo)入代碼的模塊說(shuō)明符(比如,?@angular/core? 和 ?@angular/core/testing?)。
  2. 用戶通常將這些入口點(diǎn)視為具有不同用途或功能的不同符號(hào)組。

    特定入口點(diǎn)可能僅用于特殊目的,比如測(cè)試。此類 API 可以與主入口點(diǎn)分離,以減少它們被意外或錯(cuò)誤使用的機(jī)會(huì)。

  3. 它們定義了可以惰性加載代碼的粒度。
  4. 許多現(xiàn)代構(gòu)建工具只能在 ES 模塊級(jí)別進(jìn)行“代碼拆分”(又名惰性加載)。由于 APF 主要為每個(gè)入口點(diǎn)使用一個(gè)“扁平” ES 模塊,這意味著大多數(shù)構(gòu)建工具無(wú)法將單個(gè)入口點(diǎn)中的代碼拆分為多個(gè)輸出塊。

APF 包的一般規(guī)則是為盡可能小的邏輯相關(guān)代碼集使用入口點(diǎn)。比如,Angular Material 包將每個(gè)邏輯組件或一組組件作為單獨(dú)的入口點(diǎn)發(fā)布 - 一個(gè)用于按鈕,一個(gè)用于選項(xiàng)卡等。如果需要,這允許單獨(dú)惰性加載每個(gè) Material 組件。

并非所有庫(kù)都需要這樣的粒度。大多數(shù)具有單一邏輯目的的庫(kù)應(yīng)該作為單一入口點(diǎn)發(fā)布。比如 ?@angular/core? 為運(yùn)行時(shí)使用單個(gè)入口點(diǎn),因?yàn)?nbsp;Angular 運(yùn)行時(shí)通常用作單個(gè)實(shí)體。

次要入口點(diǎn)的解析

可以通過(guò)包的 ?package.json? 的 ?"exports"? 字段解析輔助入口點(diǎn)。

自述文件

markdown 格式的自述文件,用于在 npm 和 github 上顯示包的描述。

?@angular/core? 包的示例自述內(nèi)容:

Angular
=======

The sources for this package are in the main [Angular](https://github.com/angular/angular) repo.Please file issues and pull requests against that repo.

License: MIT

部分編譯

APF 格式的庫(kù)必須以“部分編譯”模式發(fā)布。這是 ?ngc ?的一種編譯模式,它生成不依賴于特定 Angular 運(yùn)行時(shí)版本的已編譯 Angular 代碼,與用于應(yīng)用程序的完整編譯形成對(duì)比,其中 Angular 編譯器和運(yùn)行時(shí)版本必須完全匹配。

要部分編譯 Angular 代碼,請(qǐng)?jiān)?nbsp;?tsconfig.json? 中的 ?"angularCompilerOptions"? 中使用 ?"compilationMode"? 標(biāo)志:

{
  …
  "angularCompilerOptions": {
    "compilationMode": "partial",
  }
}

然后,在應(yīng)用程序構(gòu)建過(guò)程中,Angular CLI 將部分編譯的庫(kù)代碼轉(zhuǎn)換為完全編譯的代碼。

優(yōu)化

ES 模塊的扁平化

APF 指定代碼要以“扁平化”的 ES 模塊格式發(fā)布。這顯著減少了 Angular 應(yīng)用程序的構(gòu)建時(shí)間以及最終應(yīng)用程序包的下載和解析時(shí)間。請(qǐng)查看 Nolan Lawson 發(fā)表的優(yōu)秀文章“小模塊的成本”。

Angular 編譯器支持生成索引 ES 模塊文件,然后可以讓這些文件借助 Rollup 等工具生成扁平化模塊,從而生成我們稱為扁平化 ES 模塊或 FESM 的文件格式。

FESM 是一種文件格式,它會(huì)將所有可從入口點(diǎn)訪問(wèn)的 ES 模塊扁平化為單個(gè) ES 模塊。它是通過(guò)跟蹤包中的所有導(dǎo)入并將該代碼復(fù)制到單個(gè)文件中而生成的,同時(shí)保留所有公共 ES 導(dǎo)出并刪除所有私有導(dǎo)入。

縮寫(xiě)名稱“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": "esnext",
    "target": "es2020",
    …
  },
  "angularCompilerOptions": {
    …
    "flatModuleOutFile": "my-ui-lib.js",
    "flatModuleId": "my-ui-lib"
  }
}

一旦 ngc 生成了索引文件(比如 ?my-ui-lib.js?),打包器和優(yōu)化器(如 Rollup)就可用于生成扁平化的 ESM 文件。

注意 package.json 中的默認(rèn)值

從 webpack v4 開(kāi)始,對(duì)于 webpack 用戶來(lái)說(shuō),ES 模塊優(yōu)化的扁平化應(yīng)該不是必需的,其實(shí)理論上我們應(yīng)該能夠在不扁平化 webpack 中的模塊的情況下獲得更好的代碼拆分。在實(shí)踐中,當(dāng)使用非扁平化模塊作為 webpack v4 的輸入時(shí),我們?nèi)匀粫?huì)看到大小增加了。這就是為什么 package.json 中的 ?"module"? 和 ?"es2020"? 條目仍然指向 fesm 文件的原因。我們正在調(diào)查此問(wèn)題,并希望在解決大小回歸問(wèn)題后將 package.json 中的 ?"module"? 和 ?"es2020"? 入口點(diǎn)切換到未扁平化的文件。APF 目前包含未扁平化的 ESM2020 代碼,目的是驗(yàn)證此類未來(lái)的更改。

“副作用”標(biāo)志

默認(rèn)情況下,EcmaScript 模塊是有副作用的:從模塊導(dǎo)入可確保該模塊頂層的任何代碼都將執(zhí)行。這通常是不可取的,因?yàn)榈湫湍K中的大多數(shù)副作用代碼并不是真正的副作用,而是僅影響特定符號(hào)。如果沒(méi)有導(dǎo)入和使用這些符號(hào),通常需要在稱為 tree-shaking 的優(yōu)化過(guò)程中將它們刪除,而副作用代碼可以防止這種情況發(fā)生。

諸如 Webpack 之類的構(gòu)建工具支持一個(gè)標(biāo)志,該標(biāo)志允許包聲明它們并不依賴于其模塊頂層的副作用代碼,從而使工具可以更自由地對(duì)包中的代碼進(jìn)行搖樹(shù)優(yōu)化。這些優(yōu)化的最終結(jié)果應(yīng)該是較小的包大小和代碼拆分后包塊中更好的代碼分布。如果此優(yōu)化包含非本地副作用,則此優(yōu)化可能會(huì)破壞你的代碼 - 然而,這在 Angular 應(yīng)用程序中并不常見(jiàn),并且通常是糟糕設(shè)計(jì)的標(biāo)志。我們的建議是讓所有包通過(guò)將 sideEffects 屬性設(shè)置為 false 來(lái)聲明無(wú)副作用狀態(tài),并且讓開(kāi)發(fā)人員遵循 Angular 風(fēng)格指南,這自然會(huì)導(dǎo)致代碼沒(méi)有非本地副作用。

更多信息:關(guān)于副作用的 webpack 文檔

ES2020 語(yǔ)言級(jí)別

ES2020 語(yǔ)言級(jí)別現(xiàn)在是 Angular CLI 和其他工具使用的默認(rèn)語(yǔ)言級(jí)別。Angular CLI 會(huì)將捆綁包降級(jí)到所有目標(biāo)瀏覽器在應(yīng)用程序構(gòu)建時(shí)都支持的語(yǔ)言級(jí)別。

d.ts 捆綁/類型定義的扁平化

從 APF v8 開(kāi)始,我們現(xiàn)在更喜歡運(yùn)行 API Extractor 來(lái)打包 TypeScript 定義,以便整個(gè) API 都出現(xiàn)在單個(gè)文件中。

在之前的 APF 版本中,每個(gè)入口點(diǎn)都會(huì)在 .d.ts 入口點(diǎn)旁邊有一個(gè) ?src ?目錄,該目錄包含與原始源代碼結(jié)構(gòu)匹配的單個(gè) d.ts 文件。雖然這種分發(fā)格式仍然被允許和支持,但非常不鼓勵(lì)它,因?yàn)樗鼤?huì)弄暈 IDE 之類的工具,然后提供錯(cuò)誤的自動(dòng)完成,并允許用戶依賴深度導(dǎo)入的路徑,這些路徑通常不被認(rèn)為是庫(kù)或包的公共 API。

庫(kù)

從 APF v10 開(kāi)始,我們建議添加 tslib 作為主要入口點(diǎn)的直接依賴項(xiàng)。這是因?yàn)?nbsp;tslib 版本與用來(lái)編譯庫(kù)的 TypeScript 版本相關(guān)聯(lián)。

術(shù)語(yǔ)定義

本文檔中特意使用了以下術(shù)語(yǔ)。在本節(jié)中,我們定義所有這些以便更清晰。

發(fā)布到 NPM 并一起安裝的最小文件集,比如 ?@angular/core?。該包中包含一個(gè)名為 package.json 的清單、編譯后的源代碼、TypeScript 定義文件、源碼映射、元數(shù)據(jù)等。該包是通過(guò) ?npm install @angular/core? 安裝的。

符號(hào)

包含在模塊中的類、函數(shù)、常量或變量,可選擇通過(guò)模塊導(dǎo)出,以便對(duì)外界可見(jiàn)。

模塊

ECMAScript 模塊的縮寫(xiě)。包含導(dǎo)入和導(dǎo)出符號(hào)的語(yǔ)句的文件。這與 ECMAScript 規(guī)范中模塊的定義相同。

ESM

ECMAScript 模塊的縮寫(xiě)(見(jiàn)上文)。

FESM

Flattened ES Modules 的縮寫(xiě),由一種文件格式組成,該文件格式是通過(guò)將所有可從入口點(diǎn)訪問(wèn)的 ES 模塊扁平化為單個(gè) ES 模塊而創(chuàng)建的。

模塊標(biāo)識(shí)

導(dǎo)入語(yǔ)句中使用的模塊的標(biāo)識(shí)符(比如 ?@angular/core?)。此 ID 通常直接映射到文件系統(tǒng)上的路徑,但由于有各種模塊解析策略,情況也并非總是如此。

模塊說(shuō)明符

模塊標(biāo)識(shí)符(見(jiàn)上文)。

模塊解析策略

用于將模塊 ID 轉(zhuǎn)換為文件系統(tǒng)路徑的算法。Node.js 就有一個(gè)良好定義且廣泛使用的,TypeScript 支持多種模塊解析策略,Closure Compiler 還有另一種策略。

模塊格式

模塊語(yǔ)法規(guī)范,至少涵蓋用于從文件導(dǎo)入和導(dǎo)出的語(yǔ)法。常見(jiàn)的模塊格式是 CommonJS(CJS,通常用于 Node.js 應(yīng)用程序)或 ECMAScript 模塊(ESM)。模塊格式僅表示單個(gè)模塊的封裝,而不表示用于構(gòu)成模塊內(nèi)容的 JavaScript 語(yǔ)言特性。正因?yàn)槿绱?,Angular 團(tuán)隊(duì)經(jīng)常使用語(yǔ)言級(jí)別說(shuō)明符作為模塊格式的后綴,比如 ESM+ES2015 指定模塊為 ESM 格式并包含降級(jí)到 ES2015 的代碼。

捆綁包

單個(gè) JS 文件形式的工件,由構(gòu)建工具(比如 WebpackRollup)生成,其中包含源自一個(gè)或多個(gè)模塊的符號(hào)。捆綁包是一種瀏覽器專用的解決方案,可減少瀏覽器開(kāi)始下載數(shù)百甚至數(shù)萬(wàn)個(gè)文件時(shí)可能造成的網(wǎng)絡(luò)壓力。Node.js 通常不使用捆綁包。常見(jiàn)的捆綁包格式是 UMD 和 System.register。

語(yǔ)言級(jí)別

代碼的語(yǔ)言(ES2015 或 ES2020)。獨(dú)立于模塊格式。

入口點(diǎn)

旨在由用戶導(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)。

深度導(dǎo)入

從不是入口點(diǎn)的模塊中檢索符號(hào)的過(guò)程。這些模塊 ID 通常被認(rèn)為是私有 API,它們可以在項(xiàng)目的生命周期內(nèi)或在創(chuàng)建給定包的捆綁包時(shí)更改。

頂級(jí)導(dǎo)入

來(lái)自入口點(diǎn)的導(dǎo)入。可用的頂級(jí)導(dǎo)入定義了公共 API,并在“@angular/name”模塊中公開(kāi),比如 ?@angular/core? 或 ?@angular/common?。

搖樹(shù)優(yōu)化

識(shí)別和刪除應(yīng)用程序中未使用的代碼的過(guò)程 - 也稱為死代碼消除。這是使用 Rollup 、 Closure Compiler 或 Terser 等工具在應(yīng)用程序級(jí)別執(zhí)行的全局優(yōu)化。

AOT 編譯器

Angular 的預(yù)先編譯器。

扁平類型定義

從 API Extractor 生成的捆綁 TypeScript 定義。


以上內(nèi)容是否對(duì)您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號(hào)
微信公眾號(hào)

編程獅公眾號(hào)