Vueコンポーネントドキュメント生成ツールライブラリのメソッド

Vueコンポーネントドキュメント生成ツールライブラリのメソッド

プログラマーが最も嫌うことは、ドキュメントを書くことと、他の人がドキュメントを書かないことです。 Vue コンポーネントに基づいて直接ドキュメントを生成する方法はありますか?もちろんありますよ。ただし、サードパーティのアプリケーションは既存のプロジェクトと組み合わせて使用​​できない場合があり、抽出された情報をマークするために追加の注釈が必要になることがよくあります。サードパーティを利用する際によくある問題

  • ドキュメント抽出情報は包括的ではありません。抽出する必要がある情報があるかもしれませんが、サポートされていません。この場合、サードパーティのプラグインのソースコードのみを変更できます。
  • メソッドをマークするには、追加のアノテーション情報が必要です。たとえば、vuese はメソッド情報を提供するために、メソッドを @vuese、@arg などでマークする必要があります。

諺にあるように、DIY は繁栄をもたらします。独自の Vue ドキュメント生成ツールを作成し、独自のプロジェクトと組み合わせて使用​​してください。コンポーネント ドキュメントでは通常、コンポーネント名と説明 (name)、コンポーネント プロパティ (props)、コンポーネント メソッド (methods)、コンポーネント イベント (event)、スロット (slot)、およびこれらの部分に関するコメントを指定して、説明情報を生成する必要があります。次に、いくつかの部分の抽出を段階的に実装します。

.vue ファイルの解析

通常、.vue ファイルは、テンプレート、スクリプト、スタイルの 3 つの部分に分かれています。スタイル部分の内容は必要ないので、テンプレートとスクリプトの内容を個別に抽出する必要があります。 Vue は、Vue 解析専用の Vue-template-compiler ライブラリを公式に開発しました。これを直接使用して、.vue ファイルを解析および抽出できます。Vue-template-compiler は、元の Vue ファイルを処理するための parseComponent メソッドを提供します。

const コンパイラ = require('vue-template-compiler')
const 結果 = コンパイラー.parseComponent(vueStr, [オプション])

// parseComponentはテンプレート、スクリプト、スタイルコンテンツを返します。
エクスポートインターフェースSFCDescriptor {
  テンプレート: SFCBlock | 未定義;
  スクリプト: SFCBlock | 未定義;
  スタイル: SFCBlock[];
  カスタムブロック: SFCBlock[];
}

各部分のテキストを取得した後、それを ast (抽象構文木) に変換する必要があります。テンプレート部分は、Vue-template-compiler が提供する compile メソッドを直接使用して ast を生成できます。スクリプト部分は、他のメソッドを使用して ast を生成する必要があります。ここでは、js テキストを処理するために babel モジュールを使用しています。

const コンパイラ = require('vue-template-compiler')
//vueStr .vue ファイルの内容 const vue =compiler.parseComponent(vueStr)

