這年頭用Visual Studio寫程式已經離不開NuGet了!NuGet會在每個專案新増packages.config記錄已安裝Package及版本,在解決方案(.sln)檔所在資料夾則會建立packages保存各專案的NuGet Package DLL實體,放在解決方案層級的好處是方便Package檔案共享,專案A裝過NLog,專案B要安裝NLog時就不需要重新下載,直接參照packages裡的nlog.dll就好。除了packages目錄,如果選擇Enable NuGet Package Restore,還會再多一個.nuget資料夾,裡面有NuGet.exe、NuGet.config、NuGet.targets,方便建置時自動由NuGet補足缺少的Package。(但此點不適用Web Site Project)
使用NuGet Package Restore可減少原始碼傳送及封存時的資料量。packages資料夾包含大量dll檔,容量常常高達數百MB,啟用Package Restore後,packages不需隨原始碼打包,對方可在建置專案時再由NuGet即時下載安裝。
「packages跟.nuget資料夾該不該進版控?」的問題困擾我好一陣子了,之前沒掌握底層運作的眉角,常被一些「靈異現象」整得七葷八素,直到累積一些心得後,才有較具備的概念!(老話一句,會覺得「暗!見鬼了」多半是因為了解不夠透徹,線索掌握不足所致,真相大白後便會驚覺一切都符合科學邏輯,電腦永遠是死板板照指令辦事,從不背叛任何人。相較於江湖事,單純豈止十萬倍? XD)
packages進版控跟不進版控實務上都可行,但屬兩種不同策略,實踐時一些細節要到位,不然會搞到你欲哭無淚。
策略一:packages不進版控
記得要開啟Enable NuGet Package Restore選項,並確認packages目錄沒有簽入TFS。之前遇過案例:package被誤簽入TFS,但預設dll、exe檔案型別不會簽入。因此TFS版控空有packages各Package的完整目錄結構,獨缺最重要的dll檔。另一位同事取得最新版本編譯專案,NuGet試著還原Package,發現該Package版本的目錄已存在於packages,便認定已下載略過還原程序。結局是專案依循參數路徑找不到dll,若不是直接報錯,就是靠Visual Studio顯神通找到自以為合用的dll頂替,搞出靈異現象。
方法二:packages進版控
如果想避免重複下載Package,或是建置環境無法連上NuGet,則可選擇將packages全部簽入TFS版控。如此另一方在取得最新版原始碼時,所需NuGet Package dll檔一併就位,直接編譯即可,不需再花功夫下載。
但有幾點要注意:
- 如果已Enable NuGet Package Restore,.nuget資料夾也要簽入
新版NuGet會在csproj中加入以下檢查,Visual Studio能自動補上.nuget資料夾,但使用MSBuild編譯時便會因.nuget不存在而出錯。<TargetName="EnsureNuGetPackageBuildImports"BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on
this computer. Enable NuGet Package Restore to download them. For more
information, see http://go.microsoft.com/fwlink/?LinkID=322105.
The missing file is {0}.
</ErrorText>
</PropertyGroup>
<ErrorCondition="!Exists('$(SolutionDir)\.nuget\NuGet.targets')"
Text="$([System.String]::Format('$(ErrorText)', '$(SolutionDir)\.nuget\NuGet.targets'))"/>
</Target>
- 簽入.nuget、packages時要確認有包含dll及exe
預設TFS在簽入資料夾時將排除exe及dll,要記得將它們從排除清單(Excluded items)再拉回來。 - NuGet Package新増或升級時記得簽入TFS
由於不再依賴NuGet自動補檔與升級,Package如有異動記得要簽入