Package Exports
- @codeque/eslint-plugin
- @codeque/eslint-plugin/dist/index.js
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (@codeque/eslint-plugin) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
Website • Docs • Roadmap • Mission • Playground
Streamline your workflow by finding and linting complex code patterns effortlessly.
What is CodeQue?
CodeQue is semantic code search engine that understands the code syntax.
It matches code structurally which makes it excellent for more complex queries.
Query language offers wildcards, partial matching and ignores code formatting.
Structural code search is available for JavaScript, TypesScript, HTML, CSS and more soon.
Text code search with handy wildcards is available for every language and covers common regex search use cases.
Just paste code snippet to start searching, no installation needed!
Integrations
CodeQue is available as:
- VSCode extension for delightful code search and navigation experience.
- ESLint integration for creating custom linting rules in zero time.
- CLI tool for searching code and more including headless environments.
All CodeQue tools operate offline hence code never leaves your local environment.
Coming soon
CodeQue will be soon available as:
- Duplicated code identification
- Batch code refactoring
- Advanced ESLint rule creator
🔔 Get notified about updates 🔔
ESLint integration 💅
Using CodeQue ESLint plugin you can create your own custom linting rules in zero time.
Custom ESLint rules can help execute on long-term refactors or prevent introducing codebase specific bugs or bad patterns.
Rules can replace your decision log and help standardizing coding conventions across the project or organization.
CodeQue ESLint integration is a no-brainier for any team willing to improve their codebase quality.
Installation
yarn add --dev @codeque/eslint-plugin
CodeQue supports all parsers officially supported by ESLint
👉 Open GitHub issue to request parser support
Configuration
Add @codeque
plugin to plugins list in your .eslintrc
.
And then add a definition for one of the rules:
@codeque/error
@codeque/warning
There are two rules, so you can configure them to report errors or warnings.
Each rule should be provided with a list of rule config objects with CodeQue queries.
Learn more about writing queries from CodeQue docs
{
"plugins": ["@codeque"],
"rules": {
"@codeque/error": ["error", [
{
"query": "fetchData()",
"mode": "exact",
"message": "Using fetchData() without parameters causes app crash!",
},
]],
"@codeque/warning": ["warn", [
{
"query": "import $$$ from 'lodash';",
"mode": "include",
"message": "Prefer to import lodash functions from separate packages like 'lodash.debounce'",
},
]]
}
}
The above configuration
- rises an error when
fetchData()
function is called without parameters - reports a warning when utility is imported from main
lodash
package
If your config seems too big, feel free to extract your set of rules to a separate file. Change your
.eslintrc
to JS file and import rules from a separate file.
Rule config object properties
Minimal rule config object should contain just query
key
({
query: "someCode"
})
The default settings are:
mode
-include
message
-Restricted code pattern
caseInsensitive
-true
includeFiles
-undefined
(do not filter files provided by ESLint)excludeFiles
-[]
(do not filter files provided by ESLint)
All configuration options
type RuleConfig = {
query: string // Content of the query
mode: 'exact' | 'include' | 'include-with-order' // CodeQue search mode
message: string // Error message to display
caseInsensitive: boolean // Whether query should perform matches case insensitively
includeFiles: string[] | undefined // list of glob patterns to indicate files against which given rule should be executed
excludeFiles: string[] // list of glob patterns to indicate files against which given rule should not be executed
}
Rule examples
CodeQue is general purpose code search tool. The examples list could be endless. Here are some of them for you to get a glimpse of what's possible. Those are relatively simple, you will definitely find some more complex during day to day work.
Don't know how to write a query? Open an issue on GitHub !
All usages of console
object
Searching for console logs, warnings, errors is quite simple use-case and can be achieved using traditional tools, but It's for you to warm up 😁
This rule warns about all places in the code that can output some (usually unwanted) logs.
{
"rules": {
"@codeque/warning": ["warn", [
{
"query": "console.$$()",
"mode": "include",
"message": "Prefer to use 'Logger' util.",
},
]]
}
}
Library specific issues
Third party code not always work as expected. Whenever you spot a problem, add custom eslint rule to spread that knowledge across your team.
The rule warns against using disabled
property on SomeLibComponent
, and suggest using not documented isDisabled
prop instead.
{
"rules": {
"@codeque/warning": ["warn", [
{
"query": "<SomeLibComponent disabled />",
"mode": "include",
"message": "'disabled' property does not work as expected. Use 'isDisabled' instead",
"includeFiles": ["**/*.tsx"]
},
]]
}
}
Unstable hook reference
Some 3rd party hooks are not implemented correctly and return non-memoized variables.
In this rule we rise an error when confirm
callback from useAsyncDialog
is used as an item of useCallback
dependency array.
This is interesting example that links together two statements in the same code block, that does not necessarily have to directly follow each other.
{
"rules": {
"@codeque/error": ["error", [
{
"query": "const { confirm } = useAsyncDialog(); const $$ = useCallback($$$, [confirm]);",
"mode": "include",
"message": "'confirm' is known to be unstable. Using it in hook dependency array can cause render loop",
},
]]
}
}
React bad patterns
First rule restricts usage of object literal as a prop. Object literal could be extracted to variable in upper scope or memoized to avoid performance issues.
Second rule restricts places where a given array is mapped directly in JSX. It could be memoized to make the array reference stable and reduce re-renders.
{
"rules": {
"@codeque/error": ["error", [
{
"query": "<$$ $$={{}} />",
"mode": "include",
"message": "Don't use object literal in JSX props",
"includeFiles": ["**/*.tsx"]
},
{
"query": "<$$ $$={$$$.map(() => ($$$))} />",
"mode": "include",
"message": "'disabled' property does not work as expected. Use 'isDisabled' instead",
"includeFiles": ["**/*.tsx"]
},
]]
}
}
Debugging performance
You can check performance of your CodeQue ESLint rules by running
TIMING=ALL CODEQUE_DEBUG=true yarn YOUR_LINT_SCRIPT
Very generic rules or those containing wildcards on top level might be slow.
Remember to be specific if possible and use file filtering options eg. to not run JSX rules on *.js
files.
Telemetry
Plugin collects completely anonymous telemetry that helps me get insights about usage.
It's implemented using applicationinsights
and you can easily opt-out.
Learn more about telemetry
Support and feedback
Feel free to use Github Issues to
- ask for help with writing a query
- report a bug or doubt
- suggest feature or improvement