TypeScript項(xiàng)目引用(project references)

轉(zhuǎn)發(fā) # TypeScript項(xiàng)目引用(project references)

TypeScript新特性之項(xiàng)目引用(project references)

項(xiàng)目引用是TypeScript 3.0中的一項(xiàng)新功能,允許您將TypeScript程序構(gòu)建為更小的部分。

通過(guò)這樣做,您可以大大縮短構(gòu)建時(shí)間,實(shí)現(xiàn)組件之間的邏輯分離,并以新的更好的方式組織代碼。

我們還為tsc引入了一種新模式,即--build標(biāo)志,它與項(xiàng)目引用協(xié)同工作,以實(shí)現(xiàn)更快的TypeScript構(gòu)建。

示例項(xiàng)目

讓我們看一個(gè)相當(dāng)正常的程序,看看項(xiàng)目引用如何幫助我們更好地組織它。
想象一下,你有一個(gè)項(xiàng)目有兩個(gè)模塊,轉(zhuǎn)換器和單元,以及每個(gè)模塊的相應(yīng)測(cè)試文件:

/src/converter.ts
/src/units.ts
/test/converter-tests.ts
/test/units-tests.ts
/tsconfig.json

測(cè)試文件導(dǎo)入實(shí)現(xiàn)文件并進(jìn)行一些測(cè)試:

// converter-tests.ts
import * as converter from "../converter";

assert.areEqual(converter.celsiusToFahrenheit(0), 32);

以前,如果您使用單個(gè)tsconfig文件,則此結(jié)構(gòu)很難處理:

  1. 實(shí)現(xiàn)文件可以導(dǎo)入測(cè)試文件
  2. 在輸出文件夾名稱(chēng)中沒(méi)有出現(xiàn)src的情況下,無(wú)法同時(shí)構(gòu)建test和src,這可能是您不想要的
  3. 僅更改實(shí)現(xiàn)文件中的內(nèi)部結(jié)構(gòu)需要再次檢查測(cè)試,即使這不會(huì)導(dǎo)致新的錯(cuò)誤
  4. 僅更改測(cè)試需要再次對(duì)實(shí)現(xiàn)進(jìn)行檢查,即使沒(méi)有任何改變

您可以使用多個(gè)tsconfig文件來(lái)解決其中的一些問(wèn)題,但會(huì)出現(xiàn)新的問(wèn)題:

  1. 沒(méi)有內(nèi)置的最新檢查,因此您最終總是運(yùn)行兩次tsc
  2. 兩次調(diào)用tsc會(huì)導(dǎo)致更多的啟動(dòng)時(shí)間開(kāi)銷(xiāo)
  3. tsc -w無(wú)法一次在多個(gè)配置文件上運(yùn)行

項(xiàng)目引用(project references)可以解決所有這些問(wèn)題等等。

什么是項(xiàng)目引用(project references)?

tsconfig.json文件有一個(gè)新的頂級(jí)屬性"references"。
它是一個(gè)對(duì)象數(shù)組,指定要引用的項(xiàng)目:

{
    "compilerOptions": {
        // The usual
    },
    "references": [
        { "path": "../src" }
    ]
}

每個(gè)引用的path屬性可以指向包含tsconfig.json文件的目錄,也可以指向配置文件本身(可以具有任何名稱(chēng))。
當(dāng)您引用項(xiàng)目時(shí),會(huì)發(fā)生新的事情:

  1. 從引用的項(xiàng)目導(dǎo)入模塊將改為加載其輸出聲明文件(.d.ts)
  2. 如果引用的項(xiàng)目生成outFile,則輸出文件.d.ts文件的聲明將在此項(xiàng)目中可見(jiàn)
  3. 如果需要,構(gòu)建模式(下面會(huì)提到)將自動(dòng)構(gòu)建引用的項(xiàng)目

通過(guò)分成多個(gè)項(xiàng)目,您可以大大提高類(lèi)型檢查和編譯的速度,減少使用編輯器時(shí)的內(nèi)存使用量,并改進(jìn)程序邏輯分組的實(shí)施。

composite

引用的項(xiàng)目必須啟用新的composite設(shè)置。
需要此設(shè)置以確保TypeScript可以快速確定在何處查找引用項(xiàng)目的輸出。
啟用composite標(biāo)志會(huì)改變一些事情:

  1. rootDir設(shè)置(如果未顯式設(shè)置)默認(rèn)為包含tsconfig文件的目錄
  2. 所有實(shí)現(xiàn)文件必須由include模式匹配或在files數(shù)組中列出。如果違反此約束,tsc將通知您未指定哪些文件
  3. declaration必須打開(kāi)

