Heim  >  Artikel  >  Web-Frontend  >  Wie konvertiert Babel die Syntax der ES6-Klasse?

Wie konvertiert Babel die Syntax der ES6-Klasse?

php中世界最好的语言
php中世界最好的语言Original
2018-04-08 11:34:412221Durchsuche

Dieses Mal zeige ich Ihnen, wie Babel die Klassensyntax von es6 konvertiert. Was ist bei der Konvertierung von Babel in die Klassensyntax von es6 zu beachten? Das Folgende ist ein praktischer Fall, schauen wir uns das an.

Babel ist ein Transcoder, der derzeit bei der Entwicklung von React- und Vue-Projekten verwendet wird. Es kann die Syntax von es6+ in es5 sowie JSX und andere Syntax konvertieren.

In unseren Projekten konvertieren wir alle bestimmte Codes wie env, stage-0 usw., indem wir Plug-Ins und Presets (eine Sammlung mehrerer Plug-Ins) konfigurieren.

Tatsächlich kann Babel jeden Code über benutzerdefinierte Plug-ins konvertieren. Als Nächstes lernen wir Babel anhand eines Beispiels für die „Konvertierung von

von es6 in es5“ kennen. class

Der Inhalt ist wie folgt:

Webpack-Umgebungskonfiguration

Jeder sollte den Babel-Core-Loader und seine konfiguriert haben Rolle Es stellt die Kern-API von Babel bereit. Tatsächlich wird unsere Codekonvertierung über Plug-Ins implementiert.

Als nächstes implementieren wir selbst ein ES6-Klassenkonvertierungs-Plug-In, ohne Plug-Ins von Drittanbietern zu verwenden. Führen Sie zunächst die folgenden Schritte aus, um ein Projekt zu initialisieren:

  1. npm install webpack webpack-cli babel-core -D

  2. Erstellen Sie ein neues Webpack. config. js

  3. Webpack.config.js konfigurieren

Wenn unser Plug-in-Name „transform-class“ heißen soll, müssen wir das tun Nehmen Sie die folgende Konfiguration in der Webpack-Konfiguration vor:

Als nächstes erstellen wir einen Ordner der babel-plugin-transform-class in node_modules, um die Logik des Plug-ins zu schreiben (falls Es ist ein echtes Projekt, Sie müssen dieses Plug-in schreiben und im npm-Warehouse veröffentlichen), wie unten gezeigt:

Der rote Bereich ist mein neu erstellter Ordner und Oben ist eine Standard-Plug-in-Projektstruktur dargestellt. Der Einfachheit halber habe ich gerade die Kerndatei index.js geschrieben.

So schreiben Sie das Babel-Plug-In

Das Babel-Plug-In wird tatsächlich über AST (Abstract Syntax Tree) implementiert.

babel hilft uns, js-Code in AST zu konvertieren, ermöglicht uns dann, ihn zu ändern und ihn schließlich in js-Code zu konvertieren.

Es stellen sich also zwei Fragen: Wie ist die Zuordnungsbeziehung zwischen js-Code und AST? Wie kann man AST ersetzen oder

hinzufügen?

Okay, stellen wir zunächst ein Tool vor: astexplorer.net:

Dieses Tool kann einen Code in AST konvertieren:

Wie in der Abbildung gezeigt, haben wir eine es6-Klasse geschrieben und dann auf der rechten Seite der Webseite einen AST für uns generiert, der tatsächlich jede Codezeile in ein

Objekt umwandelte, sodass wir eine Zuordnung implementierten .

Wir stellen ein weiteres Dokument vor: babel-types:

Dies ist das API-Dokument zum Erstellen von AST-Knoten.

Wenn wir beispielsweise eine Klasse erstellen möchten, konvertieren wir sie zunächst in astexplorer.net und stellen fest, dass der der Klasse entsprechende AST-Typ

ist. Okay, lassen Sie uns in der Dokumentation suchen und feststellen, dass es ausreicht, nur die folgende API aufzurufen: ClassDeclaration

Dasselbe gilt für das Erstellen anderer Anweisungen Es wurden Umbauten vorgenommen.

Jetzt beginnen wir mit dem eigentlichen Schreiben eines Plug-Ins, das in die folgenden Schritte unterteilt ist:

  1. Eine Funktion in index.js exportieren

  2. Die Funktion gibt ein Objekt zurück und das Objekt verfügt über einen Besucherparameter (muss Besucher genannt werden)

  3. Abfrage

    über astexplorer.net Der entsprechende AST-Knoten ist classClassDeclaration

  4. Legen Sie eine Erfassungsfunktion

    in Vistor fest, was bedeutet, dass ich alle ClassDeclaration Knoten im js-Code ClassDeclaration

  5. Logikcode schreiben, um die Konvertierung abzuschließen
module.exports = function ({ types: t }) {
 return {
  visitor: {
   ClassDeclaration(path) {
    //在这里完成转换
   }
  }
 };
}

Es gibt zwei Parameter im Code. Die erste {types:t} Sache besteht darin, die Variable t aus den Parametern zu dekonstruieren, die eigentlich diejenige im Babel ist -Typendokument t (rotes Feld im Bild unten), das zum Erstellen von Knoten verwendet wird:

Der zweite Parameter path, bei dem es sich um die den erfassten Informationen entsprechenden Informationen handelt Knoten, wir Sie können den AST dieses Knotens über path.node abrufen und ihn auf dieser Basis ändern, um unser Ziel zu erreichen.

So konvertieren Sie ES6-Klassen in ES5-Klassen

Die oben genannten Punkte sind alles vorbereitende Arbeiten. Die eigentliche Logik beginnt jetzt. Betrachten wir zunächst zwei Fragen:

Wir müssen zunächst die ES6-Klassen in ES5-Klassen umwandeln (d. h. normale Funktionen). Codeblöcke innerhalb von Funktionen usw.

Wenn die constructor-Methode in der Klasse nicht definiert ist, fügt die JavaScript-Engine ihr automatisch eine leere constructor()-Methode hinzu, was erforderlich ist Wir führen eine Kompatibilitätsverarbeitung durch.

Als nächstes beginnen wir mit dem Schreiben von Code:

  1. Den alten AST-Knoten abrufen

  2. Erstellen Sie ein Array mit To Halten Sie den neuen AST-Knoten (obwohl die ursprüngliche Klasse nur ein Knoten ist, wird sie nach dem Ersetzen durch mehrere Funktionsknoten ersetzt). Initialisieren Sie den Standardknoten constructor (wie oben erwähnt, ist der Konstruktor möglicherweise nicht in der Klasse definiert)

  3. Schleifen Sie das AST-Objekt des alten Knotens (mehrere Funktionsknoten werden durchgeschleift)

  4. Bestimmen Sie, ob der Typ der Funktion constructor ist Wenn ja, erstellen Sie einen normalen Funktionsknoten, indem Sie die Daten abrufen, und aktualisieren Sie den Standardknoten constructor

  5. , um die verbleibenden Knoten zu verarbeiten, die nicht constructor sind. Erstellen Sie einen prototype Geben Sie function durch die Daten ein und geben Sie Go to es5Fns

  6. ein. Die Schleife endet und fügen Sie den Knoten constructor in es5Fns

  7. um festzustellen, ob die Länge von es5Fns größer als 1 ist. Wenn sie größer als 1 ist, verwenden Sie

    diese API, um den AST replaceWithMultiple

module.exports = function ({ types: t }) {
 return {
  visitor: {
   ClassDeclaration(path) {
    //拿到老的AST节点
    let node = path.node
    let className = node.id.name
    let classInner = node.body.body
    //创建一个数组用来成盛放新生成AST
    let es5Fns = []
    //初始化默认的constructor节点
    let newConstructorId = t.identifier(className)
    let constructorFn = t.functionDeclaration(newConstructorId, [t.identifier('')], t.blockStatement([]), false, false)
    //循环老节点的AST对象
    for (let i = 0; i < classInner.length; i++) {
     let item = classInner[i]
     //判断函数的类型是不是constructor
     if (item.kind == &#39;constructor&#39;) {
      let constructorParams = item.params.length ? item.params[0].name : []
      let newConstructorParams = t.identifier(constructorParams)
      let constructorBody = classInner[i].body
      constructorFn = t.functionDeclaration(newConstructorId, [newConstructorParams], constructorBody, false, false)
     } 
     //处理其余不是constructor的节点
     else {
      let protoTypeObj = t.memberExpression(t.identifier(className), t.identifier(&#39;prototype&#39;), false)
      let left = t.memberExpression(protoTypeObj, t.identifier(item.key.name), false)
      //定义等号右边
      let prototypeParams = classInner[i].params.length ? classInner[i].params[i].name : []
      let newPrototypeParams = t.identifier(prototypeParams)
      let prototypeBody = classInner[i].body
      let right = t.functionExpression(null, [newPrototypeParams], prototypeBody, false, false)
      let protoTypeExpression = t.assignmentExpression("=", left, right)
      es5Fns.push(protoTypeExpression)
     }
    }
    //循环结束,把constructor节点也放到es5Fns中
    es5Fns.push(constructorFn)
    //判断es5Fns的长度是否大于1
    if (es5Fns.length > 1) {
     path.replaceWithMultiple(es5Fns)
    } else {
     path.replaceWith(constructorFn)
    }
   }
  }
 };
}

Vererbung optimieren Tatsächlich beinhaltet die Klasse auch Vererbung, und die Idee ist nicht kompliziert. Sie bestimmt lediglich, dass es kein

-Attribut im AST gibt , müssen wir eine zusätzliche Codezeile

hinzufügen. Vergessen Sie natürlich nicht, das Schlüsselwort superClass zu berücksichtigen. Bird.prototype = Object.create(Parent)super

Gepackter Code

Ausführen

Nach dem Packen sehen wir

npm startDie Syntax wurde nacheinander erfolgreich in es5-Funktionen konvertiert. class

Ich glaube, dass Sie die Methode beherrschen, nachdem Sie den Fall in diesem Artikel gelesen haben. Weitere spannende Informationen finden Sie in anderen verwandten Artikeln auf der chinesischen PHP-Website!

Empfohlene Lektüre:

So führen Sie die Tencent-Verifizierungscode-Funktion in das Vue-Projekt ein


JS-Implementierung von Timer + Eingabeaufforderungsfeld

Das obige ist der detaillierte Inhalt vonWie konvertiert Babel die Syntax der ES6-Klasse?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn