虛擬工作區
諸如 GitHub Repositories 等擴充功能,會在由檔案系統提供者 (file system provider) 支援的一個或多個資料夾上開啟 VS Code。當擴充功能實作了檔案系統提供者時,工作區資源可能不會位於本機磁碟上,而是虛擬的(位於伺服器或雲端),且編輯操作也會在該處執行。
這種設定稱為虛擬工作區 (virtual workspace)。當 VS Code 視窗中開啟虛擬工作區時,左下角的遠端指示器會顯示標籤以提示使用者,這與其他遠端開發 (remote development) 視窗類似。

並非所有擴充功能都能處理虛擬資源,有些可能要求資源必須位於磁碟上。部分擴充功能使用的工具依賴磁碟存取、需要同步檔案存取,或是缺乏必要的檔案系統抽象層。在這種情況下,若處於虛擬工作區,VS Code 會向使用者提示目前處於受限模式 (restricted mode),且部分擴充功能已被停用或僅提供有限功能。
總體而言,使用者希望盡可能讓更多擴充功能在虛擬工作區中運作,並在瀏覽和編輯遠端資源時擁有良好的體驗。本指南將展示擴充功能如何針對虛擬工作區進行測試、說明如何進行調整以支援虛擬工作區,並介紹 virtualWorkspaces 能力屬性。
修改擴充功能以支援虛擬工作區,對於在 VS Code for the Web 中順暢運作也是重要的一步。VS Code for the Web 完全在瀏覽器內部執行,且由於瀏覽器沙盒的限制,工作區均為虛擬的。詳情請參閱網頁擴充功能 (Web Extensions) 指南。
我的擴充功能會受到影響嗎?
如果擴充功能沒有可執行程式碼,僅是純粹的宣告式內容(如主題、快速鍵、程式碼片段或語法擴充功能),則它可以在虛擬工作區中執行,無需進行任何修改。
含有程式碼的擴充功能(即定義了 main 進入點的擴充功能)則需要進行檢查,並可能需要調整。
在虛擬工作區中執行您的擴充功能
安裝 GitHub Repositories 擴充功能,並從命令面板 (Command Palette) 執行 Open GitHub Repository... 命令。該命令會顯示一個 Quick Pick 下拉選單,您可以貼上任何 GitHub URL,或選擇搜尋特定的儲存庫或提取請求 (Pull Request)。
這會為虛擬工作區開啟一個 VS Code 視窗,其中所有資源皆為虛擬的。
檢查擴充功能程式碼是否已準備好處理虛擬資源
VS Code API 對虛擬檔案系統的支援已存在一段時間。您可以查看檔案系統提供者 API。
檔案系統提供者是為新的 URI 方案 (scheme) 註冊的(例如 vscode-vfs),而該檔案系統上的資源將由使用該方案的 URI 來表示(例如 vscode-vfs://github/microsoft/vscode/package.json)。
檢查您的擴充功能如何處理從 VS Code API 回傳的 URI
- 切勿假設 URI 方案為
file。只有當 URI 方案為file時,才能使用URI.fsPath。 - 注意是否使用了 Node.js 的
fs模組進行檔案系統操作。如果可能,請使用vscode.workspace.fsAPI,它會自動委派給適當的檔案系統提供者。 - 檢查是否有依賴
fs存取的第三方元件(例如語言伺服器或 Node 模組)。 - 如果您透過命令執行可執行檔或工作 (tasks),請檢查這些命令在虛擬工作區視窗中是否合理,或者是否應該將其停用。
宣告您的擴充功能是否能處理虛擬工作區
package.json 中 capabilities 下的 virtualWorkspaces 屬性,用於宣告擴充功能是否支援虛擬工作區。
不支援虛擬工作區
下方的範例宣告該擴充功能不支援虛擬工作區,因此 VS Code 不應在此設定下啟用它。
{
"capabilities": {
"virtualWorkspaces": {
"supported": false,
"description": "Debugging is not possible in virtual workspaces."
}
}
}
部分或完全支援虛擬工作區
當擴充功能完全或部分支援虛擬工作區時,應設定 "virtualWorkspaces": true。
{
"capabilities": {
"virtualWorkspaces": true
}
}
如果擴充功能可運作但功能受限,應向使用者說明限制:
{
"capabilities": {
"virtualWorkspaces": {
"supported": "limited",
"description": "In virtual workspaces, resolving and finding references across files is not supported."
}
}
}
該說明會顯示在「擴充功能」檢視中。

隨後,擴充功能應如後文所述,停用在虛擬工作區中不支援的功能。
預設值
對於尚未填寫 virtualWorkspaces 能力的所有擴充功能,"virtualWorkspaces": true 為預設值。
然而,在測試虛擬工作區的過程中,我們整理了一份清單,列出了我們認為應在虛擬工作區中停用的擴充功能。該清單可在 issue #122836 中找到。這些擴充功能的預設值為 "virtualWorkspaces": false。
當然,擴充功能作者比我們更了解自身情況。package.json 中的 virtualWorkspaces 能力將會覆蓋我們的預設值,而我們最終也會淘汰該清單。
在開啟虛擬工作區時停用功能
停用命令與檢視貢獻
命令、檢視以及許多其他貢獻的可用性,可以透過 when 子句 中的 Context Key 來控制。
當所有工作區資料夾都位於虛擬檔案系統上時,virtualWorkspace Context Key 會被設定。下方的範例僅在非虛擬工作區時,才會在命令面板中顯示 npm.publish 命令:
{
"menus": {
"commandPalette": [
{
"command": "npm.publish",
"when": "!virtualWorkspace"
}
]
}
}
resourceScheme Context Key 會被設定為檔案總管中目前所選項目或編輯器中開啟項目的 URI 方案。
在下方的範例中,npm.runSelectedScript 命令僅在底層資源位於本機磁碟時,才會顯示於編輯器操作選單中。
{
"menus": {
"editor/context": [
{
"command": "npm.runSelectedScript",
"when": "resourceFilename == 'package.json' && resourceScheme == file"
}
]
}
}
以程式設計方式偵測虛擬工作區
若要檢查目前工作區是否由非 file 方案組成且為虛擬的,您可以使用以下原始程式碼:
const isVirtualWorkspace =
workspace.workspaceFolders &&
workspace.workspaceFolders.every(f => f.uri.scheme !== 'file');
語言擴充功能與虛擬工作區
對於虛擬工作區中的語言支援有何預期?
要求所有擴充功能都能完全處理虛擬資源是不切實際的。許多擴充功能使用需要同步檔案存取且依賴磁碟檔案的外部工具。因此,僅提供有限功能(如下列的基本 (Basic) 和單一檔案 (Single-file) 支援)是可以接受的。
A. 基本語言支援
- TextMate Tokenization 和上色 (colorization)
- 特定語言的編輯支援:括號配對、註解、斷行規則 (on enter rules)、摺疊標記 (folding markers)
- 程式碼片段
B. 單一檔案語言支援
- 文件符號 (outline)、摺疊、選取範圍
- 文件高亮 (highlights)、語意高亮 (semantic highlighting)、文件色彩
- 基於目前檔案與靜態語言函式庫的符號進行:補全 (completions)、滑鼠懸浮 (hovers)、簽名說明 (signature help)、尋找參考/宣告
- 格式化、連結編輯 (linked editing)
- 語法驗證、同檔案語意驗證與程式碼動作 (Code Actions)
C. 跨檔案、感知工作區的語言支援
- 跨檔案的參考
- 工作區符號 (Workspace symbols)
- 工作區/專案中所有檔案的驗證
VS Code 隨附的功能豐富語言擴充功能(TypeScript、JSON、CSS、HTML、Markdown)在處理虛擬資源時,均限制為「單一檔案」的語言支援。
停用語言擴充功能
如果「單一檔案」模式不可行,語言擴充功能也可以選擇在進入虛擬工作區時完全停用自身。
如果您的擴充功能同時提供了語法 (grammars) 和需要被停用的豐富語言支援,那麼語法也會一併被停用。為了避免這種情況,您可以將基本語言擴充功能(語法、語言設定、程式碼片段)與豐富語言支援拆分為兩個擴充功能。
- 基本語言擴充功能設定
"virtualWorkspaces": true,並提供語言識別碼、設定、語法和程式碼片段。 - 豐富語言擴充功能設定
"virtualWorkspaces": false,並包含main檔案。它提供語言支援、命令,並在extensionDependencies中依賴基本語言擴充功能。豐富語言擴充功能應保留既有擴充功能的 ID,以便使用者只需安裝單一擴充功能即可繼續享有完整功能。
您可以參考內建的語言擴充功能(例如 JSON)的做法,它由一個 JSON 擴充功能和一個 JSON 語言功能擴充功能組成。
這種分離方式也有助於在受限模式 (Restricted Mode) 下執行未受信任的工作區 (Untrusted Workspaces)。豐富的語言擴充功能通常需要信任,而基本語言功能則可以在任何設定下執行。
語言選擇器
當為語言功能(例如補全、滑鼠懸浮、程式碼動作等)註冊提供者時,請務必指定該提供者支援的方案 (schemes)。
return vscode.languages.registerCompletionItemProvider(
{ language: 'typescript', scheme: 'file' },
{
provideCompletionItems(document, position, token) {
// ...
}
}
);
語言伺服器協定 (LSP) 對存取虛擬資源的支援如何?
我們正在進行將檔案系統提供者支援加入 LSP 的工作,詳情請追蹤 Language Server Protocol issue #1264。