Heim > Artikel > Web-Frontend > Wie konvertiert Babel die Syntax der ES6-Klasse?
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
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: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 oderhinzufü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 einObjekt 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
über astexplorer.net Der entsprechende AST-Knoten ist class
ClassDeclaration
in Vistor fest, was bedeutet, dass ich alle ClassDeclaration
Knoten im js-Code ClassDeclaration
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:
Den alten AST-Knoten abrufen
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)
Schleifen Sie das AST-Objekt des alten Knotens (mehrere Funktionsknoten werden durchgeschleift)
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
, 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
ein. Die Schleife endet und fügen Sie den Knoten constructor
in es5Fns
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 == 'constructor') { 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('prototype'), 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
Ausführen
Nach dem Packen sehen wirnpm start
Die Syntax wurde nacheinander erfolgreich in es5-Funktionen konvertiert. class
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!