Methode der Toolbibliothek zur Generierung von Vue-Komponentendokumenten

Methode der Toolbibliothek zur Generierung von Vue-Komponentendokumenten

Die beiden Dinge, die Programmierer am meisten hassen, sind das Schreiben von Dokumentationen und das Nichtschreiben von Dokumentationen. Gibt es eine Möglichkeit, Dokumente direkt auf Grundlage von Vue-Komponenten zu erstellen? Natürlich gibt es die. Allerdings können Anwendungen von Drittanbietern möglicherweise nicht in Verbindung mit vorhandenen Projekten verwendet werden und erfordern häufig zusätzliche Anmerkungen, um die extrahierten Informationen zu markieren. Einige häufige Probleme bei der Verwendung von Drittanbietern

  • Die Informationen zur Dokumentextraktion sind nicht umfassend. Möglicherweise müssen Sie einige Informationen extrahieren, dies wird jedoch nicht unterstützt. In diesem Fall können Sie nur den Quellcode des Plug-Ins von Drittanbietern ändern.
  • Zur Markierung der Methode sind zusätzliche Annotationsinformationen erforderlich. Beispielsweise muss vuese die Methode mit @vuese, @arg usw. markieren, um Methodeninformationen bereitzustellen.

Wie das Sprichwort sagt: Selber machen erfolgreich. Erstellen Sie Ihr eigenes Vue-Tool zur Dokumenterstellung und verwenden Sie es in Verbindung mit Ihrem eigenen Projekt. Ein Komponentendokument muss im Allgemeinen den Komponentennamen und die Komponentenbeschreibung (Name), Komponenteneigenschaften (Props), Komponentenmethoden (Methoden), Komponentenereignisse (Ereignis), Slots (Slot) und Kommentare zu diesen Teilen bereitstellen, um Beschreibungsinformationen zu generieren. Als nächstes werden wir die Extraktion einzelner Teile Schritt für Schritt durchführen.

Analysieren von VUE-Dateien

Im Allgemeinen ist eine VUE-Datei in drei Teile unterteilt: Vorlage, Skript und Stil. Wir benötigen den Inhalt des Stilteils nicht, daher müssen wir den Vorlagen- und Skriptinhalt separat extrahieren. Vue hat die Bibliothek Vue-template-compiler offiziell speziell für das Vue-Parsing entwickelt. Wir können sie direkt zum Parsen und Extrahieren von .vue-Dateien verwenden. Vue-template-compiler bietet eine parseComponent-Methode zum Verarbeiten der ursprünglichen Vue-Datei.

const-Compiler = erforderlich('vue-template-compiler')
const Ergebnis = Compiler.parseComponent(vueStr, [Optionen])

// parseComponent gibt Vorlage, Skript und Stilinhalt zurück,
Schnittstelle SFCDescriptor exportieren {
  Vorlage: SFCBlock | nicht definiert;
  Skript: SFCBlock | nicht definiert;
  Stile: SFCBlock[];
  benutzerdefinierteBlöcke: SFCBlock[];
}

Nachdem Sie den Text jedes Teils erhalten haben, müssen Sie ihn auch in AST (abstrakter Syntaxbaum) konvertieren. Der Vorlagenteil kann direkt die vom Vue-Vorlagencompiler bereitgestellte Kompilierungsmethode verwenden, um AST zu generieren. Der Skriptteil muss andere Methoden verwenden, um AST zu generieren. Hier wird das Babel-Modul verwendet, um den JS-Text zu verarbeiten.

const-Compiler = erforderlich('vue-template-compiler')
//vueStr .vue-Dateiinhalt const vue = compiler.parseComponent(vueStr)

//AST für HTML-Teil generieren 
let template = compiler.compile(vue.template.content, {
    preserveWhitespace: false,
    comments: true // Kommentarinformationen generieren})

Verwenden Sie @babel/parser (Babel-Parser, der in Babel verwendete JavaScript-Parser), um JS-Textinhalte zu verarbeiten.

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

//Ast für JS-Teil generieren
let jsAst = parse.parse(vue.script.content, {
    allowImportExportEverywhere: true 
})

Dokumentinformationen extrahieren

Durch die Dateianalyse im vorherigen Schritt haben wir erfolgreich den Vue-Vorlagen-AST und den JS-AST im Skript erhalten. Der nächste Schritt besteht darin, die gewünschten Informationen daraus zu erhalten. Hier müssen Sie das Tool @babel/traverse verwenden, ein Knotentool zum Durchlaufen von JS-AST. Sie können den generierten Inhalt von ast hier anzeigen, was zum Anzeigen verschiedener Knoteninformationen praktisch ist.

const traverse = erfordern('@babel/traverse');
traverse.default(jsAst, {
  enter(Pfad){ // Start},
  //Unterstützen Sie benutzerdefinierte Knoten. Wenn der Knotentyp beispielsweise ExportDefaultDeclaration ist, löschen Sie diese Methode ExportDefaultDeclaration(){

  }
})

Extrahieren Sie Komponentennamen, Beschreibung, Eigenschaften, Methoden und Modelle

Der entsprechende, durch Exportstandard generierte Knotentyp ist ExportDefaultDeclaration. Das Deklarationsattribut sind die Optionen der entsprechenden Komponente. Durch Durchlaufen der Deklarationsattribute können Sie Knoteninformationen wie Name, Eigenschaften, Methoden, Modell usw. abrufen.

Beispiel

let componentInfo = {}
traverse.default(jsAst, {
  ExportDefaultDeclaration(Pfad){
    Pfad.Knoten.Deklaration.Eigenschaften.fürJedes(Element => {
        Schalter (Artikel.Schlüssel.Name) {
            Fall 'Requisiten':
                componentInfo.props = extractProps(item) // Props extrahieren
                brechen;
            Fall 'Methoden':
                componentInfo.methods = extractMethods(item) // Methoden extrahieren
                brechen
            Fall 'Name':
                componentInfo.name = item.value.value // Den Komponentennamen abrufen break
            Fall 'Modell':
                componentInfo.model = extractModel(item) // Modell extrahieren
                brechen
            Standard:
                brechen;
        }
    });
  }
})

Beschreibung des Extrakts

Kommentare in js werden in einzeilige und mehrzeilige Typen unterteilt. Beim Generieren von ast werden auch verschiedene Typen generiert. Siehe das Beispiel unten.

/** 
 *Mehrzeilige Notizen* Dient zum Hochladen von Dokumentinformationen*/
// Einzeiliger Kommentar export default {
}
// Kommentar beenden

Sie können sehen, dass es zwei Arten von Knoten gibt: CommentBlock und CommentLine. Die Kopfkommentare werden in führenden Kommentaren platziert und die unteren Kommentare in den nachfolgenden Kommentaren.


Im Allgemeinen wird der Kommentar zur Komponentenbeschreibung in die Exportvorgabe eingefügt und die Kommentarinformationen werden einfach extrahiert.

// ExportDefaultDeclaration füge den folgenden Code ein if (path.node.leadingComments) {
    componentInfo.desc = Pfad.Knoten.führendeKommentare.map(item => {
        wenn (Element.Typ === 'CommentLine') {
            returniere item.value.trim()
        } anders {
            returniere item.value.split('\n').map(item => item.replace(/[\s\*]/g, '')).filter(Boolean)
        }
    }).toString()
}

Extraktionsmethoden

Da die Kommentare in Methoden zusätzliche Beschreibungen von Ausgabeparametern, Eingabeparametern und anderen Informationen benötigen, die zusätzliche Verarbeitung erfordern, ist der jsdoc-Kommentarstandard immer noch relativ beliebt. Hier können Sie die Extraktionsregeln entsprechend Ihren Anforderungen definieren und müssen auch asynchron extrahieren, um festzustellen, ob es sich um eine asynchrone Funktion handelt.

/**
 * Methodenbeschreibung * @param {Bool} Typparameterbeschreibung * @returns Rückgabewertbeschreibung */

Requisiten extrahieren

Bei der Extraktion von Requisiten müssen die folgenden Situationen unterschieden werden. Es ist immer noch etwas mühsam, Standard und Validator zu extrahieren. Die Validator-Verifizierung kann durch einfache Beschreibung von Kommentaren extrahiert werden, aber der Standard ist nicht einfach zu handhaben.

{
    propA: Zahl, // einziger Typ propB: [String, Zahl], // einziger Typ, aber unterstützt mehrere propC: { 
      Typ: Zeichenfolge,
      erforderlich: true
    },
    EigenschaftD: {
      Typ: Nummer,
      default: 100 // mit Standardwert},
    Eigenschaft: {
      Typ: Objekt,
      default () { // Der Standardwert erfordert, dass die Funktion return { message: 'hello' } zurückgibt.
      }
    },
    propF: {
      Standard: Funktion () { // Der Standardwert erfordert, dass die Funktion einen anderen AST-Knotentyp zurückgibt als den oben angegebenen Standardwert return { Nachricht: „Hallo“ }
      }
      Validator: Funktion (Wert) { // prüfen return ['Erfolg', 'Warnung', 'Gefahr'].indexOf(Wert) !== -1
      }
    }
}

Hier verwende ich @babel/generator, um den Standardcode zu konvertieren, und konvertiere ihn durch eval in einen Funktionsaufruf, um den Standardwert zurückzugeben. Typen ist das Modul @babel/types, das verwendet wird, um den Knotentyp zu bestimmen.

// Den Standardwert der Props-Funktion getDefaultVal (Knoten) abrufen {
    wenn (Typen.isRegExpLiteral(Knoten) || Typen.isBooleanLiteral(Knoten) || Typen.isNumericLiteral(Knoten) || Typen.isStringLiteral(Knoten)) {
        Knotenwert zurückgeben
    } sonst wenn (Typen.isFunctionExpression(Knoten) || Typen.isArrowFunctionExpression(Knoten) || Typen.isObjectMethod(Knoten)) {
        versuchen {
            let code = generate.default(types.isObjectMethod(node) ? node.body : node).code
            lass Spaß = eval(**0,${types.isObjectMethod(node) ? 'function ()' : ''} $[code]**)
            gibt JSON.stringify(fun()) zurück
        } Fehler abfangen {
        }
    }
}

Modell extrahieren

Dies ist relativ einfach und kann direkt über den Browser durchgeführt werden.

Extrahieren von Komponentenereignissen

Das Ereignis einer Komponente kann nicht direkt vom entsprechenden Knoten abgerufen werden. Die Ereignisposition kann nur über die Methode $emit ermittelt werden. Beim Durchlaufen kann MemberExpress (komplexer Knotentyp) verwendet werden. Ob es sich um ein Ereignis handelt, lässt sich dann anhand des Attributnamens auf dem Knoten $emit ermitteln.

Sie können sehen, dass sich der Ereignisname in den Argumenten des übergeordneten MemberExpress-Elements befindet und die Kommentare sich auf der Ebene darüber befinden.

const extractEvents = (Pfad) => {
    // Das erste Element ist der Ereignisname const eventName = path.parent.arguments[0]; 
    let comments = Pfad.übergeordneterPfad.übergeordneter.führendeKommentare
    zurückkehren {
        Name: Ereignisname.Wert,
        Beschreibung: Kommentare? Kommentare.map(item => item.value.trim()).toString() : '——'
    }
}

MemberExpression (Pfad) {
    // Bestimmen Sie, ob es sich um ein Ereignis handelt
    wenn (Pfad.Knoten.Eigenschaft.Name === '$emit') {
        let event = extractEvents(Pfad)
        !componentInfo.events && (componentInfo.events = {});
        wenn (KomponentenInfo.events[Ereignis.Name]) {
            componentInfo.events[Ereignisname].desc = Ereignis.desc ? Ereignis.desc : componentInfo.events[Ereignisname].desc
        } anders {
            componentInfo.events[Ereignis.Name] = Ereignis
        }
    }
}

Nachdem Sie Events erfolgreich erhalten haben, können Sie durch Kombinieren von Events, Props und Model weiter bestimmen, ob das Attribut .sync und v-model unterstützt.

Komponentensteckplätze extrahieren

Zuerst müssen Sie eine Funktion schreiben, um den AST der Vue-Vorlage zu durchlaufen. Der Vue-Template-Compiler bietet keine Funktion ähnlich zu @babel/traverse zum Durchlaufen des AST.

Einfache Implementierung einer abstrakten Traversal-Vorlagenbaumfunktion

const traverserTemplateAst = (ast, Besucher = {}) => {
    Funktion traverseArray (Array, übergeordnetes Element) {
        array.fürJedes(Kind => {
            traverseNode(Kind, Elternteil);
        });
    }

    Funktion traverseNode (Knoten, übergeordneter Knoten) {
        Besucher.eintreten und Besucher.eintreten (Knoten, übergeordnetes Element);
        Besucher[Knoten.Tag] && Besucher[Knoten.Tag](Knoten, übergeordneter Knoten);
        Knoten.Kinder und traverseArray(Knoten.Kinder, Knoten);
        Besucher.exit und Besucher.exit (Knoten, übergeordnetes Element);
    }

    traverseNode(ast, null);
}

Die Struktur des AST des Vue-Templates ist relativ übersichtlich. Es gibt nicht so viele Typen wie das JS-AST. Man muss nur zwischen verschiedenen Tags unterscheiden. Kommentare werden in separate Knoten aufgeteilt. Wenn Sie also nach einem Slot-Knoten suchen, müssen Sie auch den vorherigen benachbarten Knoten finden, um zu bestimmen, ob es sich um einen Kommentar handelt.

traverserTemplateAst(template.ast, {
    Slot (Knoten, übergeordnetes Element) {
        !componentInfo.slots && (componentInfo.slots = {})
        // Holen Sie sich die Knotenposition let index = parent.children.findIndex(item => item === node)
        let desc = 'Keine Beschreibung', name = '-';
        wenn (Index > 0) {
            let tag = übergeordnetes Element.untergeordnetes Element[index - 1]
            // isComment bestimmt, ob es ein Kommentar ist, if (tag.isComment) {
                desc = tag.text.trim()
            }
        }
        wenn (Knoten.SlotName) Name = Knoten.attrsMap.name
        componentInfo.slots[Name] = {
            Name,
            Beschreibung
        }
    }
})

Abschluss

Bisher haben wir lediglich die automatische Generierung von Vue-Komponenteninformationen realisiert. Natürlich gibt es noch einige Situationen, die nicht berücksichtigt wurden, wie z. B. das Ereignis $emit in der Vorlage und den Slot in der Renderfunktion. Die Implementierung zum Extrahieren dieses Teils ist jedoch ähnlich. Den Quellcode dieses Artikels können Sie hier einsehen.

Dies ist das Ende dieses Artikels über die Methoden der Vue-Komponentendokumentgenerierungstoolbibliothek. Weitere relevante Inhalte zum Vue-Komponentendokumentgenerierungstool finden Sie in früheren Artikeln auf 123WORDPRESS.COM oder in den folgenden verwandten Artikeln. Ich hoffe, dass jeder 123WORDPRESS.COM in Zukunft unterstützen wird!

Das könnte Sie auch interessieren:
  • Implementierung von Vue-Scope-Slots aus der Komponentenkapselung
  • So kapseln Sie Modellkomponenten in Vue 2.0
  • Detaillierte Erläuterung der Hinweise zur Generierung von Vue-Komponentendokumenten

<<:  VirtualBox installiert die virtuelle Maschine CentOS7 und Erweiterungstools (Bild und Text)

>>:  Detaillierte Erklärung der MySQL/Java-Server-Unterstützung für Emoji und Problemlösung

Artikel empfehlen

Warum sollten Sie mit der add_header-Direktive von Nginx vorsichtig sein?

Vorwort Wie wir alle wissen, legt die Nginx-Konfi...

Vue-Handschrift-Ladeanimationsprojekt

Wenn die Seite nicht reagiert, ist die Anzeige de...

Tutorial zur HTML-Tabellenauszeichnung (15): Tabellentitel

<br />Mit diesem Tag können Sie direkt einen...

Vue implementiert eine Scroll-Ladetabelle

Inhaltsverzeichnis Ergebnisse erzielen Wissensres...

Vollbild-Drag-Upload-Komponente basierend auf Vue3

In diesem Artikel wird hauptsächlich die Vollbild...

CSS-Pseudoklasse: empty makes me shine (Beispielcode)

Jeder, der meine Artikel in letzter Zeit gelesen ...

So verwenden Sie JS WebSocket zur Implementierung eines einfachen Chats

Inhaltsverzeichnis Kurze Umfrage Langfristige Abf...