//HTML部分のASTを生成する 
テンプレートをcompiler.compile(vue.template.content, {
    空白を保持: false、
    comments: true // コメント情報を生成する})

js テキスト コンテンツを処理するために、@babel/parser (Babel パーサー、Babel で使用される JavaScript パーサー) を使用します。

const parse = require('@babel/parser');

//js 部分の ast を生成
jsAst = parse.parse(vue.script.content, { とします。
    どこでもインポートエクスポートを許可: true 
})

文書情報を抽出する

前のステップのファイル解析作業により、スクリプト内の Vue テンプレート ast と js ast を正常に取得できました。次のステップは、それらから必要な情報を取得することです。ここでは、js ast をトラバースするためのノード ツールである @babel/traverse ツールを使用する必要があります。ここでは、ast の生成されたコンテンツを表示できます。これは、さまざまなノード情報を表示するのに便利です。

traverse は '@babel/traverse' を必要とします。
トラバース.default(jsAst, {
  enter(path){ // 開始},
  //カスタムノードをサポートします。たとえば、ノードタイプが ExportDefaultDeclaration の場合は、このメソッドを削除します。ExportDefaultDeclaration(){

  }
})

コンポーネント名、説明、プロパティ、メソッド、モデルを抽出します

エクスポート デフォルトによって生成される対応するノード タイプは ExportDefaultDeclaration です。宣言属性は対応するコンポーネントのオプションです。宣言属性を走査することで、名前、プロパティ、メソッド、モデルなどのノード情報を取得できます。

コンポーネント情報 = {}
トラバース.default(jsAst, {
  エクスポートデフォルト宣言(パス){
    path.node.declaration.properties.forEach(item => {
        スイッチ (アイテム.キー.名前) {
            ケース 'props':
                componentInfo.props = extractProps(item) // プロパティを抽出
                壊す;
            ケース「メソッド」:
                componentInfo.methods = extractMethods(item) // メソッドを抽出
                壊す
            ケース '名前':
                componentInfo.name = item.value.value // コンポーネント名を取得
            ケース 'モデル':
                componentInfo.model = extractModel(item) // モデルを抽出
                壊す
            デフォルト:
                壊す;
        }
    });
  }
})

抜粋の説明

js 内のコメントは、単一行タイプと複数行タイプに分かれています。 ast を生成すると、異なるタイプも生成されます。以下の例を参照してください。

/** 
 *複数行のメモ* ドキュメント情報をアップロードするために使用*/
// 単一行コメント export default {
}
// コメント終了

CommentBlock と CommentLine の 2 種類のノードがあることがわかります。先頭のコメントは leadingComments に配置され、下部のコメントは trailingComments に配置されます。


通常、コンポーネントの説明コメントはエクスポートのデフォルトに配置され、コメント情報は単純に抽出されます。

// ExportDefaultDeclaration 次のコードを挿入します if (path.node.leadingComments) {
    コンポーネント情報.desc = path.node.leadingComments.map(item => {
        if (item.type === 'コメント行') {
            アイテム.値.トリム() を返す
        } それ以外 {
            item.value.split('\n').map(item => item.replace(/[\s\*]/g, '')).filter(Boolean) を返します。
        }
    }).toString()
}

抽出方法

メソッド内のコメントには、出力パラメータ、入力パラメータ、および追加処理を必要とするその他の情報の追加説明が必要であるため、jsdoc コメント標準は依然として比較的人気があります。ここでは、ニーズに応じて抽出ルールを定義できます。また、非同期関数であるかどうかを識別するために async を抽出する必要もあります。

/**
 * メソッドの説明 * @param {Bool} 型パラメータの説明 * @returns 戻り値の説明 */

小道具の抽出

プロパティの抽出では、以下の状況を区別する必要があります。デフォルトとバリデーターの抽出はまだ少し面倒です。バリデーターの検証はコメントの簡単な記述で抽出できますが、デフォルトの処理は簡単ではありません。

{
    propA: Number, // 型のみ propB: [String, Number], // 型のみだが複数をサポート propC: { 
      タイプ: 文字列、
      必須: true
    },
    プロップD: {
      タイプ: 数値、
      デフォルト: 100 // デフォルト値付き},
    プロップE: {
      タイプ: オブジェクト、
      default () { // デフォルト値は関数が返す必要があります return { message: 'hello' }
      }
    },
    プロップF: {
      default: function () { // デフォルト値では、関数は上記のデフォルトとは異なる ast ノード型を返す必要があります return { message: 'hello' }
      }
      バリデータ: function (value) { // チェック return ['success', 'warning', 'danger'].indexOf(value) !== -1
      }
    }
}

ここでは、@babel/generator を使用してデフォルトのコードを変換し、eval を介して関数呼び出しに変換してデフォルト値を返します。 types は、ノード タイプを決定するために使用される @babel/types モジュールです。

