﻿# 如何使用 Visual Studio Code 來取代難用的 Azure DevOps Wikis 線上編輯器

我們經常在 Azure DevOps Services 的專案中撰寫 Wiki 文件，但是 Azure DevOps 的 Wikis 線上編輯器實在是太難用了，我覺得還是在 VSCode 撰寫 Markdown 來的方便許多。除此之外，因為 Azure DevOps Wikis 可以放附件上去，但也不是所有檔案類型都支援，所以偶爾會遇到無法上傳附件的狀況。還有，你可能想要取回已經刪除的文件，但是從線上似乎沒有方法可以查閱這些文件。今天我打算用這篇文章來解決上述所有問題！

我曾經在 [如何建立與刪除 Azure DevOps 上面的 Project Wiki 文件庫](/post/2021/06/27/Create-and-Delete-Project-Wiki-from-Azure-DevOps) 這篇文章提到 Azure DevOps 上面的 Wikis 有兩種類型：

1.  **Project Wiki**
    
    每個專案只能有一個 Project Wiki
    
2.  **Code Wiki**
    
    所有 Wiki 文件會跟著 Azure Repos 中的**分支**一起管理。
    

本篇文章將會以 **Project Wiki** 為主，也是我們最常用的 Azure DevOps Wikis 使用方式。

### 將 Azure DevOps Wikis 視為 Git 儲存庫

其實 Azure DevOps 上面的 Project Wiki 背後，其實就是一個隱藏版的 Git 儲存庫 (Repository)，只是檯面上沒有講的很明白而已。

我以以下這個開源的 [AntiXss for .NET Standard 2.0](https://github.com/hangy/AntiXss) 專案為例，我將其專案建立了一個相對應的 Azure DevOps 專案，其 Wiki 文件在此：

> https://dev.azure.com/willh/AntiXss/\_wiki/wikis/AntiXss.wiki/24/Home

我們來比對一下 **Azure DevOps Wikis** 與 **Azure Repos** 的網址差異：

-   https://dev.azure.com/willh/AntiXss/\_wiki/wikis/AntiXss.wiki
-   https://dev.azure.com/willh/AntiXss/\_git/AntiXss

事實上，你只要把 Azure DevOps Wikis 的網址稍微改一下，把 `_wiki/wikis` 換成 `_git` 就可以取得 Azure DevOps Wikis 的 Git Repo 網址：

-   https://dev.azure.com/willh/AntiXss/\_git/AntiXss.wiki

所以，你是可以將整個專案的 Project Wiki 文件庫透過 Git 複製回來，預設分支名稱為 `wikiMaster` 或 `wikiMain`：

```bash
git clone https://dev.azure.com/willh/AntiXss/_git/AntiXss.wiki
cd AntiXss.wiki
code .
```

如此一來，你就可以改用 Visual Studio Code 來編輯整份 Wiki 文件了。不僅如此，由於這其實是一份完整的 Git 儲存庫，因此你可以直接在本機查閱完整的版本歷史紀錄，包含已經刪除的文件，都可以非常輕易的從 `git log` 歷史紀錄中找回，相當不錯！👍

### 從本地撰寫 Azure DevOps Wikis 文件的注意事項

雖然說你可以直接取得完整的 Project Wiki 文件庫，但是 Azure DevOps 的 Wiki 文件庫有一定的命名規定，如果不符合規定的話，該文件將不會正確顯示在 Azure DevOps 的 Wiki 文件庫中。

以下是我個人的使用經驗與建議：

1.  因為**頁面標題**等於**檔案名稱**，而檔案命名有許多限制，遇到無效字元該頁面就會被隱藏，因此：
    1.  盡量不要在 VSCode 新增頁面
    2.  盡量不要在 VSCode 修改**頁面標題**
2.  由於 Azure DevOps 只認單一分支(`wikiMaster` 或 `wikiMain`)，多人共同編輯文件時要注意衝突問題，所以：
    1.  修改前請先 `git pull --dry-run` 查看有無新版本
    2.  推送變更前請先 `git push --dry-run` 看會不會衝突
    3.  如果遭遇衝突，先考慮放棄現有變更，否則會蓋掉其他人的版本
    4.  有任何變更就隨時隨地 Commit/Push，避免單一分支出現衝突的狀況
3.  文件中所需**附件**請一律請放在根目錄下的 `.attachments` 目錄中
    1.  文件中的超連結請一律用 `/.attachments/` 作為啟始路徑
4.  在 Project Wikis 文件庫的**目錄名稱**就是**子頁面**名稱
    1.  例如 `Devs.md` 文件，同層目錄就會有個 `Devs` 資料夾，放在該資料夾的檔案就是 `Devs.md` 文件的「子頁面」
5.  在 Project Wikis 文件庫的文件可以自由排序
    1.  每個資料夾下可以有個 `.order` 檔案可以決定文件排序，裡面要放頁面名稱
    2.  如果刪除 `.order` 檔案，所有文件排序就會回歸依字母順序排序
    3.  就算你刪除 `.order` 檔案，之後你在 Azure DevOps 拖曳文件順利就會自動產生

由於**頁面標題**等於**檔案名稱**，其**檔案命名**的限制如下：

1.  檔名與路徑的**長度總和**不得超過 `235` 個字元
2.  所有的**頁面標題**必須是唯一的 (Uniqueness)
3.  檔案名稱**不能包含**以下字元
    1.  出現 Unicode 控制字元 ([control characters](https://www.compart.com/en/unicode/category/Cc)) 或 代理字元組 ([surrogate characters](https://www.informit.com/articles/article.aspx?p=2274038&seqNum=10))
    2.  出現 `/`, `\` 或 `#` 字元
    3.  出現以 `.` 開頭或結尾的檔名 (文件檔名通常都是 `.md` 結尾)
4.  有些特殊字元可以出現在頁面上，只是要編碼過
    1.  符號 `:` 必須編碼為 `%3A`
    2.  符號 `<` 必須編碼為 `%3C`
    3.  符號 `>` 必須編碼為 `%3E`
    4.  符號 `*` 必須編碼為 `%2A`
    5.  符號 `?` 必須編碼為 `%3F`
    6.  符號 `|` 必須編碼為 `%7C`
    7.  符號 `-` 必須編碼為 `%2D`
    8.  符號 `"` 必須編碼為 `%22`

針對每一個單一檔案大小也有以下限制：

1.  所有檔案大小不得超過 18MB
2.  如果是附件檔案不得超過 19MB

### 相關連結

-   [Share info with a project, repo, README, or Wiki - Azure DevOps | Microsoft Docs](https://learn.microsoft.com/en-us/azure/devops/project/wiki/about-readme-wiki?view=azure-devops&WT.mc_id=DT-MVP-4015686)
-   [Wiki files, structure, and conventions - Azure DevOps | Microsoft Docs](https://learn.microsoft.com/en-us/azure/devops/project/wiki/wiki-file-structure?view=azure-devops&WT.mc_id=DT-MVP-4015686)