declarationMaps

我們還增加了對(duì)declaration source maps的支持。如果啟用--declarationMap,您將能夠使用編輯器功能,如"轉(zhuǎn)到定義"和重命名,以在支持的編輯器中跨項(xiàng)目邊界透明地導(dǎo)航和編輯代碼。

以outFile為前綴

您還可以使用引用中的prepend選項(xiàng)啟用前置依賴(lài)項(xiàng)的輸出:

"references": [
   { "path": "../utils", "prepend": true }
]

預(yù)先設(shè)置項(xiàng)目將包括項(xiàng)目的輸出高于當(dāng)前項(xiàng)目的輸出。
這適用于.js文件和.d.ts文件,源代碼映射文件也將正確發(fā)出。

tsc只會(huì)使用磁盤(pán)上的現(xiàn)有文件來(lái)執(zhí)行此過(guò)程,因此可以創(chuàng)建一個(gè)項(xiàng)目,其中無(wú)法生成正確的輸出文件,因?yàn)槟承╉?xiàng)目的輸出將在結(jié)果文件中出現(xiàn)多次。
例如:

   A
  ^ ^
 /   \
B     C
 ^   ^
  \ /
   D

在這種情況下,重要的是不要在每個(gè)參考文獻(xiàn)中添加前綴,因?yàn)樵贒的輸出中最終會(huì)得到兩個(gè)A副本 - 這可能會(huì)導(dǎo)致意外結(jié)果。

項(xiàng)目引用的注意事項(xiàng)

項(xiàng)目引用有一些您應(yīng)該注意的權(quán)衡。

因?yàn)橐蕾?lài)項(xiàng)目使用從其依賴(lài)項(xiàng)構(gòu)建的.d.ts文件,所以您必須在克隆之后簽入某些構(gòu)建輸出或構(gòu)建項(xiàng)目,然后才能在編輯器中導(dǎo)航項(xiàng)目而不會(huì)看到虛假錯(cuò)誤。
我們正在開(kāi)發(fā)一個(gè)能夠緩解這種情況的幕后.d.ts生成過(guò)程,但是現(xiàn)在我們建議告知開(kāi)發(fā)人員他們應(yīng)該在克隆之后構(gòu)建它們。

此外,為了保持與現(xiàn)有構(gòu)建工作流的兼容性,除非使用--build開(kāi)關(guān)調(diào)用,否則tsc不會(huì)自動(dòng)構(gòu)建依賴(lài)項(xiàng)。
讓我們了解更多關(guān)于--build的信息。

TypeScript的構(gòu)建模式

期待已久的功能是TypeScript項(xiàng)目的智能增量構(gòu)建。
在3.0中,您可以將-build標(biāo)志與tsc一起使用。
這實(shí)際上是tsc的新入口點(diǎn),其行為更像構(gòu)建協(xié)調(diào)器而不是簡(jiǎn)單的編譯器。

運(yùn)行tsc --build(簡(jiǎn)稱(chēng)tsc -b)將執(zhí)行以下操作:

  1. 查找所有引用的項(xiàng)目
  2. 檢測(cè)它們是否是最新的
  3. 按正確的順序構(gòu)建過(guò)時(shí)的項(xiàng)目

您可以為tsc -b提供多個(gè)配置文件路徑(例如tsc -b src test)。
就像tsc -p一樣,如果命名為tsconfig.json,則不需要指定配置文件名本身。

> tsc -b                                # 在當(dāng)前目錄中構(gòu)建tsconfig.json
> tsc -b src                            # 構(gòu)建src/tsconfig.json
> tsc -b foo/release.tsconfig.json bar  # 構(gòu)建foo/release.tsconfig.json和構(gòu)建bar/tsconfig.json

不要擔(dān)心您在命令行上傳遞的排過(guò)序的文件 - 如果需要,tsc將重新排序它們,以便始終首先構(gòu)建依賴(lài)項(xiàng)。
還有一些特定于tsc -b的標(biāo)志:

--verbose: 打印詳細(xì)日志記錄以解釋正在發(fā)生的事情(可能與任何其他標(biāo)志組合)
--dry: 顯示將要完成的但實(shí)際上不構(gòu)建任何內(nèi)容
--clean: 刪除指定項(xiàng)目的輸出(可以與--dry結(jié)合使用)
--force: 就好像所有項(xiàng)目都已過(guò)時(shí)一樣
--watch: 監(jiān)視模式(除了--verbose外,不得與任何標(biāo)志組合使用)

注意事項(xiàng)

通常,除非出現(xiàn)noEmitOnError,否則tsc將在出現(xiàn)語(yǔ)法或類(lèi)型錯(cuò)誤時(shí)生成輸出(.js和.d.ts)。
在增量構(gòu)建系統(tǒng)中執(zhí)行此操作將非常糟糕 - 如果您的一個(gè)過(guò)時(shí)的依賴(lài)項(xiàng)出現(xiàn)新錯(cuò)誤,您只能看到它一次,因?yàn)楹罄m(xù)構(gòu)建將跳過(guò)構(gòu)建現(xiàn)在最新的項(xiàng)目。
因此,tsc -b實(shí)際上就像為所有項(xiàng)目啟用noEmitOnError一樣。
如果您檢查任何構(gòu)建輸出(.js,.d.ts,.d.ts.map等),您可能需要在某些源控制操作之后運(yùn)行--force構(gòu)建,具體取決于源控制工具是否保留
本地副本和遠(yuǎn)程副本之間的時(shí)間映射。

MSBuild

如果您有msbuild項(xiàng)目,則可以通過(guò)添加如下代碼到您的proj文件來(lái)啟用構(gòu)建模式

<TypeScriptBuildMode>true</TypeScriptBuildMode>

這將啟用自動(dòng)增量構(gòu)建和清潔。

請(qǐng)注意,與tsconfig.json/-p一樣,不會(huì)遵循現(xiàn)有的TypeScript項(xiàng)目屬性 - 應(yīng)使用tsconfig文件管理所有設(shè)置。

一些團(tuán)隊(duì)已經(jīng)設(shè)置了基于msbuild的工作流,其中tsconfig文件與他們配對(duì)的托管項(xiàng)目具有相同的隱式圖表排序。
如果您的解決方案是這樣的,您可以繼續(xù)使用msbuild和tsc -p以及項(xiàng)目引用;
這些是完全可互操作的。

指導(dǎo)(Guidance)

整體結(jié)構(gòu)

使用更多tsconfig.json文件,您通常需要使用配置文件繼承來(lái)集中您的常用編譯器選項(xiàng)。
這樣,您可以在一個(gè)文件中更改設(shè)置,而不必編輯多個(gè)文件。

另一個(gè)好的做法是擁有一個(gè)"解決方案"tsconfig.json文件,該文件只引用了所有l(wèi)eaf-node項(xiàng)目。
這提供了一個(gè)簡(jiǎn)單的切入點(diǎn);
例如,在TypeScript repo中,我們只運(yùn)行tsc -b src來(lái)構(gòu)建所有端點(diǎn),因?yàn)槲覀兞谐隽藄rc/tsconfig.json中的所有子項(xiàng)目。請(qǐng)注意,從3.0開(kāi)始,如果在tsconfig.json中至少有一個(gè)reference將不會(huì)針對(duì)空的files數(shù)組報(bào)錯(cuò)

您可以在TypeScript存儲(chǔ)庫(kù)中看到這些模式 - src/tsconfig_base.json,src/tsconfig.jsonsrc/tsc/tsconfig.json作為關(guān)鍵示例。

構(gòu)建相關(guān)模塊

通常,使用相關(guān)模塊transition a repo并不需要太多。
只需將tsconfig.json文件放在給定父文件夾的每個(gè)子目錄中,并添加對(duì)這些配置文件的引用以匹配程序的預(yù)期分層。
您需要將outDir設(shè)置為輸出文件夾的顯式子文件夾,或?qū)ootDir設(shè)置為所有項(xiàng)目文件夾的公共根目錄。

構(gòu)建outFiles

使用outFile進(jìn)行編譯的布局更靈活,因?yàn)橄鄬?duì)路徑無(wú)關(guān)緊要。
要記住的一件事是,您通常希望在"最后"項(xiàng)目之前不使用前置 - 這將改善構(gòu)建時(shí)間并減少任何給定構(gòu)建中所需的I/O量。
TypeScript repo本身就是一個(gè)很好的參考 - 我們有一些"庫(kù)"項(xiàng)目和一些"端點(diǎn)"項(xiàng)目;
"端點(diǎn)"項(xiàng)目盡可能小,只吸引他們需要的庫(kù)。

原文地址:
http://www.typescriptlang.org/docs/handbook/project-references.html

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容