何為nuget,該如何使用,和2.7版本之後建議的回覆nuget package(套件)的方式

第一次接觸.Net開發的人常常會聽到一個名詞,那就是nuget。而習慣nuget的開發者通常也會常說,「你就用nuget去裝xxx套件就好了」。

可是,常常會忽略掉非.Net開發者其實聽不太懂這個術語。在這篇,我希望能夠可以給新進的.net開發者,能夠瞭解什麼是nuget,為什麼要用nuget,nuget產生的什麼 東西應該進入版控,和最重要的建議回覆nuget package的方式(網路上面很多教學都是舊版本的做法)

第一次接觸.Net開發的人常常會聽到一個名詞,那就是nuget。而習慣nuget的開發者通常也會常說,「你就用nuget去裝xxx套件就好了」。

可是,常常會忽略掉非.Net開發者其實聽不太懂這個術語。在這篇,我希望能夠可以給新進的.net開發者,能夠瞭解什麼是nuget,為什麼要用nuget,nuget產生的什麼 東西應該進入版控,和最重要的建議回覆nuget package的方式(網路上面很多教學都是舊版本的做法)

何為nuget

nuget其實就是一個中央的資源版本儲存庫,每一個資源稱之為package(套件)。每一個package都有不同版本。

這邊我用資源兩個字,因為雖然大部份大家都是用它來管控專案用到的library,但是其實nuget也可以放一些程式, 例如7zip。

如果和別的程式語言比較,nuget就如同Java的Maven,nodeJS的npm,Ruby的Gems。

如果用安裝軟體的角度,nuget就類似Linux世界的Package Management。

nuget其實是一個open source的project(Github)。其中主要兩個部份,client端和server端。

nuget都有存在什麼資源

大家第一個映像都是nuget就是一些C# library,但是其實nuget放什麼都可以。library是最常見的,但是也有一些package其實就是一個可執行的程式。例如7zip,或一些unit test的console程式,這些類型的package可以方便在做一些自動化(Automation例如Continus Integration和Continus Delivery)的時候,環境設定變得更加簡單。

nuget也有一些特殊的library,像是各個的unit test framework的Test Adapter也可以用nuget安裝。以前,要在Visual Studio直接執行第三放的unit test framework(例如NUnit),開發者都需要傳Visual Studio的Extension才可以做到,現在因為Visual Studio的調整,只要透過nuget裝Test Adapter就可以,新的開發環境不需要記得Visual Studio要裝個Extension就可以跑測試。

也有一些變形的使用

像是 Chocolatey (微軟版本的apt-get)和 Powershell Gallery (Powershell module集中地)其實都是nuget的同分支出來的服務。

Nuget詞不同含義

需要注意,在不同情境下面,nuget可能有不同含義。總共兩種情況:
  1. 程式本身 - 有時候提到nuget指的是package management這個程式
  2. 微軟預設的package來源 - 因為nuget server其實可以自己建制,有些服務項MyGet可以提供私人的nuget server。所以nuget有時候指的是微軟預設提供的那個資源的Nuget Package的位置

為什麼要有nuget

nuget主要解決:

  1. 更好在不同專案之間使用同個package的不同版本
  2. 讓開發者或者做自動化建制的時候,能夠不用做任何事情專案就能夠執行
  3. 處理library之間的相依性。例如要用xxx需要有yyy,而且這個xxx和yyy還有可能有版本問題
  4. 升級library的版本

可以想像一下,在沒有nuget的時代。如果你想用一個第三方的library,通常做法是執行exe或者msi來把library裝到電腦的GAC。不過這個有幾個問題:

  1. 因為在GAC,如果別的開發者也要開發,但是他沒裝過怎麼辦?如果文件寫的好還可以參照文件知道要安裝,但是如果沒寫好呢?
  2. 如果同個library,在不同專案要使用不同版本,是不是要安裝好多個exe?
  3. 如果要把系統放到別的環境執行,每一次都要安裝library,如果文件沒寫好,安裝的人不知道呢?

這些問題,在nuget的到來都解決了。

nuget一些特性

  • nuget是跟著專案走 - 所以專案需要的package可以跟專案走
  • package之間的相依性會自動處理。例如,今天要裝一個Asp .net Mvc,nuget會自動連Json.Net也裝上,因為那個是其中一個相依
  • 這個專案裝了什麼package會在一個 package.config做記錄(.Net core用的名稱不同) - 當專建制的時候,如果package.config提到的package不存在的話,會自動下載package。

