詳細なプラグインメカニズム_VSCodeプラグイン開発ノート1

1.拡張性
VSコードプラグインはUIのカスタマイズには適していません。たとえば、AtomのツールバーをVSコードに実装するのは困難です。

詳細なプラグインメカニズム_VSCodeプラグイン開発ノート1

豊富な拡張性モデルを提供しますが、プラグインが基盤となるUI DOMに直接アクセスすることはできません(つまり、プラグインがIDEの外観を変更することは困難であり、UIのカスタマイズは制限されます)。これは、下部の継続的な最適化の便宜のためです。


With VS Code, we’re continually trying to optimize use of the underlying web technologies to deliver an always available, highly responsive editor and we will continue to tune our use of the DOM as these technologies and our product evolve.

UI DOMレイヤーは、最適化によって頻繁に変更される可能性があります。VSコードでは、これらの最適化項目がプラグインの依存関係によって制限されることを望まないため、UIのカスタマイズ機能を制限するだけです。

UIのカスタマイズに加えて、IDE関連の機能機能は、基本的な構文の強調表示/ APIプロンプト、参照ジャンプ(定義に移動)/ファイル検索、テーマのカスタマイズ、高度なデバッグプロトコルなどの拡張機能をサポートします。

PS実際、UIを拡張する方法があります(プラグインランタイム環境を回避するためですが、多くの労力がかかります)。詳細については、vscode拡張機能からのaccess electronic APIを参照してください。フォローアップノートでは、詳細を紹介します。

2.動作環境
パフォーマンスと互換性のために、プラグインは別のプロセス(拡張ホストプロセスと呼ばれる)で実行され、DOMへの直接アクセスを許可しないため、IntelliSenseなどの組み込みUIコンポーネントのセットを提供します。

したがって、プラグインのクラッシュや無応答は、IDEの通常の動作には影響しません。次に例を示します。


// ref: my-extension/src/extension.ts
export function activate(context: vscode.ExtensionContext) {
  // hang up
  while (true);
}

プラグインの無限ループは、IDEの通常の使用や他のプラグインのロード/アクティブ化には影響しませんが、プロセスリストでは、Code HelperのCPU使用率がほぼ100%であることがわかります。プロセスレベルのサンドボックスにより、プラグインメカニズムの安定性が保証されます。

3.コアコンセプトの
安定性:プラグイン分離
プラグインは、起動パフォーマンスとIDE自体の安定性に影響を与える可能性があるため、この問題はプロセス分離によって解決されます。プラグインは独立したプロセスで実行され、IDEとその起動時間には影響しません。

これはユーザーの観点から考えられており、ユーザーがIDEを完全に制御できることが望まれます。プラグインが何を実行していても、IDEの基本機能の通常の使用には影響しません。

PSextensionホストプロセスは、VSコード拡張APIにアクセスできる特別なノードプロセスです。VSコードは、このプロセスのデバッグサポートも提供します。

パフォーマンス:プラグインのアクティブ化
プラグインは(できるだけ遅く)遅延ロードされ、特定のシーンでのみロード/アクティブ化されるため、それ以前はメモリやその他のリソースを消費しません。

実装では、プラグインはIDEによってトリガーされる特定のアクティブ化イベント(アクティブ化イベント)を登録します。たとえば、マークダウンプラグインは、ユーザーがmdファイルを開いたときにのみアクティブ化する必要があります。


プラグインには6つのアクティベーション方法があります。

onLanguage:$ {language}特定の言語でドキュメントを開く
onCommand:$ {command}コマンドパレットから特定のコマンドを実行する
onDebugデバッグモードに入る
workspaceContains:$ {toplevelfilename}開いたフォルダーに特定のファイルが含まれる
onView:$ {viewId}指定したビューを展開する


  • 「activationEvents」:["*"]を除いて、IDEを開いてアクティブ化します。すべて条件付きアクティブ化です。プラグインは、特定のシナリオまたは特定の条件が満たされた場合にのみロード/アクティブ化されます。

プラグインマニフェストファイル
マニフェストファイルは、プラグインのメタ情報を記述するために使用されます。マニフェストファイルとしてpackage.jsonを直接使用し、プラグインのロードをトリガーするアクティベーションイベントや、プラグインが拡張(コントリビューション)する拡張ポイントなど、いくつかの一意のフィールドを追加します。ポイント)

IDEは、起動プロセス中にプラグインマニフェストファイルをスキャンします。UIが関連している場合、UIは拡張され、UIが関連していない場合、拡張ポイントはプラグイン機能に関連付けられます。

さらに、プラグインの実行環境はノードプロセスであるため、npmパッケージが使用可能であり、依存モジュールもpackage.jsonで宣言されます。プラグインのインストール時にユーザーが自動的にnpmインストールすることはないため、プラグインがリリースされる前に依存モジュールをパッケージ化する必要があることに注意してください。詳細については、インストールとパッケージ化を参照してください。

PS拡張ポイントはAOPの結合ポイントに似ており、「ここで拡張/拡張できます」。たとえば、カスタムコマンドを追加すると、コマンド拡張ポイントが拡張されます。


manifest
// package.json
{
  // 插件名称
  "name": "my-extension",
  // 显示名称
  "displayName": "MyExtension",
  // 描述信息
  "description": "An awesome vscode  extension",
  // 版本号 semver格式
  "version": "0.0.1",
  // 在插件市场展示的图标
  "icon": "img/icon.png",
  // 发布者名字
  "publisher": "ayqy",
  // vscode版本要求
  "engines": {
    "vscode": "^1.19.0"
  },
  // 所属分类,可选Languages, Snippets, Linters, Themes等等
  "categories": ["Other"],
  // 加载/激活方式
  "activationEvents": ["onLanguage:javascript"],
  // 入口文件路径
  "main": "./out/extension",
  // 注册扩展点关联
  "contributes": {
    "languages": [
      {
        "id": "javascript",
        "aliases": ["JavaScript", "javascript"],
        "extensions": [".js"]
      }
    ]
  }
}

完全なPSについては、拡張マニフェストファイル–package.jsonを参照してください。

extension.ts / activateは1回だけトリガーされ、package.jsonで宣言されたactivationEventsに従ってトリガーされます。トリガー条件は、特定の言語でファイルを開くか、特定のコマンドを実行することです。アクティブ化後、IDEが閉じられるかクラッシュするまで、extension.ts / deactivateはトリガーされないため、一般的な使用法は次のとおりです。

アクティブ化:プラグインがアクティブ化され、汎用モジュールのシングルトンが初期化されます(1回だけ実行されます)

非アクティブ化:IDEはサイトを閉じてクリーンアップしようとしていますが、最大で10秒しか待機しないと言われているため、時間のかかる操作を行うのには適していません。

拡張ポイント
は、サポートされている拡張タイプであり、package.json / contributesで宣言されています。

構成プラグイン構成項目、ユーザーは設定コマンド
使用してconfigurationDefaultsプラグイン構成項目のデフォルト値を設定
できますコマンドを追加しますユーザーはコマンドパレットから特定のコマンドを入力してプラグイン機能
メニューをアクティブにしますコマンドに関連付けられたメニュー項目を追加しますユーザーはメニュー項目をクリックして対応するコマンド
キーバインディングを実行しますコマンドに関連付けられたショートカットキーユーザーが特定のショートカットキーを押すと、対応するコマンド
言語が実行され、ファイルタイプ関連付けられるか、新しい言語が展開されます。ユーザーが特定のファイルタイプ(特定の要件を満たす)を開くと、対応するコマンドが実行されます。
デバッガーVSを介してデバッガーを追加しますコードデバッグプロトコルとIDE通信
ブレークポイントデバッガーと連携し、デバッガーが(プログラミング)言語タイプの
文法をサポートすることを宣言しますTextMate構文の説明を追加し、
テーマを強調表示する構文カスタムテーマ
スニペットを追加しますコードスニペットを追加します
jsonValidationjson形式の検証
ビューを追加します左のファイルを追加しますビューアビューとデバッグビューは
、エラーマッチングを追加するためproblemMatchersに分割され、エラーや警告などの
problemPatternsがlintの結果から解析されます。problemMatchersでは、マッチングモード
メニューを定義することが、UIを拡張する唯一の公式な方法です。拡張をサポートするメニューは次のとおりです。

コマンドパレット検索ボックスの下部メニューcommandPalette
ファイルビューア右クリックメニューエクスプローラ/コンテキスト
エディタ
右クリックメニューエディタ/コンテキスト
タイトルバーメニューエディタ/タイトル
タイトルバー右クリックメニューエディタ/タイトル/コンテキスト
デバッグビュー
コールスタック右クリックメニューdebug / callstack / context
SCM(ソースコード管理)ビュー
タイトルバーメニューscm /タイトル
ファイルグループ化メニューscm / resourceGroup /コンテキスト
ファイルステータスメニューscm /リソース/コンテキスト
ファイル変更メニューscm /変更/タイトル
左ビュー
ファイルビューアサブ列ビュー/タイトル
デバッグビューサブ列ビュー/ item / context
P.S.はすべて目立たない場所であり、大幅なUIのカスタマイズはサポートされていません。たとえば、左側のサイドバー(アクティビティバー)にアイコンを追加することはできません。

タイトルバーのメニュー拡張機能はカスタムアイコンをサポートしていますが、定義がおかしいです。例:


"commands": [{
  "command": "markdown.showPreviewToSide",
  "title": "%markdown.previewSide.title%",
  "category": "Markdown",
  "icon": {
    "light": "./media/PreviewOnRightPane_16x.svg",
    "dark": "./media/PreviewOnRightPane_16x_dark.svg"
  }
}],
"menus": {
        "editor/title": [
            {
                "command": "markdown.showPreviewToSide",
                "when": "editorLangId == markdown",
                "alt": "markdown.showPreview",
                "group": "navigation"
            }
  ]
}

コマンドのアイコンを定義すると、メニューがコマンドに関連付けられ、メニューに対応するアイコンが表示されます

拡張API
環境を分離すると、プラグインで使用できるAPIを厳密に制限することがはるかに簡単になります。プラグインはIDEによって提供される拡張可能なAPIにのみアクセスでき、混乱することはありません(公式にサポートされているテーマのカスタマイズ項目を除き、UI DOMとスタイルの変更など)。

API設計原則
プラグインAPIは、いくつかの原則に従います。

Promiseに基づく:非同期操作はすべてPromiseによって記述されます

キャンセルトークン:キャンセルステータスを確認してキャンセル通知を受け取るための追加パラメーターとしてCancellationTokenを渡します

解放可能なリソース管理:イベントの監視、コマンド、UIの相互作用など、保持されているすべてのリソースを手動で解放する必要があります。

イベントAPI:サブスクリプションメソッドを呼び出し(on [Will | Did] VerbNoun)、リスナーを渡し(イベントパラメータを受信)、Disposableを返します

厳密なnullチェック:TypeScriptを使用して未定義とnullを厳密に区別します

PS「使い捨て」の詳細については、廃棄パターンを参照してください。

APIの概要
APIは名前名ごとに編成されており、グローバル名前付けは次のとおりです。

コマンド実行/登録コマンド、IDE自体と他のプラグイン登録コマンドの両方(executeCommandなど)
デバッグ関連API(startDebugging
env IDE関連環境情報(machineId、sessionId
拡張、クロスプラグインAPI呼び出し、extensionDependencyなど)など)は、プラグインが
言語プログラミングに依存することを宣言しますcreateDiagnosticCollection、registerDocumentFormattingEditProvider
scmなどの言語関連API、createSourceControl
ウィンドウエディタなどのソースコードバージョン制御API onDidChangeTextEditorSelection、createTerminal、showTextDocument
ワークスペースなどのウィンドウ関連API findFiles、openTextDocumentなどのワークスペースレベルのAPI(作業スペースはフォルダが開いている場合にのみ使用可能) 、saveAllは、
たとえば、workspace.findFiles + languages.registerDefinitionProviderを介してHasteのグローバルモジュールリファレンスジャンプサポートを実装できます。

さらに、vscode.previewHtml、vscode.openFolder、editorScrollなどの一部のAPIは、コマンド(上記の「IDE独自の」コマンド)の形式で提供されます。

プロトコルベースの拡張
プラグインプロセスは、特定のプロトコルを介してIDEと通信します。実装はJSON形式のstdin / stdoutです。

このモデルのより強力な点は、合意された通信プロトコルに準拠している限り、プラグインを任意の言語で実装できることです。

4.言語関連の拡張機能
は、構文の強調表示、コードスニペット、および構成ファイルを介したスマートブラケットの照合をサポートし、より複雑な拡張機能は、拡張APIまたは言語サーバーを介して実行されます。

構成タイプの拡張
構文の強調表示:文字列、コメント、キーワードなどの文法的な役割を区別するための基本的なサポート、および変数や関数の参照などの意味上の区別のための高度なサポート

コードスニペット:スニペットのクイック入力、単純なプレースホルダーの基本的なサポート、ネストされたプレースホルダーの高度なサポート

スマートブラケットマッチング:ブラケット、引用符、クロスラインコメントなど、ペアで表示されるものを自動的に補足するための高度なサポート。

言語拡張VSコードは、標準のText Mate Grammar(tmLanguage形式)をサポートしていることに注意してください。たとえば、MonacoEditorの非主流のMonarchスタイルの方がはるかに使いやすいです。詳細については「色付けの明確化」を参照してください。


簡単に構成できないプログラムによる拡張は、拡張API(書き込みプラグイン)を介して実現されます。2つの方法があります。

完全に独立した言語サーバープロトコルとIDE間の通信を実現

プロバイダーを登録して、フックと同様のカスタム機能を提供します

