JSPM

@codeque/eslint-plugin

0.1.0
  • ESM via JSPM
  • ES Module Entrypoint
  • Export Map
  • Keywords
  • License
  • Repository URL
  • TypeScript Types
  • README
  • Created
  • Published
  • Downloads 66
  • Score
    100M100P100Q110930F
  • License Sustainable Use License

Create custom ESLint rules based on code samples. Utilizing CodeQue - structural code search engine.

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.

Give it a try in playground

Just paste code snippet to start searching, no installation needed!

Integrations

CodeQue is available as:

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