// Propsのデフォルト値を取得する function getDefaultVal (node) {
    type.isRegExpLiteral(node) || types.isBooleanLiteral(node) || types.isNumericLiteral(node) || types.isStringLiteral(node) の場合 {
        ノード値を返す
    } そうでない場合 (types.isFunctionExpression(node) || types.isArrowFunctionExpression(node) || types.isObjectMethod(node)) {
        試す {
            code = generate.default(types.isObjectMethod(node) ? node.body : node).code とします。
            fun = eval(**0,${types.isObjectMethod(node) ? 'function ()' : ''} $[code]**) とします。
            JSON.stringify(fun()) を返す
        } キャッチ(エラー){
        }
    }
}

モデルの抽出

これは比較的簡単で、直接取得することができます。

コンポーネントイベントの抽出

コンポーネントのイベントは、対応するノードから直接取得することはできません。イベントの位置は、$emit メソッドを通じてのみ特定できます。トラバースでは、MemberExpress (複合型ノード) を使用し、ノード上の属性名が $emit であるかどうかでイベントかどうかを判断できます。

イベント名は MemberExpress 親の引数にあり、コメントは 1 つ上のレベルにあることがわかります。

const extractEvents = (パス) => {
    // 最初の要素はイベント名です const eventName = path.parent.arguments[0]; 
    コメントを path.parentPath.parent.leadingComments とします。
    戻る {
        名前: イベント名.値、
        説明: コメント? comments.map(item => item.value.trim()).toString() : '——'
    }
}

メンバー式 (パス) {
    // イベントかどうかを判定する
    (path.node.property.name === '$emit')の場合{
        イベントをextractEvents(パス)とします
        !componentInfo.events && (componentInfo.events = {});
        if (componentInfo.events[イベント名]) {
            componentInfo.events[イベント名].desc = event.desc ? event.desc : componentInfo.events[イベント名].desc
        } それ以外 {
            componentInfo.events[イベント名] = イベント
        }
    }
}

イベントを正常に取得した後、イベント、プロパティ、モデルを組み合わせて、属性が .sync および v-model をサポートしているかどうかをさらに判断できます。

コンポーネントスロットの抽出

まず、Vue テンプレートの ast をトラバースする関数を記述する必要があります。Vue-template-compiler は、ast をトラバースするための @babel/traverse に似た関数を提供していません。

トラバーサルテンプレート抽象ツリー関数のシンプルな実装

const traverserTemplateAst = (ast、ビジター = {}) => {
    関数 traverseArray (配列、親) {
        配列.forEach(子 => {
            トラバースノード(子、親);
        });
    }

    関数 traverseNode (ノード、親) {
        visitor.enter && visitor.enter(ノード、親);
        訪問者[node.tag] && 訪問者[node.tag](ノード、親);
        node.children をトラバース配列に追加します。
        visitor.exit && visitor.exit(ノード、親);
    }

    トラバースノード(ast、null);
}

Vue テンプレートの ast の構造は比較的明確です。js ast ほど多くの型はありません。異なるタグを区別するだけで済みます。コメントは個別のノードに分割されるため、スロット ノードを検索するときは、コメントであるかどうかを判断するために、その前の隣接ノードも検索する必要があります。

トラバーサーテンプレートAst(template.ast, {
    スロット (ノード、親) {
        !componentInfo.slots && (componentInfo.slots = {})
        // ノードの位置を取得します。let index = parent.children.findIndex(item => item === node)
        let desc = '説明なし'、name = '-';
        (インデックス>0)の場合{
            タグ = 親.子[インデックス - 1]
            // isCommentはコメントかどうかを判定します。if (tag.isComment) {
                desc = タグ.テキスト.トリム()
            }
        }
        if (node.slotName) name = node.attrsMap.name
        コンポーネント情報.スロット[名前] = {
            名前、
            説明
        }
    }
})

結論

