仮想ワークスペース
GitHub Repositories 拡張機能のような拡張機能は、ファイルシステムプロバイダーによってバックアップされた1つ以上のフォルダー上で VS Code を開きます。拡張機能がファイルシステムプロバイダーを実装すると、ワークスペースのリソースはローカルディスク上に配置されず、サーバー上やクラウド上に配置される仮想(Virtual)なものとなり、編集操作もその場所で行われるようになります。
この構成は仮想ワークスペースと呼ばれます。VS Code ウィンドウで仮想ワークスペースが開かれている場合、他のリモート開発ウィンドウと同様に、左下のリモートインジケーターにラベルで表示されます。

すべての拡張機能が仮想リソースで動作できるわけではなく、リソースがディスク上にあることを必要とするものもあります。ディスクアクセスに依存するツールを使用したり、同期的なファイルアクセスを必要としたり、必要なファイルシステムの抽象化が行われていない拡張機能もあります。そのような場合、仮想ワークスペースでは、VS Code はユーザーに対して制限付きモードで実行されていること、および一部の拡張機能が無効になっているか機能が制限されていることを通知します。
一般的に、ユーザーは可能な限り多くの拡張機能が仮想ワークスペースで動作し、リモートリソースの閲覧や編集時に優れたユーザー体験を得ることを望んでいます。このガイドでは、拡張機能が仮想ワークスペースに対してテストを行う方法、仮想ワークスペースで動作させるための変更点、および virtualWorkspaces 機能プロパティについて説明します。
拡張機能を仮想ワークスペースで動作するように変更することは、VS Code for the Web でうまく動作させるための重要なステップでもあります。VS Code for the Web は完全にブラウザ内で実行され、ブラウザのサンドボックスの性質上、ワークスペースは仮想となります。詳細については、Web 拡張機能ガイドを参照してください。
自分の拡張機能は影響を受けますか?
テーマ、キーバインド、スニペット、文法拡張機能のように実行可能なコードを持たず、純粋に宣言的な拡張機能であれば、仮想ワークスペースで実行可能であり、修正は不要です。
main エントリポイントを定義するコードを持つ拡張機能は、確認が必要であり、場合によっては修正が必要となります。
仮想ワークスペースに対して拡張機能を実行する
GitHub Repositories 拡張機能をインストールし、コマンドパレットから Open GitHub Repository... コマンドを実行します。このコマンドはクイックピックドロップダウンを表示し、任意の GitHub URL を貼り付けるか、特定のリポジトリやプルリクエストを検索できます。
これにより、すべてのリソースが仮想である仮想ワークスペース用の VS Code ウィンドウが開きます。
拡張機能コードが仮想リソースに対応しているか確認する
仮想ファイルシステムに対する VS Code API のサポートは、以前から存在しています。ファイルシステムプロバイダー API を確認してください。
ファイルシステムプロバイダーは新しい URI スキーム(例: vscode-vfs)に対して登録され、そのファイルシステム上のリソースはそのスキームを使用した URI(vscode-vfs://github/microsoft/vscode/package.json)で表現されます。
VS Code API から返される URI を拡張機能がどのように扱うかを確認する
- URI スキームが常に
fileであると仮定してはいけません。URI.fsPathは URI スキームがfileの場合にのみ使用できます。 - ファイル操作のために
fsノードモジュールを使用していないか確認してください。可能な場合は、適切なファイルシステムプロバイダーに委譲するvscode.workspace.fsAPI を使用してください。 fsアクセスに依存するサードパーティ製コンポーネント(言語サーバーやノードモジュールなど)がないか確認してください。- コマンドから実行可能ファイルやタスクを実行している場合は、それらのコマンドが仮想ワークスペースウィンドウで意味をなすか、あるいは無効にすべきかを検討してください。
拡張機能が仮想ワークスペースを扱えるかどうかを通知する
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": true は、まだ virtualWorkspaces 機能を設定していないすべての拡張機能に対するデフォルト値です。
しかし、仮想ワークスペースのテスト中、仮想ワークスペースでは無効にすべきだと判断した拡張機能のリストを作成しました。このリストは issue #122836 で確認できます。これらの拡張機能は、デフォルトで "virtualWorkspaces": false となっています。
もちろん、この決定は拡張機能の作者が行うのが最も適切です。拡張機能の package.json にある virtualWorkspaces 機能が我々のデフォルトを上書きするため、最終的にはこのリストは廃止する予定です。
仮想ワークスペースが開かれたときに機能を無効にする
コマンドとビューの貢献を無効にする
コマンドやビュー、その他多くの貢献の可用性は、when 句内のコンテキストキーを使用して制御できます。
virtualWorkspace コンテキストキーは、すべてのワークスペースフォルダーが仮想ファイルシステム上にある場合に設定されます。以下の例では、仮想ワークスペースにいない場合にのみ npm.publish コマンドをコマンドパレットに表示します。
{
"menus": {
"commandPalette": [
{
"command": "npm.publish",
"when": "!virtualWorkspace"
}
]
}
}
resourceScheme コンテキストキーは、エクスプローラーで現在選択されている要素、またはエディターで開かれている要素の 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 によるトークン化と色分け
- 言語固有の編集サポート: 括弧のペア、コメント、入力時ルール、折りたたみマーカー
- コードスニペット
B. 単一ファイル言語サポート
- ドキュメントシンボル(アウトライン)、折りたたみ、選択範囲
- ドキュメントのハイライト、セマンティックハイライト、ドキュメントの色
- 現在のファイルおよび静的な言語ライブラリに基づくシンボルに対する補完、ホバー、シグネチャヘルプ、参照/宣言の検索
- フォーマット、リンク編集
- 構文検証および同一ファイル内のセマンティック検証とコードアクション
C. ファイル横断、ワークスペース対応言語サポート
- ファイル間の参照
- ワークスペースシンボル
- ワークスペース/プロジェクト内の全ファイルの検証
VS Code に付属するリッチな言語拡張機能(TypeScript、JSON、CSS、HTML、Markdown)は、仮想リソースで作業する場合、単一ファイル言語サポートに制限されます。
言語拡張機能を無効にする
単一ファイルでの作業が選択肢にない場合、言語拡張機能は仮想ワークスペース内にあるときに拡張機能自体を無効にする判断も可能です。
拡張機能が文法とリッチな言語サポートの両方を提供しており、リッチなサポートのみを無効にする必要がある場合、文法も無効化されてしまいます。これを避けるには、基本的な言語拡張機能(文法、言語構成、スニペット)とリッチな言語サポートを分離し、2つの拡張機能を作成することができます。
- 基本的な言語拡張機能には
"virtualWorkspaces": trueを設定し、言語 ID、構成、文法、スニペットを提供します。 - リッチな言語拡張機能には
"virtualWorkspaces": falseを設定し、mainファイルを含めます。これは言語サポートやコマンドを提供し、基本的な言語拡張機能への依存(extensionDependencies)を持ちます。リッチな言語拡張機能は、ユーザーが単一の拡張機能をインストールするだけで全機能を引き続き利用できるよう、既存の拡張機能 ID を保持する必要があります。
このアプローチは、JSON 拡張機能と JSON 言語機能拡張機能で構成される JSON のような組み込み言語拡張機能で見ることができます。
この分離は、制限付きモードで実行される信頼されていないワークスペースにも役立ちます。リッチな言語拡張機能は多くの場合信頼を必要としますが、基本的な言語機能はどのような設定でも実行可能です。
言語セレクター
言語機能(補完、ホバー、コードアクションなど)のプロバイダーを登録する際は、そのプロバイダーがサポートするスキームを指定するようにしてください。
return vscode.languages.registerCompletionItemProvider(
{ language: 'typescript', scheme: 'file' },
{
provideCompletionItems(document, position, token) {
// ...
}
}
);
仮想リソースにアクセスするための言語サーバープロトコル(LSP)のサポートはどうなっていますか?
LSP にファイルシステムプロバイダーサポートを追加する作業が進行中です。言語サーバープロトコルの issue #1264 で追跡できます。