Cette fois, je vais vous apporter un guide détaillé étape par étape pour convertir Babel en es6. Quelles sont les précautions pour convertir Babel en es6. Voici des cas pratiques, jetons un coup d'œil.
Babel est un transcodeur actuellement utilisé lors du développement de projets React et Vue. Il peut convertir la syntaxe es6+ en es5, ainsi que JSX et autres syntaxes.
Dans nos projets, nous convertissons tous des codes spécifiques, tels que env, stage-0, etc., en configurant des plug-ins et des préréglages (une collection de plusieurs plug-ins).
En fait, Babel peut convertir n'importe quel code via des plug-ins personnalisés. Ensuite, découvrons Babel à travers un exemple de « conversion d'es6 class
en es5 ».
Le contenu est le suivant :
Configuration de l'environnement webpack
Tout le monde devrait avoir configuré le chargeur babel-core et son rôle Il fournit l'API de base de Babel. En fait, notre conversion de code est implémentée via des plug-ins.
Ensuite, nous implémenterons nous-mêmes un plug-in de conversion de classe es6 sans utiliser de plug-ins tiers. Effectuez d'abord les étapes suivantes pour initialiser un projet :
npm install webpack webpack-cli babel-core -D
Créez un nouveau webpack. config.js
Configurer webpack.config.js
Si le nom de notre plug-in veut être appelé transform-class, nous devons le faire. faites la configuration suivante dans la configuration du webpack :
Ensuite, nous créons un nouveau dossier de babel-plugin-transform-class dans node_modules pour écrire la logique du plug-in ( s'il s'agit d'un vrai projet, vous devez écrire ce plug-in et le publier sur npm Warehouse), comme indiqué ci-dessous :
La zone rouge est mon dossier nouvellement créé, et au-dessus se trouve une structure de projet de plug-in standard. Pour plus de commodité, je viens d'écrire le fichier principal index.js.
Comment écrire un plug-in Babel
Le plug-in Babel est en fait implémenté via AST (Abstract Syntax Tree).
babel nous aide à convertir le code js en AST, puis nous permet de le modifier, et enfin de le convertir en code js.
Il y a donc deux questions en jeu : quelle est la relation de mappage entre le code js et AST ? Comment remplacer ou ajouterAST ?
Bien, introduisons d'abord un outil : astexplorer.net :
Cet outil peut convertir un morceau de code en AST :
Comme le montre la figure , nous avons écrit une classe es6, puis le côté droit de la page Web a généré un AST pour nous, qui a en fait transformé chaque ligne de code en un objet , de sorte que nous avons implémenté un mappage .
Présentation d'un autre document : babel-types :
Ceci est le document API pour créer des nœuds AST.
Par exemple, si nous voulons créer une classe, nous la convertissons d'abord dans astexplorer.net et constatons que le type AST correspondant à la classe est ClassDeclaration
. D'accord, cherchons dans la documentation et constatons qu'il suffit d'appeler l'API suivante :
Il en va de même pour la création d'autres instructions. Avec les deux choses ci-dessus, nous ne pouvons pas. des conversions ont été effectuées.
Maintenant, nous commençons à écrire un plug-in, qui est divisé en les étapes suivantes :
Exporter une fonction dans index.js
La fonction renvoie un objet, et l'objet a un paramètre visiteur (doit être appelé visiteur)
Requête via astexplorer.netclass
Le nœud AST correspondant est ClassDeclaration
Définir une fonction de capture ClassDeclaration
dans vistor, ce qui signifie que je veux capturer tous les ClassDeclaration
nœuds dans le code js
Écrivez le code logique pour terminer la conversion
module.exports = function ({ types: t }) { return { visitor: { ClassDeclaration(path) { //在这里完成转换 } } }; }
Il y a deux paramètres dans le code La première {types:t}
chose est de déconstruire la variable t à partir des paramètres, qui est en fait celle de babel. -types le document t (encadré rouge dans l'image ci-dessous), qui sert à créer des nœuds :
Le deuxième paramètre path
, qui est l'information correspondant au capturé nœud, nous pouvons obtenir l'AST de ce nœud via path.node
, et le modifier sur cette base pour atteindre notre objectif.
Comment convertir des classes es6 en classes es5
Ce qui précède sont tous des travaux préparatoires, la vraie logique commence à partir de maintenant, considérons d'abord deux questions :
Nous devons effectuer la conversion suivante. Tout d'abord, convertir les classes es6 en écriture de classe es5 (c'est-à-dire des fonctions ordinaires). Nous avons observé que beaucoup de code peut être réutilisé, y compris les noms. blocs de code à l'intérieur des fonctions, etc.
Si la méthode constructor
de la classe n'est pas définie, le moteur JavaScript y ajoutera automatiquement une méthode constructor()
vide, ce qui nécessite Nous effectuons un traitement de compatibilité.
Ensuite, nous commençons à écrire du code. L'idée est :
Récupérez l'ancien nœud AST
Créez un tableau avec To. conserver le nouveau nœud AST (bien que la classe d'origine ne soit qu'un seul nœud, elle sera remplacée par plusieurs nœuds de fonction après remplacement) Initialiser le nœud constructor
par défaut (comme mentionné ci-dessus, le constructeur peut ne pas être défini dans la classe)
Bouclez l'objet AST de l'ancien nœud (plusieurs nœuds de fonction seront bouclés)
Déterminez si le type de la fonction est constructor
, si tel est le cas, créez un nœud de fonction normal en récupérant les données, et mettez à jour le nœud constructor
par défaut
pour traiter les nœuds restants qui ne sont pas constructor
, créez un prototype
tapez la fonction à travers les données et mettez Aller à es5Fns
La boucle se termine et placez le nœud constructor
dans es5Fns
pour déterminer si la longueur de es5Fns est supérieure à 1. Si elle est supérieure à 1, utilisez replaceWithMultiple
cette API pour mettre à jour l'AST
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) } } } }; }
Optimiser l'héritage
En fait, la classe implique également l'héritage, et l'idée n'est pas compliquée, elle détermine simplement qu'il n'y a pas d'attribut superClass
dans l'AST. , nous devons ajouter une ligne de code supplémentaire Bird.prototype = Object.create(Parent)
Bien sûr, n'oubliez pas de traiter le mot-clé super
.
Code packagé
Exécuter npm start
Après packaging, on voit class
Comment vue cli met à niveau webapck4
Étapes détaillées pour la modularisation de l'application AngularJS
vue-cli 3.0 Ce que les débutants doivent savoir
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!