ワークスペースとは
ワークスペースは、複数ルートのフォルダーを同時に開く機能です。イメージとしては、Visual Studioのソリューション内で複数のプロジェクトを開けるのと同じです。アプリケーションを複数のルートフォルダーに分割していたり、テストを別ルートフォルダーに分けていたりした方には便利だと思います。もちろんルートフォルダーは、それぞれ異なるパスに配置してあっても問題ありません。
ワークスペースは、従来のバージョンからプレビュー機能として実装が進められていましたが、VS Code 1.18から正式リリースされました。
ワークスペースの使用方法
使い方は簡単で、[ファイル]-[ワークスペースにフォルダーを追加]を選択するだけです。もう少し直感的に追加したい方は、エクスプローラーにフォルダーをドラック&ドロップしても追加できます。
ワークスペースの設定を保存したいなら、[ファイル]-[名前を付けてワークスペースを保存]を選択します。.code-workspaceの拡張子で設定を保存できます。保存後は、VS Codeの[ファイル]-[ワークスペースを開く]や**.code-workspace**ファイルをダブルクリックすれば再度ワークスペースを開けます。
ワークスペースの設定
.code-workspaceファイルはJSON形式のファイルになっていて、エイリアスの設定などを追加できます。最初にファイルの記述例を示します。
{
"folders": [
{
"name": "Product",
"path": "app3"
},
{
"name": "Test",
"path": "app2"
},
{
"path": "C:\\app3"
}
],
"settings": {
"window.zoomLevel": 2
},
"extensions": {
"recommendations": [
"yuichinukiyama.vscode-preview-server"
]
}
}
ワークスペースの保存を設定した直後はpathの設定だけがされています。pathには**.code-workspaceファイルからの相対パスか絶対パスでワークスペースのフォルダーが指定されています。つまり、.code-workspace**ファイルのパスを保存後変更すると、pathを修正しないと読み込めなくなるので注意してください。
nameを指定するとフォルダーにエイリアス(別名)を付けられます。また、settingsを指定すれば、ワークスペース共通のVS Codeの設定ができます。設定できる項目はワークスペースを使っていないときと同じです。
recommendationsは推奨の拡張機能です。ワークスペースを開いたタイミングで推奨機能のインストールを表示したり、拡張機能画面の推奨欄に拡張機能を表示したりできます。共同開発時に、共通で使ってほしい拡張機能がある場合などに便利です。recommendationsの書き方は少々癖があって、著者名.拡張機能名です。拡張機能画の拡張機能名の横に出ているので、そちらで確認してください。
拡張機能への影響
今まで見てきたように、ワークスペースは複数のルートフォルダーを開いたり、VS Codeの設定ができるため、フォルダーにアクセスしたり、ローカルのVS Code設定にアクセスする拡張機能は影響を受けます。公式のwikiに影響を受けるケースが列挙されているので、抄訳すると以下のようになります。
- workspace.rootPathプロパティを使用している拡張機能
- グローバルではなくファイルレベルでコントリビューションのポイントを持っている拡張機能
- language Serverを含む拡張機能
私の作っている拡張機能もworkspace.rootPathプロパティを使用しているので、影響を受ける対象でした。このプロパティは非推奨になったので、代替えのAPIが提供されています。
メソッド | 説明 |
---|---|
workspace.workspaceFolders | すべてのWorkspaceFolderにアクセスする(ワークスペースを開いていない場合はundefined) |
workspace.onDidChangeWorkspaceFolders | WorkspaceFolderが追加されたり削除されたりした場合、イベントが実行される |
workspace.getWorkspaceFolder(uri) | 指定したWorkspaceFolderを取得する(ワークスペースを開いていない場合はundefined) |
ワークスペースが入ることにより、VS Codeが開いているものが、ファイル/フォルダー/ワークスペースの3つに増えています。それぞれどれを開いているか確認するためには、workspaceFoldersをチェックします。
const folders = workspace.workspaceFolders;
if (folders === undefined) {
// undefinedだった場合はファイルを開いている
} else if (folders.length === 1) {
// workspaceFolders配列の要素数が1つだった場合はフォルダーを開いている
} else {
// それ以外(workspaceFolders配列の要素数が2以上)だった場合はワークスペースを開いている。
}
また、ファイルの相対パスを取得している方は、workspace.asRelativePath(pathOrUri: string | Uri, includeWorkspaceFolder?: boolean): string;の動作が変更されていることに注意してください。includeWorkspaceFolderパラメーターをtrueに設定すると、取得する相対パス名がcode-workspaceファイルのnameプロパティで付けた名前になります。しかも、trueが既定値のため、パラメーターを渡していないと正確な相対パスではなく、ワークスペースのエイリアスが取得されています。従来どおりの相対パスを取得する場合はfalseを指定してください。
コントリビューションポイントや設定もグローバルとフォルダーレベルに加えて、ワークスペースで設定できるようになったため、拡張機能の設定をどこにするかを決められるようになりました。具体的には、package.jsonにscopeプロパティが追加されています。windowは既定値で、従来通り、グローバルの設定を使います。一方、resourceはアクティブなリソースに依存して使われる設定が変わります。
{
"keywords": ["multi-root ready"],
"contributes": {
"configuration": [
{
"title": "Configuration Samples",
"properties": {
"conf.view": {
"type": "string",
"description": "window scope",
"scope": "window"
},
"conf.resource": {
"type": "object",
"default": {},
"description": "resource scope",
"scope": "resource"
}
}
}
]
}
なお、ワークスペースに対応した拡張機能には、**"keywords": ["multi-root ready"]**を付けることが推奨されています。急ぎで対応したため、コードが汚いですが、私の拡張機能に加えたコミットが参考になるかもしれないので、リンクを張っておきます。