Last active
April 3, 2025 02:11
-
-
Save kvnxiao/d31ed05260ff5b97dfb58202a7139db3 to your computer and use it in GitHub Desktop.
Groups Biome.js rules into recommended vs. non-recommended from the Biome rules page (https://biomejs.dev/linter/rules)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* Run the following script in the console of the Biome rules page | |
https://biomejs.dev/linter/rules | |
const rules = Array.from(document.querySelectorAll("tbody")).flatMap( | |
(table) => { | |
const trs = table.querySelectorAll("tr"); | |
return Array.from(trs).map((tr) => { | |
const tds = Array.from(tr.querySelectorAll("td")); | |
const ruleName = tds[0].textContent; | |
const isRecommended = | |
tds.at(-1).childNodes[0].title === "This rule is recommended"; | |
return { | |
ruleName, | |
isRecommended, | |
}; | |
}); | |
}, | |
); | |
const recommendedRules = rules | |
.filter((rule) => rule.isRecommended) | |
.map((rule) => rule.ruleName); | |
const nonRecommendedRules = rules | |
.filter((rule) => !rule.isRecommended) | |
.map((rule) => rule.ruleName); | |
console.log(JSON.stringify({ | |
recommended: recommendedRules, | |
nonRecommended: nonRecommendedRules, | |
}, null, 2)); | |
*/ | |
// Copy-pasted output from the above script (2025-04-02, Biome.js v1.9.4) | |
const linterRules = { | |
recommended: [ | |
"noAccessKey", | |
"noAriaHiddenOnFocusable", | |
"noAriaUnsupportedElements", | |
"noAutofocus", | |
"noBlankTarget", | |
"noDistractingElements", | |
"noHeaderScope", | |
"noInteractiveElementToNoninteractiveRole", | |
"noLabelWithoutControl", | |
"noNoninteractiveElementToInteractiveRole", | |
"noNoninteractiveTabindex", | |
"noPositiveTabindex", | |
"noRedundantAlt", | |
"noRedundantRoles", | |
"noSvgWithoutTitle", | |
"useAltText", | |
"useAnchorContent", | |
"useAriaActivedescendantWithTabindex", | |
"useAriaPropsForRole", | |
"useButtonType", | |
"useFocusableInteractive", | |
"useGenericFontNames", | |
"useHeadingContent", | |
"useHtmlLang", | |
"useIframeTitle", | |
"useKeyWithClickEvents", | |
"useKeyWithMouseEvents", | |
"useMediaCaption", | |
"useSemanticElements", | |
"useValidAnchor", | |
"useValidAriaProps", | |
"useValidAriaRole", | |
"useValidAriaValues", | |
"useValidLang", | |
"noBannedTypes", | |
"noEmptyTypeParameters", | |
"noExcessiveNestedTestSuites", | |
"noExtraBooleanCast", | |
"noForEach", | |
"noMultipleSpacesInRegularExpressionLiterals", | |
"noStaticOnlyClass", | |
"noThisInStatic", | |
"noUselessCatch", | |
"noUselessConstructor", | |
"noUselessEmptyExport", | |
"noUselessFragments", | |
"noUselessLabel", | |
"noUselessLoneBlockStatements", | |
"noUselessRename", | |
"noUselessSwitchCase", | |
"noUselessTernary", | |
"noUselessThisAlias", | |
"noUselessTypeConstraint", | |
"noWith", | |
"useArrowFunction", | |
"useFlatMap", | |
"useLiteralKeys", | |
"useOptionalChain", | |
"useRegexLiterals", | |
"useSimpleNumberKeys", | |
"noChildrenProp", | |
"noConstAssign", | |
"noConstantCondition", | |
"noConstructorReturn", | |
"noEmptyCharacterClassInRegex", | |
"noEmptyPattern", | |
"noFlatMapIdentity", | |
"noGlobalObjectCalls", | |
"noInnerDeclarations", | |
"noInvalidBuiltinInstantiation", | |
"noInvalidConstructorSuper", | |
"noInvalidDirectionInLinearGradient", | |
"noInvalidGridAreas", | |
"noInvalidPositionAtImportRule", | |
"noInvalidUseBeforeDeclaration", | |
"noNonoctalDecimalEscape", | |
"noPrecisionLoss", | |
"noRenderReturnValue", | |
"noSelfAssign", | |
"noSetterReturn", | |
"noStringCaseMismatch", | |
"noSwitchDeclarations", | |
"noUnknownFunction", | |
"noUnknownMediaFeatureName", | |
"noUnknownProperty", | |
"noUnknownUnit", | |
"noUnmatchableAnbSelector", | |
"noUnnecessaryContinue", | |
"noUnreachable", | |
"noUnreachableSuper", | |
"noUnsafeFinally", | |
"noUnsafeOptionalChaining", | |
"noUnusedLabels", | |
"noVoidElementsWithChildren", | |
"noVoidTypeReturn", | |
"useExhaustiveDependencies", | |
"useIsNan", | |
"useJsxKeyInIterable", | |
"useValidForDirection", | |
"useYield", | |
"noAccumulatingSpread", | |
"noDelete", | |
"noDangerouslySetInnerHtml", | |
"noDangerouslySetInnerHtmlWithChildren", | |
"noGlobalEval", | |
"noArguments", | |
"noCommaOperator", | |
"noInferrableTypes", | |
"noNonNullAssertion", | |
"noParameterAssign", | |
"noUnusedTemplateLiteral", | |
"noUselessElse", | |
"noVar", | |
"useAsConstAssertion", | |
"useConst", | |
"useDefaultParameterLast", | |
"useEnumInitializers", | |
"useExponentiationOperator", | |
"useExportType", | |
"useImportType", | |
"useLiteralEnumMembers", | |
"useNodejsImportProtocol", | |
"useNumberNamespace", | |
"useNumericLiterals", | |
"useSelfClosingElements", | |
"useShorthandFunctionType", | |
"useSingleVarDeclarator", | |
"useTemplate", | |
"useWhile", | |
"noApproximativeNumericConstant", | |
"noArrayIndexKey", | |
"noAssignInExpressions", | |
"noAsyncPromiseExecutor", | |
"noCatchAssign", | |
"noClassAssign", | |
"noCommentText", | |
"noCompareNegZero", | |
"noConfusingLabels", | |
"noConfusingVoidType", | |
"noConstEnum", | |
"noControlCharactersInRegex", | |
"noDebugger", | |
"noDoubleEquals", | |
"noDuplicateAtImportRules", | |
"noDuplicateCase", | |
"noDuplicateClassMembers", | |
"noDuplicateFontNames", | |
"noDuplicateJsxProps", | |
"noDuplicateObjectKeys", | |
"noDuplicateObjectKeys", | |
"noDuplicateParameters", | |
"noDuplicateSelectorsKeyframeBlock", | |
"noDuplicateTestHooks", | |
"noEmptyBlock", | |
"noEmptyInterface", | |
"noExplicitAny", | |
"noExportsInTest", | |
"noExtraNonNullAssertion", | |
"noFallthroughSwitchClause", | |
"noFocusedTests", | |
"noFunctionAssign", | |
"noGlobalAssign", | |
"noGlobalIsFinite", | |
"noGlobalIsNan", | |
"noImplicitAnyLet", | |
"noImportAssign", | |
"noImportantInKeyframe", | |
"noLabelVar", | |
"noMisleadingCharacterClass", | |
"noMisleadingInstantiator", | |
"noMisrefactoredShorthandAssign", | |
"noPrototypeBuiltins", | |
"noRedeclare", | |
"noRedundantUseStrict", | |
"noSelfCompare", | |
"noShadowRestrictedNames", | |
"noShorthandPropertyOverrides", | |
"noSparseArray", | |
"noSuspiciousSemicolonInJsx", | |
"noThenProperty", | |
"noUnsafeDeclarationMerging", | |
"noUnsafeNegation", | |
"useDefaultSwitchClauseLast", | |
"useGetterReturn", | |
"useIsArray", | |
"useNamespaceKeyword", | |
"useValidTypeof", | |
], | |
nonRecommended: [ | |
"noExcessiveCognitiveComplexity", | |
"noUselessStringConcat", | |
"noUselessUndefinedInitialization", | |
"noVoid", | |
"useDateNow", | |
"useSimplifiedLogicExpression", | |
"noConstantMathMinMaxClamp", | |
"noInvalidNewBuiltin", | |
"noNewSymbol", | |
"noNodejsModules", | |
"noUndeclaredDependencies", | |
"noUndeclaredVariables", | |
"noUnusedFunctionParameters", | |
"noUnusedImports", | |
"noUnusedPrivateClassMembers", | |
"noUnusedVariables", | |
"useArrayLiterals", | |
"useHookAtTopLevel", | |
"useImportExtensions", | |
"noCommonJs", | |
"noDescendingSpecificity", | |
"noDocumentCookie", | |
"noDocumentImportInPage", | |
"noDuplicateCustomProperties", | |
"noDuplicateElseIf", | |
"noDuplicateProperties", | |
"noDuplicatedFields", | |
"noDynamicNamespaceImportAccess", | |
"noEnum", | |
"noExportedImports", | |
"noHeadElement", | |
"noHeadImportInDocument", | |
"noImgElement", | |
"noIrregularWhitespace", | |
"noIrregularWhitespace", | |
"noMissingVarFunction", | |
"noNestedTernary", | |
"noOctalEscape", | |
"noProcessEnv", | |
"noRestrictedImports", | |
"noRestrictedTypes", | |
"noSecrets", | |
"noStaticElementInteractions", | |
"noSubstr", | |
"noTemplateCurlyInString", | |
"noUnknownPseudoClass", | |
"noUnknownPseudoElement", | |
"noUnknownTypeSelector", | |
"noUselessEscapeInRegex", | |
"noUselessStringRaw", | |
"noValueAtRule", | |
"useAdjacentOverloadSignatures", | |
"useAriaPropsSupportedByRole", | |
"useAtIndex", | |
"useCollapsedIf", | |
"useComponentExportOnlyModules", | |
"useConsistentCurlyBraces", | |
"useConsistentMemberAccessibility", | |
"useDeprecatedReason", | |
"useExplicitType", | |
"useGoogleFontDisplay", | |
"useGuardForIn", | |
"useImportRestrictions", | |
"useSortedClasses", | |
"useStrictMode", | |
"useTrimStartEnd", | |
"useValidAutocomplete", | |
"noBarrelFile", | |
"noReExportAll", | |
"useTopLevelRegex", | |
"noDefaultExport", | |
"noDoneCallback", | |
"noImplicitBoolean", | |
"noNamespace", | |
"noNamespaceImport", | |
"noNegationElse", | |
"noParameterProperties", | |
"noRestrictedGlobals", | |
"noShoutyConstants", | |
"noYodaExpression", | |
"useBlockStatements", | |
"useCollapsedElseIf", | |
"useConsistentArrayType", | |
"useConsistentBuiltinInstantiation", | |
"useDefaultSwitchClause", | |
"useExplicitLengthCheck", | |
"useFilenamingConvention", | |
"useForOf", | |
"useFragmentSyntax", | |
"useNamingConvention", | |
"useNodeAssertStrict", | |
"useShorthandArrayType", | |
"useShorthandAssign", | |
"useSingleCaseStatement", | |
"useThrowNewError", | |
"useThrowOnlyError", | |
"noConsole", | |
"noConsoleLog", | |
"noEmptyBlockStatements", | |
"noEvolvingTypes", | |
"noMisplacedAssertion", | |
"noReactSpecificProps", | |
"noSkippedTests", | |
"useAwait", | |
"useErrorMessage", | |
"useNumberToFixedDigitsArgument", | |
], | |
}; | |
import fs from "node:fs"; | |
import path from "node:path"; | |
// Assuming that this script is in the "scripts/" folder | |
const biomeJson = JSON.parse(fs.readFileSync(path.join(import.meta.dirname, "..", "biome.json"), "utf-8")); | |
const ruleTypes = ["complexity", "performance", "security", "style", "suspicious", "correctness", "nursery", "a11y"] | |
for (const ruleType of ruleTypes) { | |
const rules = biomeJson.linter.rules[ruleType]; | |
if (!rules) { | |
continue; | |
} | |
for (const entry of Object.keys(rules)) { | |
if (linterRules.recommended.includes(entry)) { | |
console.log(entry); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment