UNPKG

@addon24/eslint-config

Version:

ESLint configuration rules for WorldOfTextcraft projects - Centralized configuration for all project types

136 lines (120 loc) 5.29 kB
/** * ESLint-Regel, die die Verwendung von MUI-Button statt unserer eigenen Button-Komponente prüft */ const noMuiButtonRule = { meta: { type: "suggestion", docs: { description: "Verbietet die direkte Verwendung von MUI-Button", category: "Best Practices", recommended: true, }, fixable: "code", messages: { noMuiButton: "Bitte verwende die eigene Button-Komponente aus '@/components/UI/Button' statt der MUI-Button-Komponente.", noMuiButtonImport: "Bitte verwende die eigene Button-Komponente aus '@/components/UI/Button' statt der MUI-Button-Komponente.", }, }, create(context) { // Speichert Material-UI Button Importe const muiButtonImports = new Set(); return { // Prüft alle Import-Deklarationen ImportDeclaration(node) { // Überprüft, ob aus @mui/material importiert wird if (node.source.value === "@mui/material" || node.source.value === "@material-ui/core") { // Überprüft alle Importe aus diesem Modul node.specifiers.forEach((specifier) => { // Wenn Button importiert wird if ( (specifier.type === "ImportSpecifier" && specifier.imported && specifier.imported.name === "Button") || (specifier.type === "ImportDefaultSpecifier" && specifier.local.name === "Button") ) { // Speichert den lokalen Namen des importierten Buttons muiButtonImports.add(specifier.local.name); context.report({ node, messageId: "noMuiButtonImport", fix(fixer) { // Entfernt Button aus dem Import // Behandelt verschiedene Fälle, je nachdem wie der Import aussieht // Fall 1: Einziger Import aus @mui/material if (node.specifiers.length === 1) { return fixer.remove(node); } // Fall 2: Benannter Import in geschweiften Klammern if (specifier.type === "ImportSpecifier") { const importText = context.getSourceCode().getText(node); const buttonPattern = specifier.local.name === "Button" ? "Button" // Direkter Import: import { Button } from "@mui/material" : `Button as ${specifier.local.name}`; // Alias Import: import { Button as MuiButton } from "@mui/material" // Entfernt nur Button aus der Import-Liste if (importText.includes(`, ${buttonPattern}`)) { return fixer.replaceText(node, importText.replace(`, ${buttonPattern}`, "")); } else if (importText.includes(`${buttonPattern}, `)) { return fixer.replaceText(node, importText.replace(`${buttonPattern}, `, "")); } else if (importText.includes(`{ ${buttonPattern} }`)) { return fixer.remove(node); } } return null; } }); } }); } }, // Prüft alle JSX-Elemente JSXOpeningElement(node) { // Wenn ein Element mit dem Namen "Button" gefunden wird if (node.name.type === "JSXIdentifier" && node.name.name === "Button") { // Prüfe anhand des Scopes, ob dieser Button aus @mui/material stammt const scope = context.getScope(); let currentScope = scope; // Durchsuche alle Scopes nach dem Button-Variablennamen while (currentScope) { const buttonVar = currentScope.variables.find(v => v.name === "Button"); if (buttonVar) { // Prüfe jede Definition der Button-Variable for (const def of buttonVar.defs) { // Wenn es sich um einen Import handelt if (def.type === "ImportBinding" && def.parent && def.parent.source) { const importSource = def.parent.source.value; // Wenn der Import von @mui/material oder @material-ui/core stammt if (importSource === "@mui/material" || importSource === "@material-ui/core") { context.report({ node, messageId: "noMuiButton", }); return; } } } // Wenn wir eine Definition gefunden haben, aber sie ist nicht von MUI, // dann brechen wir die Suche ab (überschreibende Variable gefunden) break; } // Zum übergeordneten Scope wechseln currentScope = currentScope.upper; } // Außerdem prüfen wir anhand unserer Liste von MUI-Button-Importen if (muiButtonImports.has("Button")) { context.report({ node, messageId: "noMuiButton", }); } } }, // Am Ende der Datei werden die gesammelten Informationen zurückgesetzt "Program:exit": function() { muiButtonImports.clear(); } }; } }; export default { rules: { "no-mui-button": noMuiButtonRule } };