iT邦幫忙

第 12 屆 iT 邦幫忙鐵人賽

DAY 9
0
Software Development

自己用的工具自己做! 30天玩轉VS Code Extension之旅系列 第 9

Day09 | Data Storage以及教學中沒有特別提及的小細節

哈囉,大家好,我是韋恩,今天我們來了解一下在vscode裡的data storage,今天介紹的內容也都非常實務。

VSCode的Data Storage簡介


當我們為用戶開發應用程式時,通常都會讓使用者儲存一些個人化設定與本地資料,如前面所提的configuration就很方便地提供了user settings的介面讓使用者設置個人設定。但User Settings雖然方便,若是要滿足extension的各種使用情境,還是力有未逮。為此,VSCode提供了多種可以儲存使用者資料的api跟方法,讓extension可以像一般的桌面程式一樣儲存本地資料。

在官方的教學文件中,主要介紹了四種Data Storage的選擇,主要為兩大類:

Key/value鍵值

  • ExtensionContext.workspaceState: 透過extension的memento物件,儲存workspace scope特定的資料,menento物件會以使用key/value的方式儲存資料,如同前端的localStorage。當同一個workspace再次被打開時,vscode會還原(restore)上一次儲存在memento物件的資料讓使用者取得設定。

  • ExtensionContext.globalState:提供如同user settings scope的memento物件,讓使用者以key/value方式儲存資料。當同一個extension在vscode中active時,vscod即會還原(restore)上一次儲存在memento物件的資料讓使用者取得設定。

Memento物件的使用方法如下:


import * as vscode from 'vscode';

export function activate(context: vscode.ExtensionContext) {
    /*
	* 設定、更新memento的資料
	*/
    context.workspaceState.update('keyA', 'keyAValue');
    /*
	* 取得memento的資料,可設定初始預設值
	*/
	context.workspaceState.get('keyB', 'defaultValue');
}

Custom Storage

  • ExtensionContext.storagePath: 提供workspace scope級別的storagePath,讓使用者在這個路徑的資料夾下設置database或任意型態的資料,extension可以讀寫這個路徑下面的檔案,並且這個地方的資料不會隨著extension卸載後消失,再次裝回亦可讀取。
  • ExtensionContext.globalStoragePath: 如上所述,差別在於其storagePath適用於user settings scope,為全域的儲存範圍。

在extension需要儲存大型檔案或大量資料時,於storagePath下配置檔案特別有用。

註:storagePath、globalStoragePath在新版的vscode已經列為deprecated,應使用storageUriglobalStorageUri來取得storage的路徑配置本地儲存的資料庫或檔案。

教學未提及的小細節


在上面的說明裡,我們可以看到這些api或路徑都是於ExtensionContext下取得,這個ExtensionContext是什麼呢?在哪裡取得呢?我們在extension.ts中的active function中取得的context參數,即為上面提及的ExtensionContext,因此我們可以在context參數中使用這些api跟路徑,並且vscode中透過自動補全取得一系列可以使用的api清單。

Ok,現在我們點開context了,我們赫然發現storagePath以及globalStorage path在現在版本已經列為deprecated了,筆者實際過ExtensionContext.storagePath,當前版本仍可以取得對應路徑,但強烈建議讀者改用ExtensionContext.storageUri下面的path路徑,如下所示:

    const storagePath = context.storageUri?.path;
	const storagePathCast = (context.storageUri as vscode.Uri).path;
	const globalStoragePath = context.globalStorageUri.path;

註: 此處的storagePath因為有可能回傳undefined,故需轉變型態為vscode.Uri,或使用optional chaining(storagePath後面的?)的語法,才能避免編譯器提示的錯誤。

好的,現在我們已經了解storageUri的用法,現在我會再介紹兩種在開發中會有幫助的api,分別是:

  • ExtensionContext.logUri: 提供當天的log儲存的資料夾的位置,可配合Log4jswinstonjs等流行的logger library使用。為什麼我們需要本地儲存的Log檔案呢?當我們的應用程式在斷網的客戶端執行時,我們沒辦法直接透過api傳回當下出錯的紀錄,此時的log檔案就是不可缺少而且必需的。

  • ExtensionContext.environmentVariableCollection: 提供extension的環境變數設定,可以讓我們在extension中設置環境變數,並且可以讓terminal讀取到。環境變數的collection物件提供一系列方法,我們可以在自動補全中看到:

collection提供了一系列用於新增、修改、刪除、清空的api,讓我們方便的管理這些變數,用法如下:

  • 新增環境變數:
   /*
    * 新增環境變數: append->往尾部追加,prepend->往頭部追加
    */
   context.environmentVariableCollection.append('TestEnv', 'TestEnvValue');
   context.environmentVariableCollection.prepend('Test2Env', 'Test2EnvValue');

相同的環境變數會被覆蓋,只會被讀取一個,請務必注意。

  • 刪除、清空環境變數:
/*
	* 刪除單一環境變數
	*/
context.environmentVariableCollection.delete('Test2Env');
/*
	* 清空所有環境變數
	*/
context.environmentVariableCollection.clear();
  • 更新環境變數:
/*
 * 更新單一環境變數
 */
context.environmentVariableCollection.replace('TestEnv', 'UpdatedEnvValue');
  • 操作所有環境變數:
    /*
	* 操作所有環境變數
	*/
	context.environmentVariableCollection.forEach((variable, mutator, collection) => {
		console.log(variable, mutator);
	});
	// 執行結果:
	// variable: TestEnv
    // mutator: {
	//	  value:"UpdatedEnvValue"
	//	  type:1
	// }

我們可以在terminal中使用環境變數,做個小測試吧!

$ echo ${TestEnv}

以上面的範例為例,terminal會輸出得到UpdatedEnvValue。

Workspace Configuration與Data Storage比較


現在,我們已經了解了可以在data storage中儲存本地資料,那麼什麼時候使用configuration比較方便,什麼時候用data storage呢?

  1. workspace設定可以被監聽,如果extension需要在user手動變更設定時刷新某些UI狀態,就很適合使用workspace的Configuration。
    vscode.workspace.onDidChangeConfiguration((e) => {
		const newConfig = vscode.workspace.getConfiguration('extension-namespace');
		...
	});
  1. 儲存使用者workspace個別設定,適合data storage

workspace可以覆蓋使用者設定確實很方便,但如果我們有多個workspace需要同一個workspace設定,這些設定又偏偏跟user settings中的有些差異呢?此時,我們可以將多個設定存入storagePath中我們準備的jsonfile或資料庫,讓使用者儲存自訂個人化設定,並透過某個key或自訂的type,讓使用者在workspace settings一鍵引用重複的設定。

  1. 需儲存較大量資料,將資料儲存於storagePath下面較好。

vscode的storagePath可以讓我們自由選擇要將資料儲存於檔案或資料庫,我們可以搭配jsonFile這個library儲存json檔案,也可以選擇輕量的nedb或者是leveldb儲存結構化的資料,並進行增刪改查。

結語


今天我們介紹了data storage與一些文件在教學中沒有特別提的小細節,這些細節我們可以透過VSCode的自動補全發現,其實就是因為vscode有完善的api類型定義檔。因此除了查看自動補全後的說明,我們也可以直接查閱官方網站Reference一節vscode api下面的說明,這個頁面會自動讀取VSCode類型檔的定義,並用美觀的UI呈現出來,因此當我們要查閱最新的api說明時,也請儘量多加利用這一個api文件的資源喔!當然,最後也最重要的還是要動手練習並加以實踐這些文件裡提及的api,我們才會有自己的東西,實踐出真知!

好的,今天介紹就到此為止了,今天介紹的內容都非常實務,希望大家了解學習後,能夠開發更多元多樣的extension出來,我們明天見,掰掰!

本日參考文件



上一篇
Day08 | 提供使用者Extension的設定選項吧
下一篇
Day10 | 你問我答,Extension與使用者的互動流程
系列文
自己用的工具自己做! 30天玩轉VS Code Extension之旅36

尚未有邦友留言

立即登入留言