TypeScript專案引用(project references)
TypeScript新特性之專案引用(project references)
專案引用是TypeScript 3.0中的一項新功能,允許您將TypeScript程式構建為更小的部分。
通過這樣做,您可以大大縮短構建時間,實現元件之間的邏輯分離,並以新的更好的方式組織程式碼。
我們還為tsc引入了一種新模式,即--build標誌,它與專案引用協同工作,以實現更快的TypeScript構建。
示例專案
讓我們看一個相當正常的程式,看看專案引用如何幫助我們更好地組織它。
想象一下,你有一個專案有兩個模組,轉換器和單元,以及每個模組的相應測試檔案:
/src/converter.ts /src/units.ts /test/converter-tests.ts /test/units-tests.ts /tsconfig.json
測試檔案匯入實現檔案並進行一些測試:
// converter-tests.ts import * as converter from "../converter"; assert.areEqual(converter.celsiusToFahrenheit(0), 32);
以前,如果您使用單個tsconfig檔案,則此結構很難處理:
1. 實現檔案可以匯入測試檔案
2. 在輸出資料夾名稱中沒有出現src的情況下,無法同時構建test和src,這可能是您不想要的
3. 僅更改實現檔案中的內部結構需要再次檢查測試,即使這不會導致新的錯誤
4. 僅更改測試需要再次對實現進行檢查,即使沒有任何改變
您可以使用多個tsconfig檔案來解決其中的一些問題,但會出現新的問題:
1. 沒有內建的最新檢查,因此您最終總是執行兩次tsc
2. 兩次呼叫tsc會導致更多的啟動時間開銷
3. tsc -w無法一次在多個配置檔案上執行
專案引用(project references)可以解決所有這些問題等等。
什麼是專案引用(project references)?
tsconfig.json檔案有一個新的頂級屬性"references"。
它是一個物件陣列,指定要引用的專案:
{ "compilerOptions": { // The usual }, "references": [ { "path": "../src" } ] }
每個引用的path屬性可以指向包含tsconfig.json檔案的目錄,也可以指向配置檔案本身(可以具有任何名稱)。
當您引用專案時,會發生新的事情:
1. 從引用的專案匯入模組將改為載入其輸出宣告檔案(.d.ts)
2. 如果引用的專案生成outFile,則輸出檔案.d.ts檔案的宣告將在此專案中可見
3. 如果需要,構建模式(下面會提到)將自動構建引用的專案
通過分成多個專案,您可以大大提高型別檢查和編譯的速度,減少使用編輯器時的記憶體使用量,並改程序序邏輯分組的實施。
composite
引用的專案必須啟用新的composite設定。
需要此設定以確保TypeScript可以快速確定在何處查詢引用專案的輸出。
啟用composite標誌會改變一些事情:
1. rootDir設定(如果未顯式設定)預設為包含tsconfig檔案的目錄
2. 所有實現檔案必須由include模式匹配或在files陣列中列出。如果違反此約束,tsc將通知您未指定哪些檔案
3. declaration必須開啟
declarationMaps
我們還增加了對declaration source maps的支援。如果啟用--declarationMap,您將能夠使用編輯器功能,如"轉到定義"和重新命名,以在支援的編輯器中跨專案邊界透明地導航和編輯程式碼。
以outFile為字首
您還可以使用引用中的prepend選項啟用前置依賴項的輸出:
"references": [ { "path": "../utils", "prepend": true } ]
預先設定專案將包括專案的輸出高於當前專案的輸出。
這適用於.js檔案和.d.ts檔案,原始碼對映檔案也將正確發出。
tsc只會使用磁碟上的現有檔案來執行此過程,因此可以建立一個專案,其中無法生成正確的輸出檔案,因為某些專案的輸出將在結果檔案中出現多次。
例如:
A ^ ^ /\ BC ^^ \ / D
在這種情況下,重要的是不要在每個參考文獻中新增字首,因為在D的輸出中最終會得到兩個A副本 - 這可能會導致意外結果。
專案引用的注意事項
專案引用有一些您應該注意的權衡。
因為依賴專案使用從其依賴項構建的.d.ts檔案,所以您必須在克隆之後簽入某些構建輸出或構建專案,然後才能在編輯器中導航專案而不會看到虛假錯誤。
我們正在開發一個能夠緩解這種情況的幕後.d.ts生成過程,但是現在我們建議告知開發人員他們應該在克隆之後構建它們。
此外,為了保持與現有構建工作流的相容性,除非使用--build開關呼叫,否則tsc不會自動構建依賴項。
讓我們瞭解更多關於--build的資訊。
TypeScript的構建模式
期待已久的功能是TypeScript專案的智慧增量構建。
在3.0中,您可以將-build標誌與tsc一起使用。
這實際上是tsc的新入口點,其行為更像構建協調器而不是簡單的編譯器。
執行tsc --build (簡稱tsc -b)將執行以下操作:
1. 查詢所有引用的專案
2. 檢測它們是否是最新的
3. 按正確的順序構建過時的專案
您可以為tsc -b提供多個配置檔案路徑(例如tsc -b src test)。
就像tsc -p一樣,如果命名為tsconfig.json,則不需要指定配置檔名本身。
> tsc -b# 在當前目錄中構建tsconfig.json > tsc -b src# 構建src/tsconfig.json > tsc -b foo/release.tsconfig.json bar# 構建foo/release.tsconfig.json和構建bar/tsconfig.json
不要擔心您在命令列上傳遞的排過序的檔案 - 如果需要,tsc將重新排序它們,以便始終首先構建依賴項。
還有一些特定於tsc -b的標誌:
--verbose: 列印詳細日誌記錄以解釋正在發生的事情(可能與任何其他標誌組合)
--dry: 顯示將要完成的但實際上不構建任何內容
--clean: 刪除指定專案的輸出(可以與--dry結合使用)
--force: 就好像所有專案都已過時一樣
--watch: 監視模式(除了--verbose外,不得與任何標誌組合使用)
注意事項
通常,除非出現noEmitOnError,否則tsc將在出現語法或型別錯誤時生成輸出(.js和.d.ts)。
在增量構建系統中執行此操作將非常糟糕 - 如果您的一個過時的依賴項出現新錯誤,您只能看到它一次,因為後續構建將跳過構建現在最新的專案。
因此,tsc -b實際上就像為所有專案啟用noEmitOnError一樣。
如果您檢查任何構建輸出(.js,.d.ts,.d.ts.map等),您可能需要在某些源控制操作之後執行--force構建,具體取決於源控制工具是否保留
本地副本和遠端副本之間的時間對映。
MSBuild
如果您有msbuild專案,則可以通過新增如下程式碼到您的proj檔案來啟用構建模式
<TypeScriptBuildMode>true</TypeScriptBuildMode>
這將啟用自動增量構建和清潔。
請注意,與tsconfig.json/-p一樣,不會遵循現有的TypeScript專案屬性 - 應使用tsconfig檔案管理所有設定。
一些團隊已經設定了基於msbuild的工作流,其中tsconfig檔案與他們配對的託管專案具有相同的隱式圖表排序。
如果您的解決方案是這樣的,您可以繼續使用msbuild和tsc -p以及專案引用;
這些是完全可互操作的。
指導(Guidance)
整體結構
使用更多tsconfig.json檔案,您通常需要使用配置檔案繼承來集中您的常用編譯器選項。
這樣,您可以在一個檔案中更改設定,而不必編輯多個檔案。
另一個好的做法是擁有一個"解決方案"tsconfig.json檔案,該檔案只引用了所有leaf-node專案。
這提供了一個簡單的切入點;
例如,在TypeScript repo中,我們只執行tsc -b src來構建所有端點,因為我們列出了src/tsconfig.json中的所有子專案。請注意,從3.0開始,如果在tsconfig.json中至少有一個reference將不會針對空的files陣列報錯
您可以在TypeScript儲存庫中看到這些模式 -src/tsconfig_base.json ,src/tsconfig.json 和src/tsc/tsconfig.json 作為關鍵示例。
構建相關模組
通常,使用相關模組transition a repo並不需要太多。
只需將tsconfig.json檔案放在給定父資料夾的每個子目錄中,並新增對這些配置檔案的引用以匹配程式的預期分層。
您需要將outDir設定為輸出資料夾的顯式子資料夾,或將rootDir設定為所有專案資料夾的公共根目錄。
構建outFiles
使用outFile進行編譯的佈局更靈活,因為相對路徑無關緊要。
要記住的一件事是,您通常希望在"最後"專案之前不使用前置 - 這將改善構建時間並減少任何給定構建中所需的I/O量。
TypeScript repo本身就是一個很好的參考 - 我們有一些"庫"專案和一些"端點"專案;
"端點"專案儘可能小,只吸引他們需要的庫。
原文地址:
http://www.typescriptlang.org/docs/handbook/project-references.html