ここまでは、Vue コンポーネント情報の自動生成を実現しただけです。もちろん、テンプレート内のイベント $emit やレンダリング関数内のスロットなど、まだ考慮されていない状況がいくつかあります。ただし、この部分を抽出する実装は似ています。この記事のソースコードはここからご覧いただけます。

Vue コンポーネント ドキュメント生成ツール ライブラリのメソッドに関するこの記事はこれで終わりです。Vue コンポーネント ドキュメント生成ツールの関連コンテンツについては、123WORDPRESS.COM の過去の記事を検索するか、以下の関連記事を引き続き参照してください。今後とも 123WORDPRESS.COM をよろしくお願いいたします。

以下もご興味があるかもしれません:
  • コンポーネントのカプセル化からの Vue スコープ スロットの実装
  • Vue 2.0 でモデルコンポーネントをカプセル化する方法
  • Vueコンポーネントドキュメント生成ノートの詳細な説明

<<:  VirtualBox は CentOS7 仮想マシンと拡張ツールをインストールします (画像とテキスト)

>>:  絵文字と問題解決のためのMySQL/Javaサーバーサポートの詳細な説明

推薦する

IE6、IE7、IE8 で CSS3 の丸い角と影のスタイルをサポートする

CSS3 の角丸や影の効果を使ったページを作りたいのですが、IE ブラウザでは対応していません。こ...

Dockerコンテナとローカルマシン間でファイルを転送する方法

ホストとコンテナ間でファイルを転送するには、コンテナの完全な ID が必要です。取得方法は以下の通り...

MySQL 8.0.23 のレプリケーション アーキテクチャにおけるスレーブ ノードの自動フェイルオーバー

私はしばらく MGR と連絡を取り合ってきました。MySQL 8.0.23 の登場により、MySQL...

MySQLが間違ったインデックスを選択する理由と解決策

MySQL では、テーブルに複数のインデックスを指定できますが、ステートメントの実行時に、使用するイ...

カルーセル効果を書くためのjs

この記事では、カルーセルマップの効果を実現するためのjsの具体的なコードを参考までに共有します。具体...

MySQLクエリのパフォーマンスに影響を与える大きなオフセットの理由と最適化の詳細な説明

序文MySQL クエリは select コマンドを使用し、limit および offset パラメー...

JavaScript でのモグラ叩きゲームの実装

この記事では、モグラ叩きゲームを実装するためのJavaScriptの具体的なコードを参考までに紹介し...

Nginx 仮想ホストを構成する 3 つの方法 (ポートベース) の詳細な説明

Nginx は、IP ベースの仮想ホスト構成、ポート ベースの仮想ホスト構成、ドメイン名ベースの仮想...

JS 面接の質問: forEach はループから抜け出すことができますか?

この質問をされたとき、私は無知で頭が真っ白になりました。もちろん、正しく答えられませんでした。私はず...

dockerを使用してTomcatをデプロイし、Skywalkingに接続する

目次1. 概要2. dockerを使用してTomcatをデプロイし、Skywalkingに接続する要...

Vite+ElectronでVUE3デスクトップアプリケーションを素早く構築

目次1. はじめに2. Viteプロジェクトを作成する1. viteをインストールする2. プロジェ...

Vue SPA ファースト スクリーン最適化ソリューション

目次序文最適化ソ連オンデマンドインポート1. ルーティングファイルでコンポーネントをオンデマンドでイ...

js のマクロタスクとマイクロタスクについての簡単な説明

目次1. JavaScriptについて2. JavaScript イベントループ3. マクロタスクと...

Angularコンポーネント投影の詳細な説明

目次概要1. 簡単な例1.サブコンポーネントの<ng-content>ディレクティブを使...

JavaScript 文字列の一般的なメソッドの詳細な説明

目次1. キャラクター文法パラメータ索引戻り値2. 連結文法パラメータ文字列2 [, …文字列N]戻...