使用中、前者は面倒ですがより強力で柔軟性があり、後者は便利で直接的ですがそれほど柔軟ではありません。サポートされている拡張機能は次のとおりです。

ホバーのヒント:基本的なサポートタイプ、ドキュメントおよびその他の情報、高度なサポートメソッドの署名構文の強調表示

完了のヒント:高度なサポートでは、完了のヒントの横に追加情報が表示されます

エラーの確認:保存時に開いたファイルの内容のエラーを確認および報告するための基本的なサポート、開いたファイルディレクトリ内のリソースのエラーを確認および報告するための高度なサポート

メソッドシグネチャ:基本サポートには、メソッドシグネチャにパラメータ記述ドキュメントが含まれます

定義にジャンプ:基本的なサポートは、複数の定義がある場合に表示されます

参照検索:基本サポートは、すべての参照の特定の場所を返します

検索のハイライトを選択:基本サポートは、現在のドキュメント内のすべての同じ参照を返します

メソッド/変数宣言ディレクトリ:基本サポートは、ドキュメントで宣言されているすべての識別子とその定義場所を返します

クイックフィックス:警告とエラーの提案、クイックフィックス。エラー修正アクションの基本サポート、機能を提案するための反復コードなどのソースコード変更の高度なサポート

コンテキスト操作オプション:ユーザーのコードコンテキストに基づいて、追加情報と操作オプションを提供できます。基本サポート表示、上級者はカスタムコマンドを追加できます

名前の変更:Basicは参照による名前の変更をサポートしていませんが、高度なサポートはワークスペースでのクロスファイルの名前変更をサポートしています

コードフォーマット:基本はコードフォーマットをサポートしていません、高度なサポートは全文/選択/入力でフォーマットされています

V.開発ステップの
環境要件
VSコード

Yeoman and Yo Code – Extension Generator:npm install -g yogenerator-コードを1つのステップで実行します


スキャフォールディングを介してプロジェクトテンプレートを生成する手順

yo code
コマンドは、プラグインタイプをインタラクティブに選択します


New Extension (TypeScript)
New Extension (JavaScript)
New Color Theme
New Language Support
New Code Snippets
New Extension Pack

TypeScriptをお勧めします。その他は文字通りです。ExtensionPack(プラグインパック)はより興味深いものです。つまり、Nuclide of React Nativeと同様に、プラグインによってアセンブルされたプラグインです。

プラグイン名とその他のメタ情報を入力してプラグインプロジェクトを取得し、VSコードを使用してプロジェクトを個別に開きます(ワークスペースに他のプロジェクトディレクトリを含めることはできません)。F5はデバッグを開始してプラグインデバッグに入ります。

プラグインエントリファイルはmy-extension / src / extension.tsであり、プロジェクト構造の仕様はVSコードの組み込みプラグインを参照できます。


// ref: https://github.com/Microsoft/vscode/tree/master/extensions/markdown
markdown/
  media/
    *.svg
    *.css
  snippets/
    markdown.json
  syntaxes/
    *.tmLanguage
  src/
    features/
      *Provider.ts
    typings/
      *.d.ts
    commandManager.ts
    commands.ts
    logger.ts
    markdownEngine.ts
    security.ts
    telemetryReporter.ts


6.パッケージリリースはCLIツールを提供します。vsce:


パックには、-g VSCEをインストールNPM
プラグインディレクトリにと.vsixファイルにそれをパック:


cd my-extension
vsce package

my-extesion.vsixのローカルパッケージ(node_modulesの依存関係を含む)を取得します。公開したくない場合は、インストールを自分で広める方法を見つけることができます。npmレジストリとは異なり、コピーを手動でデプロイして、プライベートプラグインをイントラネット環境であるVisual StudioMarketplaceに配置できるためです。 (VSコードプラグイン市場)そのようなオープンマインドはありません:


If you want to share your extension with others privately, you can send them your packaged extension .vsix file.

(见他人と個人的に共有する)

Visual Studio Marketplaceのセットをデプロイする方法はないため、自動ダウンロード/インストールのプロンプトなど、プラグインの更新の問題を手動で解決する方法しか見つかりません。

公開
プラグインマーケットを公開するには、いくつかのことを行う必要があります。

Visual Studio TeamServicesアカウントを登録する

[セキュリティ]ページに移動して、パーソナルアクセストークンを作成します

パブリッシャーを追加するvscecreate-publisher(パブリッシャー名)コマンド

vsce login(パブリッシャー名)コマンドlogin

公開するvscepublish -p <token>コマンド

詳細については、拡張機能の公開を参照してください


VisualStudioコードの拡張に関するリファレンス

おすすめ

転載: blog.51cto.com/15080030/2592713