無論您的套件執行什麼動作或包含什麼程式碼,您都會使用其中一個 CLI 工具 ( nuget.exe 或 dotnet.exe) 將該功能封裝成可與任意數量的其他開發人員共用和使用的元件。 若要安裝 NuGet CLI 工具,請參閱 安裝 NuGet 用戶端工具。 請注意,Visual Studio 不會自動包含 CLI 工具。
針對非 SDK 樣式專案,通常是 .NET Framework 專案,請遵循本文中所述的步驟來建立套件。 如需使用 Visual Studio 和
nuget.exeCLI 的逐步指示,請參閱 建立和發佈 .NET Framework 套件。如需使用 SDK 樣式格式的 .NET Core 和 .NET Standard 專案,以及任何其他 SDK 樣式專案,請參閱 使用 dotnet CLI 建立 NuGet 套件。
針對從
packages.config遷移至 PackageReference 的專案,請使用 msbuild -t:pack。
從技術上講,NuGet 套件只是已使用副檔名重新 .nupkg 命名的 ZIP 檔案,而且其內容符合特定慣例。 本主題說明建立符合這些慣例的套件的詳細程序。
封裝會從您想要以套件形式傳遞的編譯程式碼 (元件)、符號和/或其他檔案開始 (請參閱概 觀和工作流程)。 此過程與用於生成進入套件的檔案的編譯無關,不過您可以利用專案檔中的資訊,保持編譯的程序集和套件同步。
這很重要
本主題適用於非 SDK 樣式專案,通常是使用 Visual Studio 2017 和更新版本和 NuGet 4.0+ 的 .NET Core 和 .NET Standard 專案以外的專案。
決定要封裝的組件
大部分的一般用途套件都包含一或多個元件,其他開發人員可以在自己的專案中使用。
一般而言,最好每個 NuGet 套件都有一個元件,前提是每個元件都獨立有用。 例如,如果您有一個
Utilities.dll相依於Parser.dll,而Parser.dll本身很有用,那麼為每個項目建立一個套件。 這樣做可讓開發人員使用Parser.dll而不依賴Utilities.dll。如果您的程式庫是由多個沒有獨立用處的元件所組成,則可以將它們合併成一個套件。 根據上一個範例,如果
Parser.dll包含只被Utilities.dll使用的程式碼,那麼保留Parser.dll在相同的套件中是可行的。同樣,如果
Utilities.dll依賴於Utilities.resources.dll,而後者本身又沒有用處,那麼將兩者放在同一個包中。
事實上,資源是一個特例。 將套件安裝到專案中時,NuGet 會自動將元件參考新增至套件的 DLL,但不包括 被命名為 .resources.dll 且被視為當地語系化衛星組件的那些(請參閱 建立當地語系化套件)。 因此,請避免將 .resources.dll 用於包含基本套件程式碼的檔案。
如果您的程式庫包含 COM 互通元件,請遵循使用 COM 互通元件建立套件中的其他指導方針。
.nuspec 檔案的角色和結構
知道要封裝哪些檔案後,下一步就是在 XML 檔案中 .nuspec 建立套件資訊清單。
清單:
- 描述套件的內容,並本身包含在套件中。
- 驅動套件的建立,並指示 NuGet 如何將套件安裝到專案中。 例如,資訊清單會識別其他套件相依性,讓 NuGet 也可以在安裝主要套件時安裝這些相依性。
- 包含必要和選擇性屬性,如下所述。 如需確切的詳細資料,包括此處未提及的其他屬性,請參閱 .nuspec 參考。
必要屬性:
- 套件識別碼,在裝載套件的資源庫中必須是唯一的。
- Major.Minor.Patch[-Suffix] 格式的特定版本號碼,其中 -Suffix 會識別發行前版本
- 主機上應顯示的套件標題 (如 nuget.org)
- 作者和所有者信息。
- 包裝的詳細描述。
常見的可選屬性:
- 發布說明
- 版權信息
- Visual Studio 中套件管理員 UI 的簡短描述
- 地區設定識別碼
- 專案網址
- 授權可以是表達式或檔案(
licenseUrl已被棄用,請改用licensenuspec 中的中繼資料元素) - 圖示檔案 (
iconUrl已棄用,請改用iconnuspec metadata 元素 ) - 相依性及參考資料清單
- 協助圖庫搜尋的標籤
以下是典型 (但虛構) .nuspec 檔案,其中包含描述屬性的註解:
<?xml version="1.0"?>
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<metadata>
<!-- Identifier that must be unique within the hosting gallery -->
<id>Contoso.Utility.UsefulStuff</id>
<!-- Package version number that is used when resolving dependencies -->
<version>1.8.3</version>
<!-- Authors contain text that appears directly on the gallery -->
<authors>Dejana Tesic, Rajeev Dey</authors>
<!--
Owners are typically nuget.org identities that allow gallery
users to easily find other packages by the same owners.
-->
<owners>dejanatc, rjdey</owners>
<!-- Project URL provides a link for the gallery -->
<projectUrl>http://github.com/contoso/UsefulStuff</projectUrl>
<!-- License information is displayed on the gallery -->
<license type="expression">Apache-2.0</license>
<!-- Icon is used in Visual Studio's package manager UI -->
<icon>icon.png</icon>
<!--
If true, this value prompts the user to accept the license when
installing the package.
-->
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<!-- Any details about this particular release -->
<releaseNotes>Bug fixes and performance improvements</releaseNotes>
<!--
The description can be used in package manager UI. Note that the
nuget.org gallery uses information you add in the portal.
-->
<description>Core utility functions for web applications</description>
<!-- Copyright information -->
<copyright>Copyright ©2016 Contoso Corporation</copyright>
<!-- Tags appear in the gallery and can be used for tag searches -->
<tags>web utility http json url parsing</tags>
<!-- Dependencies are automatically installed when the package is installed -->
<dependencies>
<dependency id="Newtonsoft.Json" version="9.0" />
</dependencies>
</metadata>
<!-- A readme.txt to display when the package is installed -->
<files>
<file src="readme.txt" target="" />
<file src="icon.png" target="" />
</files>
</package>
如需宣告相依性及指定版本號碼的詳細資訊,請參閱 packages.config 和 套件版本設定。 您還可以使用 dependency 元素上的 include 和 exclude 屬性,直接在套件中顯示來自相依性的資產。 請參閱 .nuspec 參考 - 相依性。
由於資訊清單包含在從中建立的套件中,因此您可以透過檢查現有的套件來尋找任意數量的其他範例。 一個好的來源是電腦上的 global-packages 資料夾,其位置由以下命令傳回:
nuget locals -list global-packages
進入任何 package\version 資料夾,將 .nupkg 檔案複製到檔案 .zip ,然後開啟該 .zip 檔案並檢查其中的檔案 .nuspec 。
備註
在從 Visual Studio 專案建立.nuspec時,資訊清單包含代幣,這些代幣在建置套件時會被取代為專案的相關資訊。 請參閱 從 Visual Studio 專案建立 .nuspec。
建立 .nuspec 檔案
建立完整的資訊清單通常從透過下列其中一種方法產生的基本 .nuspec 檔案開始:
然後,您可以手動編輯檔案,使其描述最終套件中您想要的確切內容。
這很重要
產生的 .nuspec 檔案包含預留位置,必須先修改這些預留位置,才能使用命令建立 nuget pack 套件。 如果 .nuspec 中包含任何預留位置,則該命令會失敗。
從慣例型工作目錄
因為 NuGet 套件只是一個已將副檔名改為 .nupkg 的 ZIP 壓縮檔案,因此通常最簡單的方式是在本機檔案系統上設計出您想要的資料夾結構,然後直接從該結構中創建 .nuspec 檔案。 然後,指令 nuget pack 會自動新增該資料夾結構中的所有檔案 (不包括任何以 開 .頭的資料夾,可讓您將私人檔案保留在同一結構中)。
此方法的優點是,您不需要在資訊清單中指定要包含在套件中的檔案 (如本主題稍後所述) 。 您可以簡單地讓建置程式產生進入套件的確切資料夾結構,而且您可以輕鬆地包含其他可能不屬於專案一部分的檔案:
- 應注入目標專案的內容和原始程式碼。
- PowerShell 腳本
- 變更專案中現有的組態和原始程式碼檔案。
資料夾慣例如下:
| 資料夾 | Description | 套件安裝時的動作 |
|---|---|---|
| (root) | readme.txt 地點 | 安裝套件時,Visual Studio 會在套件根目錄中顯示 readme.txt 檔案。 |
| lib/{tfm} | 指定目標架構名稱(TFM)的組件(.dll)、文件(.xml)和符號檔案(.pdb) |
元件會新增為編譯及執行階段的參考,並且 .xml 和 .pdb 會被複製到專案資料夾中。 請參閱 支援多個目標架構, 以建立架構目標特定的子資料夾。 |
| 參考/{TFM} | 指定目標架構名稱(TFM)的元件(.dll)和符號(.pdb)檔案 |
元件只會在編譯階段新增為參考;因此,不會將任何內容複製到專案 bin 資料夾中。 |
| runtimes | 架構特定的元件 (.dll)、符號 (.pdb) 和原生資源 (.pri) 檔案 |
在執行階段中,元件僅會新增為參考;而其他檔案則會被複製到專案資料夾中。 在/ref/{tfm}資料夾下應該一律有對應的 (TFM) 特定組件,以提供對應的編譯時組件。 請參閱 支援多個目標架構。 |
| 內容 | 任意檔案 | 內容會複製到專案根目錄。 將 內容 資料夾視為最終取用套件的目標應用程式根目錄。 若要讓套件在應用程式的 /images 資料夾中新增影像,請將它放在套件的 content/images 資料夾中。 |
| 組建 |
(3.x+) MSBuild .targets 和 .props 檔案 |
自動插入到專案中。 |
| 建置多目標支持 |
(4.0+) MSBuild .targets 和 .props 跨架構目標的檔案 |
自動插入到專案中。 |
| buildTransitive |
(5.0+) MSBuild .targets 和 .props 檔案能以轉移依賴的方式流向任何使用專案。 請參閱功能頁面。 |
自動插入到專案中。 |
| 工具 | 可從套件管理員主控台存取的 Powershell 腳本和程式 |
tools資料夾只會新增至專供套件管理員主控台使用的PATH環境變數中,(具體來說,不會新增至建置專案時的 MSBuild 設定的PATH)。 |
因為您的資料夾結構可以包含任意數目目標架構的任意數目元件,所以在建立支援多個架構的套件時,需要這個方法。
在任何情況下,一旦您擁有所需的資料夾結構,請在該資料夾中執行以下命令來建立 .nuspec 檔案:
nuget spec
同樣地,生成的.nuspec 不含有對資料夾結構中的檔案的明確參考。 NuGet 在建立套件時會自動包含所有檔案。 不過,您仍然需要編輯資訊清單其他部分的佔位符值。
從元件 DLL
在從組件建立套件的簡單案例中,您可以使用下列命令從組件中的中繼資料產生 .nuspec 檔案:
nuget spec <assembly-name>.dll
使用此表單可將資訊清單中的幾個預留位置,以元件中特定的值取而代之。 例如, <id> 內容會設定為組合名稱,並 <version> 設定為組合版本。 不過,資訊清單中的其他屬性在元件中沒有相符的值,因此仍包含預留位置。
從 Visual Studio 專案
從.nuspec或.csproj檔案建立.vbproj是很方便的,因為安裝到這些專案中的其他套件會自動被參照為相依。 只需在與專案檔案相同的資料夾中使用以下命令:
# Use in a folder containing a project file <project-name>.csproj or <project-name>.vbproj
nuget spec
產生的 <project-name>.nuspec 檔案包含 標記,這些標記在打包時會被專案中的值取代,包括對已安裝的其他套件的參照。
如果您有要包含在 .nuspec 中的套件相依性,請改用 nuget pack,並從產生的 .nupkg 檔案中取得 .nuspec 檔案。 例如,使用下列命令。
# Use in a folder containing a project file <project-name>.csproj or <project-name>.vbproj
nuget pack myproject.csproj
記號由專案屬性兩側的 $ 符號隔開。 例如, <id> 以這種方式產生的資訊清單中的值通常如下所示:
<id>$id$</id>
此符號會在封裝時被專案檔中的AssemblyName值取代。 如需專案值與.nuspec 權杖的確切對應,請參閱替換權杖參考。
代幣可讓您在更新專案時,無需更新重要值,例如版本號碼 .nuspec。 (如有需要,您始終可以將記號替換為文字值)。
請注意,從 Visual Studio 專案工作時,還有數個其他封裝選項可供使用,如稍後 執行 nuget pack 以產生 .nupkg 檔案 中所述。
解決方案層級套件
僅適用於 NuGet 2.x 無法在 NuGet 3.0+ 中使用。
NuGet 2.x 支援解決方案層級的套件概念,這類套件會安裝套件管理員主控台的工具或額外命令(位於 tools 資料夾的內容),但不會將任何參考、內容或組建自定義新增到解決方案中的專案。 這類套件在其直接 lib、 content或 build 資料夾中不包含任何檔案,且其相依性在各自 lib的 、 content或 build 資料夾中都沒有檔案。
NuGet 會在 .nuget 資料夾中的 packages.config 檔案中追蹤已安裝的解決方案層級套件,而不是在專案的 packages.config 檔案中。
具有預設值的新檔案
下列命令會建立具有預留位置的預設資訊清單,以確保您從正確的檔案結構開始:
nuget spec [<package-name>]
如果您省略 <package-name>,則產生的檔案是 Package.nuspec。 如果您提供 Contoso.Utility.UsefulStuff名稱,例如 ,則檔案是 Contoso.Utility.UsefulStuff.nuspec。
結果的 .nuspec 包含像 projectUrl 這樣的值的預留位置。 在使用該檔案來創建最終 .nupkg 檔案之前,請務必先編輯它。
選擇唯一的套件識別碼並設定版本號碼
套件識別碼 (<id> 元素) 和版本號碼 (<version> 元素) 是資訊清單中最重要的兩個值,因為它們會唯一識別套件中包含的確切程式碼。
套件識別碼的最佳實務:
-
唯一性:識別碼必須在 nuget.org 或裝載套件的任何資源庫中是唯一的。 在決定識別碼之前,請搜尋適用的圖庫以檢查該名稱是否已在使用中。 為了避免衝突,一個好的模式是使用您的公司名稱作為識別碼的第一部分,例如
Contoso.。 -
類似命名空間的名稱:遵循類似 .NET 中命名空間的模式,使用點表示法而不是連字號。 例如,使用
Contoso.Utility.UsefulStuff而不是Contoso-Utility-UsefulStuff或Contoso_Utility_UsefulStuff。 當套件識別碼符合程式碼中使用的命名空間時,取用者也發現它很有幫助。 -
範例套件:如果您產生示範如何使用另一個套件的範例程式碼套件,請作為字尾附加
.Sample至識別碼,如Contoso.Utility.UsefulStuff.Sample所示。 (範例套件當然會相依於另一個套件。建立範例套件時,請使用先前所述的慣例型工作目錄方法。 在content資料夾中,將範例程式碼安排到名為\Samples\<identifier>的資料夾,如同\Samples\Contoso.Utility.UsefulStuff.Sample一樣。
套件版本的最佳做法:
- 一般而言,請設定套件的版本以符合程式庫,但這並非絕對必要。 當您將封裝限制為單一組件時,這是一件簡單的問題,如先前 決定要封裝的組件中所述。 整體而言,請記住,NuGet 本身在解析相依性時會處理套件版本,而不是元件版本。
- 使用非標準版本配置時,請務必考慮 NuGet 版本設定規則,如 套件版本設定中所述。
以下一系列簡短的部落格文章也有助於了解版本控制:
新增說明文件和其他文件
若要直接指定要包含在套件中的檔案,請使用
<?xml version="1.0"?>
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<metadata>
<!-- ... -->
</metadata>
<files>
<!-- Add a readme -->
<file src="readme.txt" target="" />
<!-- Add files from an arbitrary folder that's not necessarily in the project -->
<file src="..\..\SomeRoot\**\*.*" target="" />
</files>
</package>
小提示
使用慣例型工作目錄方法時,您可以將 readme.txt 放在套件根目錄中,並將其他內容放在資料夾中 content 。 資訊清單中不需要任何 <file> 元素。
當您包含套件根目錄中命名 readme.txt 的檔案時,Visual Studio 會在直接安裝套件之後立即將該檔案的內容顯示為純文字。 對於安裝作為依賴項的套件,Readme 檔案不會顯示。 例如,HtmlAgilityPack 套件的自述文件顯示如下:
備註
如果您在.nuspec檔案中包含空的<files>節點,NuGet 不會在套件中包含除了lib資料夾以外的任何其他內容。
在套件中包含 MSBuild props 和目標項目
在某些情況下,您可能想要在取用套件的專案中新增自訂建置目標或屬性,例如在建置期間執行自訂工具或程序。 您可以在 NuGet 套件中深入瞭解 MSBuild props 和目標
在專案的建置資料夾中建立 <package_id>.targets or <package_id>.props (例如 Contoso.Utility.UsefulStuff.targets)。
在 .nuspec 檔案中,請務必參考位於 <files> 節點的這些檔案:
<?xml version="1.0"?>
<package >
<metadata minClientVersion="2.5">
<!-- ... -->
</metadata>
<files>
<!-- Include everything in \build -->
<file src="build\**" target="build" />
<!-- Other files -->
<!-- ... -->
</files>
</package>
將套件新增至專案時,NuGet 會自動包含這些屬性和目標。
執行 nuget pack 以產生 .nupkg 檔案
使用元件或慣例型工作目錄時,請使用您的nuget pack檔案,透過執行.nuspec來建立套件,並將<project-name>替換為您特定的檔案名稱:
nuget pack <project-name>.nuspec
使用 Visual Studio 專案時,利用專案檔案執行 nuget pack,這會自動載入專案的 .nuspec 檔案,並使用專案檔中的值取代其中的任何標記:
nuget pack <project-name>.csproj
備註
直接使用專案檔是權杖取代的必要條件,因為專案是權杖值的來源。 當您將nuget pack與.nuspec檔案一同使用時,權杖置換不會發生。
在所有情況下, nuget pack 都會排除以句點開頭的資料夾,例如 .git 或 .hg。
NuGet 指出檔案中 .nuspec 是否有任何需要更正的錯誤,例如忘記變更資訊清單中的預留位置值。
完成 nuget pack 後,您將擁有一個 .nupkg 檔案,您可以按 發佈套件中的說明發佈至合適的畫廊。
小提示
在建立套件之後檢查套件的實用方法是在 [套件總管 ] 工具中開啟它。 這可讓您以圖形方式檢視套件內容及其資訊清單。 您也可以將產生的 .nupkg 檔案重新命名為檔案 .zip 並直接探索其內容。
其他選項
您可以使用各種命令列參數 nuget pack 來排除檔案、覆寫資訊清單中的版本號碼,以及變更輸出資料夾等功能。 如需完整清單,請參閱 pack 指令參考。
下列選項是 Visual Studio 專案常見的一些選項:
參考專案:如果專案參考其他專案,您可以使用以下
-IncludeReferencedProjects選項將參考專案新增為套件的一部分,或新增為相依性:nuget pack MyProject.csproj -IncludeReferencedProjects此併入處理程序是遞迴的,因此如果參照專案 B 和 C,而這些專案參照 D、E 和 F,則
MyProject.csproj來自 B、C、D、E 和 F 的檔案會包含在套件中。如果參考的專案包含
.nuspec自己的檔案,則 NuGet 會改為將該參考的專案新增為相依性。 您需要分別封裝和發佈該專案。組建組態:根據預設,NuGet 會使用專案檔中設定的預設組建組態,通常是 偵錯。 若要從不同的組建組態 (例如 Release) 封裝檔案,請搭配
-properties組態使用選項:nuget pack MyProject.csproj -properties Configuration=Release符號:若要包含允許取用者在偵錯工具中逐步執行套件程式碼的符號,請使用選項
-Symbols:nuget pack MyProject.csproj -symbols
測試套件安裝
在發佈套件之前,您通常會想測試將套件安裝到專案中的過程。 測試可確保必要的檔案最終都位於專案中的正確位置。
您可以使用一般 套件安裝步驟,在 Visual Studio 或命令列上手動測試安裝。
對於自動化測試,基本流程如下:
- 將
.nupkg檔案複製到本機資料夾。 - 使用命令
nuget sources add -name <name> -source <path>將資料夾新增至套件來源 (請參閱 nuget 來源)。 請注意,您只需在任何給定電腦上設定一次此本機來源。 - 使用
nuget sources中指定的來源名稱,透過nuget install <packageID> -source <name>來安裝該來源的套件,其中<name>應符合來源名稱。 指定來源可確保僅從該來源安裝套件。 - 檢查您的檔案系統,以檢查檔案是否已正確安裝。
後續步驟
建立套件 ( .nupkg 檔案) 之後,您可以將它發佈至您選擇的資源庫,如 發佈套件中所述。
您可能也想要擴充套件的功能,或以其他方式支援其他案例,如下列主題所述:
最後,還有其他套件類型需要注意: