eslint-plugin-sonar-config
v0.1.3
Published
ESLint plugin com regras customizadas para melhorar a qualidade de código em projeto com Sonar implementado.
Downloads
582
Maintainers
Readme
eslint-plugin-sonar-config
Preset ESLint auto-contido que replica o perfil SonarJS para JS/React. Combina ESLint core + 7 plugins oficiais (react, react-hooks, jsx-a11y, sonarjs, unicorn, import, jest) + 13 customs, cobrindo 165 regras em cada preset.
Entrega dois presets tunados para contextos diferentes:
modules-legacy— React 16, JS puro, módulos Liferay legado (.eslintrc.js)flat/client-extension— React 18+, TypeScript, client extensions modernos (eslint.config.js)
Instalação
Auto-contido — os plugins externos vêm como deps transitivas:
npm install --save-dev eslint eslint-plugin-sonar-config
eslint-plugin-jestéoptionalDependency— instalado por padrão mas ignorado silenciosamente se o projeto remover, e as regrasjest/*saem do preset automaticamente.
Uso — Client Extension (moderno)
Pensado pra código moderno: React 18+, TypeScript, hooks only, eslint.config.js.
const sonarConfig = require("eslint-plugin-sonar-config");
module.exports = [
sonarConfig.configs["flat/client-extension"],
];Ou equivalente com o alias flat/recommended:
module.exports = [sonarConfig.configs["flat/recommended"]];Uma linha. Plugins já registrados, settings.react.version = "detect".
Versão ESM:
import sonarConfig from "eslint-plugin-sonar-config";
export default [sonarConfig.configs["flat/client-extension"]];Características deste preset:
no-unused-varsdesativado — delega pra@typescript-eslint/no-unused-varsque o consumer ativareact/no-deprecated= errorreact-hooks/rules-of-hooks= error,exhaustive-deps= warnreact/hook-use-state= errorno-var= error
Uso — Modules Legacy
Pensado pro Liferay legado: React 16, JS puro, jQuery/AUI, modules/**.
// .eslintrc.js
module.exports = {
extends: ["plugin:sonar-config/modules-legacy"],
// ...resto da sua config
};Ou equivalente com o alias recommended:
extends: ["plugin:sonar-config/recommended"]Características deste preset:
no-unused-vars= error comvarsIgnorePattern: "^React$|^Component$"eargsIgnorePattern: "^_"no-var= warn (legado tem muito var, não bloqueia build)react/no-deprecated= off (componentWillMount etc ainda aparecem)react-hooks/rules-of-hooks= warn (mistura class + FC)react/hook-use-state= offsonar-config/no-this-in-functional-component= off (classes existem)react/no-access-state-in-setstate= error (classes existem)settings.react.version = "16"
Se quiser customizar alguma regra, basta adicionar um bloco depois:
export default [
sonarConfig.configs["flat/recommended"],
{
rules: {
"react/jsx-key": "warn", // downgrade
"sonar-config/no-infinite-loop": "off", // desativa uma custom
},
},
];Legacy config (.eslintrc.js)
module.exports = {
extends: ["plugin:sonar-config/recommended"],
};Uma linha no extends. O preset legacy já declara internamente os 8 plugins (sonar-config + 7 externos) no array plugins, e o ESLint legacy resolve cada pacote a partir do node_modules (os plugins vêm via dependencies transitivas).
Se o projeto já tem outros plugins ou settings, basta compor:
module.exports = {
extends: [
"plugin:sonar-config/recommended",
"plugin:prettier/recommended",
],
plugins: ["prettier"],
rules: {
"react/prop-types": "off",
},
};⚠️ Versões internas fixadas:
eslint-plugin-sonarjs@^4— catálogo completo usado pelo preseteslint-plugin-unicorn@^56— v57+ é ESM-only, incompatível com workspaces CommonJS
Regras customizadas deste plugin (13)
Apenas as regras Sonar que não têm equivalente funcional em ESLint core, plugins oficiais ou sonarjs v4 (sem type info do TS):
| Regra | Sonar ID | Descrição |
|---|---|---|
| await-only-promises | — | await só em Promises |
| no-this-in-functional-component | — | Não usar this em componentes funcionais |
| prefer-for-of | — | Prefere for…of a for (let i…) |
| array-method-missing-args | — | push() / unshift() sem argumento |
| no-misleading-array-mutation | — | const b = a.reverse() é enganoso |
| no-unsafe-window-open | — | window.open sem noopener/noreferrer |
| no-useless-async | S4326 | async sem nenhum await no corpo |
| no-infinite-loop | S2189 | Loops sem break/return/throw |
| no-array-delete | S2870 | Proíbe delete arr[i] |
| no-index-of-compare-positive | S2692 | Evita indexOf(x) > 0 (ignora o primeiro elemento) |
| prefer-regex-exec | S6594 | Prefere regex.exec() em certos contextos |
| no-internal-api | S6627 | Acesso a APIs internas (_*) de libs externas |
| no-non-numeric-array-index | — | Não usar chave não-numérica em array |
Regras marcadas com Sonar ID existem como
sonarjs/*na v4, mas exigem@typescript-eslint/parsercom type info — silenciosamente não-op em JS/JSX puro. Por isso mantemos customs.
Rodando os testes das customs
npm testUsa o RuleTester oficial do ESLint. Cobre casos positivos e negativos pras 13 customs.
Regras Sonar não cobertas
Duas regras Sonar não têm implementação viável apenas em JavaScript (sem TypeScript) e foram deixadas fora do preset:
- Boolean literals should not be used in comparisons — só existe em
@typescript-eslint/no-unnecessary-boolean-literal-compare(requer type info) - Optional chaining should be preferred — sem regra JS-only confiável; use
@typescript-eslint/prefer-optional-chainem projetos TS
Mapeamento completo
Veja .planning/sonar-rules-mapping.md para a tabela completa: cada uma das 164 regras Sonar e qual regra ESLint core/plugin/custom a implementa.
Integração com a CLI SEA-LI
Este preset é consumido automaticamente pela CLI de qualidade de código Liferay.
Desenvolvimento
eslint-plugin-sonar-config/
├── index.js # Preset + registro das customs
├── package.json
├── README.MD
├── .planning/
│ └── sonar-rules-mapping.md # Mapeamento Sonar → ESLint
└── rules/ # 18 regras customTestando localmente
npm link
# no projeto de teste:
npm link eslint-plugin-sonar-config