2016年3月13日 星期日

何為nuget,該如何使用,和2.7版本之後建議的回覆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套件)

image

打開nuget package manager

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

imageVS 2013 安裝畫面
imageVS 2015 安裝畫面

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

1.2 刪除package

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

imageVS 2013畫面

8f46acf7-751f-44c3-9f40-f4a1313dd270

VS 2015畫面

1.3 更新package

imageVS 2013畫面
imageVS 2015畫面

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

2. Package Manager Console

image開啟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資料夾要放到版控才可以。

image

這種做法有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在不同專案方便使用。

沒有留言 :

張貼留言