使用 Visual Studio 發佈帶有預設檔案的 NuGet 套件
TLDR
- 開發 NuGet 套件時,若需包含預設設定檔,建議使用
.NET Standard作為專案目標平台。 - 現代 NuGet 套件開發已不需額外撰寫
.nuspec檔案,直接在.csproj中設定即可。 install.ps1僅適用於使用package.config的舊版專案,在PackageReference模式下不會執行。- 若目標專案使用
PackageReference,套件內的檔案不會自動複製到專案目錄中,此為 NuGet 的設計限制。 - 支援舊版
.NET Framework專案時,建議在csproj中使用<TargetFrameworks>指定多目標框架。
NuGet 套件開發的專案設定
在開發 NuGet 套件時,建議選擇 .NET Standard 平台以確保跨平台支援。若需同時支援舊版 .NET Framework,可在專案檔中設定多目標框架。
什麼情況下會遇到這個問題:當你需要開發一個同時支援新舊專案的套件,且需要處理不同框架的相容性時。
在 .csproj 中設定多目標框架的範例:
xml
<PropertyGroup>
<TargetFrameworks>netstandard2.1;netstandard2.0;net45</TargetFrameworks>
</PropertyGroup>針對套件資訊的設定,直接在 .csproj 內定義即可,無需額外的 .nuspec 檔案:
xml
<PropertyGroup>
<AssemblyName>LibrarySample</AssemblyName>
<Authors>Wing</Authors>
<Version>0.0.1</Version>
<Description>測試用</Description>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
</PropertyGroup>發佈帶有預設檔案的套件
若要在套件中包含預設檔案(如 Config.json)並在安裝時自動處理,需在 .csproj 中進行配置。
什麼情況下會遇到這個問題:當你的套件需要提供預設設定檔範本,並希望使用者安裝後能直接在專案中看到該檔案。
專案檔配置方式
透過 <ItemGroup> 將檔案加入並設定打包路徑:
xml
<ItemGroup>
<Content Include=".\Config.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<PackageCopyToOutput>true</PackageCopyToOutput>
</Content>
<None Include=".\install.ps1">
<Pack>True</Pack>
<PackagePath>tools</PackagePath>
</None>
</ItemGroup>關於 install.ps1 的限制
install.ps1僅在package.config模式下會被執行。- 若目標專案使用
PackageReference(如 ASP.NET Core 或現代 .NET 專案),install.ps1不會執行,且檔案不會自動複製到專案目錄中。 - 即使是
.NET Framework專案,若改用PackageReference,同樣無法觸發install.ps1或自動複製檔案。
WARNING
NuGet.org 只接受開放原始碼方案或免費軟體基礎核准的授權運算式。若使用其他授權,請使用 PackageLicenseFile 指定授權檔案路徑。
發佈與驗證結果
完成設定後,對專案點擊右鍵選擇「套件 (Pack)」即可產生 .nupkg 檔案。
什麼情況下會遇到這個問題:當你需要將開發好的套件發佈至 NuGet Server(如 NuGet.org 或私有伺服器)供他人使用時。
發佈步驟
- 確保組態設定為
Release模式。 - 執行打包後,於
bin/Release目錄下取得.nupkg檔案。 - 若使用 NuGet.org,可直接透過網頁介面上傳;若為私有伺服器,請使用
nuget push指令。
驗證觀察
- package.config 模式:安裝時會執行
install.ps1,檔案會正確複製至專案目錄,並設定為「內容」與「有更新才複製」。 - PackageReference 模式:不會執行
install.ps1,且檔案不會自動複製至專案目錄。這是 NuGet 目前的設計行為,開發者應在套件說明中告知使用者需手動建立設定檔,或透過程式碼在執行時期處理預設值。
異動歷程
- 2022-11-08 初版文件建立。
