使用 global.json 精準的選擇 .NET SDK 版本 | The Will Will Web

The Will Will Web

記載著 Will 在網路世界的學習心得與技術分享

使用 global.json 精準的選擇 .NET SDK 版本

我在 2018 年寫過一篇 如何在多個 .NET Core SDK 版本之間進行切換 (global.json) 文章,當時只說明了你如何選擇特定版本,沒有提到當有新版 .NET SDK 出現時,他會怎樣選擇版本。這篇文章我打算來補完這部分技術細節。

前情提要

首先,各位先看看我目前電腦的 .NET SDK 安裝情況,我從 .NET Core 3.1 到 .NET 6 Preview 都有安裝:

C:\NETSDK>dotnet --version
6.0.100-preview.4.21255.9

C:\NETSDK>dotnet --list-sdks
3.1.100 [C:\Program Files\dotnet\sdk]
3.1.115 [C:\Program Files\dotnet\sdk]
3.1.201 [C:\Program Files\dotnet\sdk]
3.1.301 [C:\Program Files\dotnet\sdk]
3.1.302 [C:\Program Files\dotnet\sdk]
3.1.402 [C:\Program Files\dotnet\sdk]
3.1.409 [C:\Program Files\dotnet\sdk]
5.0.104 [C:\Program Files\dotnet\sdk]
5.0.203 [C:\Program Files\dotnet\sdk]
5.0.300 [C:\Program Files\dotnet\sdk]
6.0.100-preview.4.21255.9 [C:\Program Files\dotnet\sdk]

在沒有 global.json 檔案的情況下,預設 .NET SDK 只會選擇目前的最新版本。

事實上,專案團隊中的每個人安裝的 .NET SDK 版本不盡相同,例如有的人安裝了 5.0.202 版,由些人則安裝了 5.0.203 版,那麼我們的 global.json 應該設定哪個版本才好呢?答案是:設定主要版本的第一版! 例如:3.1.1005.0.100 等等。

假設我就在我的電腦執行以下命令,建立 global.json 檔案:

dotnet new globaljson --sdk-version 5.0.100
{
  "sdk": {
    "version": "5.0.100"
  }
}

由於我的電腦並沒有 5.0.100 版本,所以當我執行 dotnet --version 我會得到 5.0.104 這個版本:

G:\NETSDK>dotnet new globaljson --sdk-version 5.0.100
The template "global.json file" was created successfully.

G:\NETSDK>type global.json
{
  "sdk": {
    "version": "5.0.100"
  }
}
G:\NETSDK>dotnet --version
5.0.104

這也意味著著:【當 .NET SDK 無法透過 global.json 找到相對應版本時,它會自動找出往後最新的主要 SDK 版本

如果你設定的 .NET SDK 版本在開發者的電腦有安裝的話,就會直接選擇特定版本。

認識 .NET SDK 的版本定義

我以 3.1.115 版本為例,這個版號可以區分成以下幾種:

  1. 主要版本 (Major)

    3
    

    版號第一段的數字。

  2. 次要版本 (Minor)

    1
    

    版號第二段的數字。

  3. 功能版本 (Feature)

    1
    

    版號第三段的第一個數字。

  4. 修補版本 (Patch)

    15
    

    版號第三段的最後兩個數字。

如何更佳精準的控制 .NET SDK 選用版本

為了能夠更精準的控制版本的跳躍,以下我用 .NET Core 3.1 來當示範整個步驟。

  1. 建立 global.json 選用 .NET Core SDK 3.1.100 版本

    dotnet new globaljson --sdk-version 3.1.100
    
    {
      "sdk": {
        "version": "3.1.100"
      }
    }
    

    因為我的電腦正好有安裝 3.1.100 這個 .NET SDK 版本,此時你用 dotnet --version 會得到 3.1.100 版本!

  2. 我們將 global.json 加入 sdk.rollForward 屬性,並設定為 latestPatch

    {
      "sdk": {
        "version": "3.1.100",
        "rollForward": "latestPatch"
      }
    }
    

    此時你會發現,因為定義 sdk.rollForward 屬性為 latestPatch 的關係,我們用 dotnet --version 會得到 3.1.115 版本!

  3. 我們將 global.jsonsdk.rollForward 屬性修改為 latestFeature

    {
      "sdk": {
        "version": "3.1.100",
        "rollForward": "latestFeature"
      }
    }
    

    此時你會發現,因為定義 sdk.rollForward 屬性為 latestFeature 的關係,我們用 dotnet --version 會得到 3.1.409 版本!

  4. 我們將 global.jsonsdk.rollForward 屬性修改為 latestMinor

    {
      "sdk": {
        "version": "3.1.100",
        "rollForward": "latestMinor"
      }
    }
    

    因為我們並沒有 3.2 版可用,定義 sdk.rollForward 屬性為 latestMinor 將會與 latestFeature 的結果一模一樣,我們用 dotnet --version 會得到 3.1.409 版本!

  5. 我們將 global.jsonsdk.rollForward 屬性修改為 latestMajor

    {
      "sdk": {
        "version": "3.1.100",
        "rollForward": "latestMajor"
      }
    }
    

    因為定義 sdk.rollForward 屬性為 latestMajor 的關係,我們用 dotnet --version 會得到 6.0.100-preview.4.21255.9 版本!

    請注意!上述設定直接讓 .NET SDK 跳到最新預覽版了,如果你只希望套用到最新穩定版的話,可以調整設定如下:

    {
      "sdk": {
        "version": "3.1.100",
        "rollForward": "latestMajor",
        "allowPrerelease": false
      }
    }
    

    這個也是我最喜歡的 globaljson 設定值!

  6. 我們將 global.jsonsdk.rollForward 屬性修改為 disable

    {
      "sdk": {
        "version": "3.1.100",
        "rollForward": "disable"
      }
    }
    

    因為定義 sdk.rollForward 屬性為 disable 的關係,我們用 dotnet --version 會得到 3.1.100 版本!

    注意:使用 disable 設定後,如果開發人員沒有安裝確切的指定版本, 完全無法使用 .NET SDK 了!

以上這幾個就很夠用了,其他的就沒有很重要。

使用 * (萬用字元) 標示版本

如果你在 global.json 使用 * (萬用字元) 標示版本的話,如下:

{
  "sdk": {
    "version": "3.1.*",
    "rollForward": "latestMajor",
    "allowPrerelease": false
  }
}

不管你設定什麼版本,任何無效的版本對 .NET SDK 來說,就等同於這份 global.json 不存在一樣。只要這份 global.json 的 JSON 格式正確,基本上 .NET SDK 執行的時候就不會報錯,所以你寫這樣也是會過的:

{
  "sdk": {
    "version": "3.1.100",
    "rollForward": "latestWhatever",
    "allowPrerelease": false
  }
}

既然都視為不存在,.NET SDK 就會自動選擇目前的最新主要、次要、功能、修補版本,反正是最新版就對了!

所以上述的兩種錯誤設定,由於執行 .NET SDK 的工具時都不會報錯,所以很有可能會讓你覺得這是應該是正確的設定,各位要千萬小心,不要自己腦補邏輯進去。

你可以用 dotnet --version 測試看看,錯誤的設定將會得到 6.0.100-preview.4.21255.9 版本! 🔥

相關連結