小能豆

ESLint rule to detect uncalled functions

javascript

I have a Logger class which beautifies the logs before showing them in JS browser console. I use .bind() to let console display correct script name and line (like script_name.ts:62) in the sources instead of always showing Logger.ts:130:

  1. When I use console.log.bind(console, ...args) (correct script name and line):

expected view

  1. When I call console.log(...args) directly in the Logger.log() function (always the same line in Logger class):

enter image description here

But there is a problem: I often forgot to call the function returned by Logger.log(). In this case I won’t see any log in the console. Is there any ESLint rule which may help to handle this and show warning when this happens?

Roughly the Logger code is:

class Logger {
  log(...args: any[]) {
    // doing here something with log args
    return console.log.bind(console, ...args);
  }
}

// correct call
Logger.log("some text")();

// incorrect call (nothing will be shown)
Logger.log("some text");

I use this in browser extension in content scripts, this case doesn’t work well with many existing logger libraries.


阅读 76

收藏
2023-12-01

共1个答案

小能豆

While ESLint doesn’t have a built-in rule to specifically catch situations where the logger’s returned function is not invoked immediately, you can achieve this by creating a custom ESLint rule. Here’s an example of how you might approach this:

  1. Install the necessary packages: Install @typescript-eslint/parser, @typescript-eslint/eslint-plugin, and eslint if you haven’t already.

npm install --save-dev @typescript-eslint/parser @typescript-eslint/eslint-plugin eslint

  1. Create a custom ESLint rule: In your ESLint configuration, add a rule that checks whether the logger’s returned function is invoked immediately.

// .eslintrc.js or .eslintrc.json { "parser": "@typescript-eslint/parser", "plugins": ["@typescript-eslint"], "extends": [ "eslint:recommended", "plugin:@typescript-eslint/recommended" ], "rules": { "invoke-logger-function": ["error", "always"] }, "overrides": [ { "files": ["*.ts", "*.tsx"], "rules": { "@typescript-eslint/explicit-function-return-type": "off" } } ] }

  1. Create the ESLint rule: Create a custom ESLint rule to enforce that the logger’s returned function is invoked immediately. This rule will look for calls to the logger method and check if the returned function is invoked.

```
// invoke-logger-function.ts
import { Rule } from “eslint”;
import { TSESTree } from “@typescript-eslint/experimental-utils”;

const rule: Rule.RuleModule = {
meta: {
type: “problem”,
docs: {
description: “Enforce immediate invocation of logger’s returned function”,
category: “Best Practices”,
recommended: true,
},
fixable: null,
},
create: (context) => {
return {
CallExpression(node: TSESTree.CallExpression) {
if (
node.callee.type === “MemberExpression” &&
node.callee.property.type === “Identifier” &&
node.callee.property.name === “log”
) {
const parentType = node.parent?.type;
if (parentType !== “CallExpression”) {
context.report({
node: node.callee.property,
message: “Logger’s returned function should be invoked immediately.”,
});
}
}
},
};
},
};

export default rule;
```

  1. Configure ESLint to use the custom rule: Update your ESLint configuration to include the custom rule.

// .eslintrc.js or .eslintrc.json { // ... "plugins": ["@typescript-eslint", "./path/to/custom-rules"], "rules": { // ... "invoke-logger-function": ["error", "always"] }, // ... }

Ensure that the path to the custom rule (./path/to/custom-rules) is correct.

  1. Run ESLint: Run ESLint to check your TypeScript files for the new rule.

npx eslint --ext .ts .

Now ESLint will show an error if you forget to immediately invoke the logger’s returned function.

2023-12-01