ESlint est un outil fantastique pour rendre notre code plus cohérent et fait gagner beaucoup de temps à nos équipes. Il existe une tonne de plugins qui gèrent la plupart des cas d'utilisation génériques, mais parfois nous avons des besoins spécifiques, et créer notre propre règle prendrait trop de temps.
Pour les cas les plus simples, lorsque nous voulons simplement interdire l'utilisation d'une fonction (ou de toute autre chose en fait), nous pouvons exploiter une règle par défaut : la syntaxe sans restriction.
Avant d'écrire notre premier sélecteur, nous devons comprendre le système sous-jacent. L'AST est simplement une représentation d'un programme sous forme d'objets imbriqués (d'où le "Tree" en AST), créé par un "analyseur". Il est très flexible car il peut être facilement lu, interrogé et manipulé. L’alternative serait d’utiliser des expressions régulières, mais cela serait très difficile à lire et à écrire. Il s'agit donc essentiellement d'une étape intermédiaire qui permet toutes les grandes choses qu'un IDE fait en comprenant notre code.
Pour comprendre comment cela fonctionne, nous pouvons jouer avec l'AST Explorer, un outil pratique qui affiche un peu de code et son AST en parallèle, où vous pouvez survoler ou cliquer sur n'importe quelle partie du code pour mettre en évidence sa partie AST correspondante. :
⚠️ Attention à bien sélectionner l'analyseur lors du changement de langue.
Par exemple, lors de l'écriture du code Vue, assurez-vous d'utiliser le vue-eslint-parser dans notre cas, car nous voulons écrire un sélecteur ESlint. Vous pouvez également inspecter ce que @vue/compiler-dom génère, mais vous ne pourrez pas interroger l'arborescence résultante avec une règle ESlint.
Le deuxième outil utile dont nous aurons besoin est la documentation des sélecteurs ESLint. Il répertorie l'expression que nous pouvons utiliser pour interroger l'AST, et cela peut vous sembler familier si vous êtes habitué à travailler avec CSS. Il est basé sur le même comportement « en cascade », avec des correspondances telles que les descendants, les frères et sœurs, le filtrage des nœuds et des attributs, etc. Voici quelques exemples tirés de la documentation :
Donc, étant donné ce code :
const time = dayjs();
Il générera l'AST suivant en utilisant @typescript-eslint/parser :
Program { body: [ VariableDeclaration { declarations: [ VariableDeclarator { id: Identifier init: CallExpression { callee: Identifier { name: "dayjs" } arguments: [] optional: false } } ] kind: "const" } ] sourceType: "module" }
Dans notre cas, nous devons faire correspondre un appel de fonction (CallExpression) dont le nom est dayjs (Identifier with name propriété). Nous avons également besoin du sélecteur de descendant direct > pour être sûr que nous ne correspondons à aucun appel de fonction qui aurait un identifiant dayjs imbriqué. Le sélecteur sera donc CallExpression > Identifiant[name="dayjs"].
Voici notre sélecteur pour empêcher l'utilisation de dayjs sans UTC que vous pouvez essayer en direct dans ESLint Playground :
const time = dayjs();
Program { body: [ VariableDeclaration { declarations: [ VariableDeclarator { id: Identifier init: CallExpression { callee: Identifier { name: "dayjs" } arguments: [] optional: false } } ] kind: "const" } ] sourceType: "module" }
Voici un autre exemple qui interdit une manière (assez hacky) de définir des variables locales dans les modèles dans les modèles Vue (notez que la règle est préfixée par vue/ car elle nécessite le package eslint-plugin-vue) :
'no-restricted-syntax': [ 'error', { selector: 'CallExpression > Identifier[name="dayjs"]', message: 'Always use dayjs.utc() instead of dayjs() to avoid timezone issues', }, ]
const foo = dayjs(); // ^^^^^ Invalid const bar = dayjs.utc();
Au fait, vous pouvez en savoir plus ici sur cette astuce bizarre qui nous a causé quelques problèmes de réactivité dans le passé, nous avons donc décidé de l'interdire complètement.
C'est le dernier exemple, où nous avons eu un cas où nous devions interdire l'utilisation d'un ensemble spécifique de traductions, nous avons donc dû trouver la fonction t (ou toute variante) qui a un premier argument commençant par exports. :
'vue/no-restricted-syntax': [ 'error', { selector: 'VAttribute > VExpressionContainer > AssignmentExpression', message: 'Do not assign values in templates as it will not be reactive', }, ],
<template> <div :set="(foo = 'bar')">{{ foo }}</div> <!-- Outputs <div>bar</div> --> <!-- ^^^^^^^^^^ Invalid --> </template>
Si vous avez du mal à trouver le bon sélecteur, vous pouvez demander de l'aide à ChatGPT ! C'est aussi bon pour expliquer les sélecteurs :
De plus, si vous devez restreindre uniquement les importations, il est plus simple d'utiliser la règle de non-restriction des importations :
'no-restricted-syntax': [ 'error', { selector: 'CallExpression[callee.name=/^(t|tc|tf|te|d|n)$/][arguments.0.value=/^exports./]', message: 'Do not assign values in templates as it will not be reactive', }, ],
Cette solution fonctionne très bien dans les situations les plus simples, mais elle ne vous permettra pas de proposer une correction automatique. Pour des solutions plus complètes, une règle personnalisée doit être créée à la place.
Grâce à ces règles, on gagne du temps en ne répétant pas deux fois la même erreur !
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!