如何使用nuget

nuget有兩種使用方式:

  1. 用GUI
  2. 用Package Manager Console

1. 使用GUI

Visual Studio 2013 和 Visual Studio 2015的畫面不太一樣,但是操作都差不多。

在安裝的時候注意安裝到的專案其他就還蠻直覺。舉例今天安裝常用的Json.Net套件:

1.1 安裝package

右鍵點選專案,選擇 Mange Nuget Package(管理nuget套件)

打開nuget package manager

預設會選取左邊頁籤(VS 2015是上面)Online,這個時候可以在右上角的輸入框來輸入要搜索的套件。在確定安裝前,在上面的下拉選單可以切換是否接受 Pre Realse (預覽版)的版本。

VS 2013 安裝畫面
VS 2015 安裝畫面

可以看到VS 2015 的版本多上了可以選擇要安裝的Version,而2013只能夠裝最新版本。

1.2 刪除package

在頁籤的Installed裡面會列出目前有安裝的package,不要的直接點Uninstall即可。

VS 2013畫面
VS 2015畫面

1.3 更新package

VS 2013畫面
VS 2015畫面

在頁籤Update可以看到那些版本是可以更新的。在VS 2015更可以選擇要更新的版本(甚至降板)

2. Package Manager Console

開啟Package Manager Console

Package Manager Console 其實就是Powershell。透過這種方式安裝有兩個好處:

  1. 如果知道Package名稱 - 速度比較快。因為UI還要搜索
  2. 可以傳入參數。例如用--version來表示要安裝的版本,--force強制刪掉某一個package(忽略這個package的相依package) - 方便更新package版本

 

2.1 安裝package

基本上語法就是 Install-package {packageName}例如:

Install-Package Newtonsot.Json

2.2 刪除package

基本上語法就是 Uninstall-package {packageName}例如:

Uninstall-Package Newtonsot.Json

如何回覆package

基本上有3種做法:

  1. 對專案設定package restore - 2.7 之前的做法
  2. nuget 2.7 之後,什麼都不用做 - 建議做法
  3. 使用nuget.exe呼叫 nuget restore (在專案的資料夾下執行,會自動找到對應的sln並且回覆package)

做法1.:對專案設定package restore

在之前版本的nuget,要回覆nuget package需要做一些設定,並且把產生出來的.nuget資料夾要放到版控才可以。

這種做法有2個問題:

  1. 這個做法是在專案Build(建制)的時候 在回覆不存在的package。因為是在Build的時候做,所以第一次build會失敗,因為package還沒下載好。
  2. 版控要記錄.nuget資料夾

第一個問題比較嚴重,像之前我第一次接觸自動建制,就因為這個卡住。

因為這個原因,在nuget 2.7之後改變回覆package的做法。

如果看到這篇,請大家告訴大家,建議不要在用上面描述那種方式做nuget回覆

做法2.建議:nuget 2.7之後的做法 - 什麼都不用做

nuget 2.7之後的回覆方式就是:什麼都不需要做。沒錯,沒看錯,什麼都不需要做,只要建制,Visual Studio就會自己在 Build之前先把缺少的nuget package下載好。所以,如果有任何package需要在build的時候觸發,完全不會有問題。

什麼檔案應該進入版控

在官方建議的.gitignore設定是:

# 忽略 NuGet Packages
*.nupkg
# 忽略下載 packages 的資料夾 
**/packages/*
# 但是保留 build/ 資料夾, 用作於package的 MSBuild target.
!**/packages/build/
# 下面這行可有可無 - 就算沒有也會自動產生
#!**/packages/repositories.config
	

結語

希望透過這篇,可以讓從來沒有接觸nuget的使用者瞭解並且知道為什麼要使用nuget,瞭解nuget帶來的好處和如何在新版本回覆package。

今天介紹的是如何使用nuget,在未來在介紹如何建立一個nuget package,把各位常用的自己寫的package能夠透過nuget在不同專案方便使用。


Google+

創用 CC 授權條款
Alan Tsai 的隨手筆記Alan Tsai製作,以創用CC 姓名標示 4.0 國際 授權條款釋出。