網站搜尋

除錯 - Visual Studio:如何在共享專案中使用 IIS Express 和跨專案引用(不連結或複製檔案)除錯 TypeScript


理想情況下,我們可以簡單地將共享的 TypeScript 專案引用添加到另一個專案,並能像使用 Visual Basic 或 C# 的跨專案引用一樣使用被引用的代碼。可惜,這還不可用。

希望微軟能在未來的某個版本中升級 Visual Studio,使其支持無縫的跨專案 TypeScript 偵錯,而無需重複共享文件。在那之前,我們需要一個解決方法。其他幾個人在 Stack Overflow 上也提出了類似的問題:

  • VS2013 Typescript:多專案的引用與除錯
  • 在其他專案中調試 Typescript ts 檔案
  • 兩個專案之間的跨專案引用

但這些問題中沒有一個符合本問題中所列的所有要求。以下是為什麼這些問題中所發布的答案不符合我們需求的原因:

在 Visual Studio 中,遞迴或手動連結檔案的問題

  • 在連結檔案上,除錯和「前往定義」功能都運作不佳,甚至完全無法運作。在除錯 ASP.NET 網站時,連結的檔案不存在。
  • 一些有用的外掛程式會將每個連結的檔案視為單獨的檔案,這會減慢整個解決方案的程式碼審查和除錯速度(例如,單個連結的共享檔案中的錯誤會顯示為三個不同的錯誤:一個是原始檔案的錯誤,一個是參考專案 A 的錯誤,另一個是參考專案 B 的錯誤)。
  • 這很不優雅。

將檔案從共享專案複製到引用專案時的問題

  • 無論你多麼小心,你很可能會直接編輯複製的檔案,而不是原本的共享檔案;當你重建時,複製檔案中的所有更改都將丟失。
  • 與鏈接文件有關的問題在這裡也適用。

僅僅引用共享專案的 TypeScript 檔案所遇到的問題

  • 生成的地圖檔案,這些檔案在多個系統中進行除錯時是必需的,並不指向共享專案。相反,它們指向相對路徑的檔案引用,這會破壞共享檔案的除錯。

其他要求

  • 我們需要保留直接在每個引用應用程式中構建共享 TypeScript 的能力,而不是使用單獨的共享網站然後再包含那個共享代碼,因為引用的應用程式目標不同的 ECMAScript 版本(例如,公共網站為 ECMAScript3,而管理網站為 ECMAScript 5/6,可指定最低瀏覽器版本),而且不同的應用程式引用不同的共享檔案(引用項目透過不同的 reference.ts 檔案引用共享項目中的不同檔案組,從而保持引用整齊)。
  • 在開發環境中,透過共享網站進行除錯是可以的,但對於生產版本,必須將共享代碼直接構建到引用的專案中。
  • 所有 TypeScript 檔案,包括共享檔案,都是編譯成每個引用項目中的單一檔案,稱為 App.js。
  • 確保在 Visual Studio 之外也能進行除錯(這樣我們可以使用 Chrome、Firefox 及其他支援 map 文件的瀏覽器進行除錯,也能在 Visual Studio/Internet Explorer 中進行除錯)。

有人有這個問題的解決方案,或者知道微軟是否會在 Visual Studio 2015 中建立跨專案引用(包括完整的除錯支援)?

答案#1

我們能提出的滿足所有要求的最佳解決方案涉及以下步驟:

  1. 將參考加入到你共享的 TypeScript 檔案中(使用特殊的 _references.ts 檔案,或直接在 TypeScript 檔案中加入參考)。

  2. 使用 PowerShell 自動更新 TypeScript 生成的地圖檔,使其指向共享 Web 應用程式的專案 URL 或虛擬目錄(可用於 IIS Express 和完整 IIS)。

我明白這看起來像很多工作,但設置不應該超過30分鐘。它運作良好,長期來看將節省開發的精力和時間:

1. 在你共用的 TypeScript 檔案中新增參考

  • Visual Studio 使這個變得簡單:將 TypeScript 檔案(可以是單個檔案或 _references.ts 檔案)從共享專案拖到引用專案的 _references.ts 檔案或任何其他 TypeScript 檔案中(_references.ts 可以保持引用整齊,但並非所有專案結構都適用)。請注意,_references.ts 檔案必須始終位於專案根目錄中,才能按預期運作。

來源

  • Visual Studio 2013 的 TypeScript 編譯器不尊重 '_references.ts' 文件
  • http://blogs.msdn.com/b/typescript/archive/2013/12/05/announcing-typescript-0-9-5.aspx.

2. 使用 PowerShell 自動更新 TypeScript 生成的地圖文件(以啟用除錯)

此步驟確保共享引用指向原始共享檔案,使用一種可在 Visual Studio、Chrome 和 Firefox 調試中運作的方法(將相對共享引用替換為專案 URL 或虛擬目錄)。

致微軟:這種類型的引用應該在未來的 Visual Studio 版本中是可配置的和/或自動化的,例如,如果文件來自不同的專案,被引用時,應自動將引用映射到共享專案的專案 URL。

選項 1:您共享的程式碼位於 Web 應用程式專案中。

這適用於多個除錯系統(已在 Visual Studio、Chrome 和 Firefox 上測試):

  1. 從屬性 | 網頁 | 專案 URL 獲取共用應用程式專案 URL。

  2. 使用後置建置事件來執行 PowerShell 腳本,該腳本將替換您 App.js.map 文件中的所有共用引用,以指向專案 URL。

範例後置建置命令:

Powershell [io.file]::WriteAllText('$(ProjectDir)Scripts\App.js.map', ((gc '$(ProjectDir)Scripts\App.js.map') -replace '../../Shared_TypeScript/','http://localhost:12345/'))

欲了解更多詳情,請參閱下方來源中的 PowerShell 替換。

  1. 確保你為你的共享 Web 應用程式專案以及你所參考的 Web 應用程式專案設定除錯。

選項 2:您共享的程式碼不在 Web 應用程式專案中。

這對 Visual Studio 調試無效,但可能對某些情況是一個更好的選擇,而且它是非網頁應用程式專案唯一已知的選項(已在 Chrome 測試,可能也適用於 Firefox):

  1. 將虛擬目錄新增到您的 IIS Express 網站設定中,指向您的共享 TypeScript 專案:https://stackoverflow.com/a/8929315/2033465(參見 EDIT)。

  2. 使用後置建置事件來執行一個 Powershell 腳本,該腳本將替換你在 App.js.map 檔案中的所有共享引用,以指向你上述設置的虛擬目錄。

範例後置建置命令:

Powershell [io.file]::WriteAllText('$(ProjectDir)Scripts\App.js.map', ((gc '$(ProjectDir)Scripts\App.js.map') -replace '../../GlobalRef/','/GlobalRef/'))

欲了解更多詳情,請參閱下方來源中的 PowerShell 替換。

來源

  • PowerShell 替換:VS2010 編譯後事件,在檔案中替換字串。Powershell?

如果你需要能在生產環境中對 TypeScript 文件進行除錯(這不是我們的要求),那麼你可以修改後建構腳本以運行不同的命令(類似,但指向你共享網站的虛擬目錄而不是本地主機)。這超出了本文的範疇。

結論

這是迄今為止我能想出的最好的方法(感謝所有其他來源),它符合所有要求。

如果您有更好的方法,請告訴我們。

答案#2

我正在解決類似的問題。我的需求是:

  • 在一個解決方案中有多個專案,組織方式與 C# 專案相同,即解決方案資料夾內有 .sln 文件,每個專案有對應的子資料夾,內含 .csproj 和 TypeScript 文件。

  • 在 VS 和 IE11 中進行除錯的可能性(通過 F5 運行,設置斷點以及所有那些酷炫的東西)

  • 理想情況下不需要額外的腳本。

我試過:

  • postbuild PowerShell 腳本將來源複製到 www 根目錄 src
  • 以這種方式組織專案,其中啟動專案是 wwwroot,其他專案則放在 wwwroot 的 src 資料夾下(也就是在啟動專案資料夾內的 /src 資料夾中)

兩個解決方案在適當的 tsconfig 下都能運作(映射已按需要設定),它能運作,但我並不滿意。

在第一種情況下,問題出在檔案的更新上。重新編譯後它可以使用,所以不是很方便,因為它需要重啟 IE、重新編譯所有內容、複製所有內容,這花費了很多時間。但它能用,或多或少。

第二個方案比較好,但我被指責專案結構混亂且奇怪(這是我從頭就知道的,我自己也不喜歡)。

所以我對這個問題深入研究了一些,並提出了虛擬目錄的解決方案。現在,專案結構符合標準的 C# 專案結構,可以在 IE11 及外部的 Chrome 上進行除錯(使用 IIS Express 並且是在相同的 localhost:port),同時也可以正確使用「保存時編譯」,包括例如 CSS 修改和頁面重新加載,而不需要重建和重新啟動 IE。

這可以手動完成(不使用額外的腳本),也可以透過後置建置腳本自動完成,無論是在 IIS Express(.vs/config/application.host)還是 IIS 上(到目前為止我還沒使用過完整的 IIS,但我很確定可以透過命令行自動化它)。如果你不會經常操作專案,我會說手動更新 IIS/applicationhost.config 檔案就足夠,而且效果很好(當然,前提是 tsconfig 設定正確以生成 map 檔案並為你的 TS 檔案設置 sourceRoot)。

   Search for the 
   .vs/config/applicationhost.config -> <system.applicationHost> -> <sites> -> <site name="YOUR-STARTUP-PROJECT">
   for each project in the solution add\
   <virtualDirectory path="/src/YourSoultionProject1Name" physicalPath="C:\...PATH-TO-YOUR-PROJECT-ROOT-FOLDER-ON-DISK">

對於每個專案,也不要忘記將 tsconfig 檔案的 sourceRoot 選項設置為 /src/YOUR_PROJECT_NAME(或在專案屬性中配置 ts 編譯器)

這是我到目前為止找到的最佳解決方案。唯一的問題是 .vs 是與使用者相關的,通常不會轉移到版本庫,因此每個使用者都必須自行設置。這也是我提出以下解決方案的原因之一(除此之外還有其他原因)。

我決定創建額外的 - 建立 - 專案,雖然一開始我想避免,但它將允許我做到:

  • 在開啟或建置專案後,自動根據解決方案中的專案設置虛擬目錄
  • 根據解決方案配置(Debug/Release)和專案內容建立 wwwroot。這包括:

    • 處理 LESS/SASS
    • 縮小 JS/CSS/HTML
    • 生成 cache.manifest 以支援離線應用程式
  • 從 Visual Studio 在 IE 中調試或在 Chrome 外部調試
  • 像平常一樣將網頁專案發佈到 Azure
  • 清理 wwwroot 和例如 js 資料夾
  • 監控解決方案中任何專案的任何檔案變更,並將變更應用到目標檔案,而無需重新編譯(基於 gulp watch)

我幾乎完成了,完成後我會在這裡放上連結,讓你了解我是如何進行的。

它如何運作(這會寫在自述文件中,但現在先簡短說明):

目前,我在解決方案中有 6 個專案,其中 5 個是具有適當 tsconfig 和/或 HTML/LESS/SASS/CSS/JSON/IMG 資源的「真正」TypeScript 代碼。

所有專案都是基於「HTML 應用程式與 TypeScript」範本。我在建立後已經移除了它們的所有內容(包括 web.config),所以它們現在只包含我的檔案。我也設定了專案之間的參考,以便可以遵循所需的建置順序。所有 TypeScript 專案會將 TS 編譯到所屬專案的 bin 資料夾(我的 tsconfig 直接編譯器設定為只產生一個單一的 js 檔案,但對多個檔案也適用)(包括 map 檔案和 d.ts,如果需要)。其他專案則在 tsconfig 中透過相對路徑(../libproject/bin/lib./d.ts)參考其他專案 bin 資料夾中的 d.ts。

我嘗試將其複製到依賴項目,就像 C# 那樣。這有效,但要讓它正確運作需要更多的工作和時間(包括清理。後置構建事件並不理想)。

第六個專案是「build」和啟動專案,所以它不包含任何「真正的」程式碼(除了我需要的構建工具)。它基於 gulp 和我寫的一些用於讀取解決方案/專案資訊和配置的腳本。

它還會從每個專案讀取我的自訂設定,這些設定正在控制 wwwroot 的建置過程。最後,它會從解決方案專案複製/處理(最小化)資源到這個建置/啟動專案。

我希望我明天能完成第一個版本並將其發佈到 GitHub,這樣你就可以查看它,並最終至少使用部分代碼。你需要安裝 node.js。