DEV Community

Cover image for How To Publish ESLint Rules as NPM Package
Yehezkiel Gunawan
Yehezkiel Gunawan

Posted on • Originally published at yehezgun.com

How To Publish ESLint Rules as NPM Package

Disclaimer

In this tutorial, I’ll focus on the specific use case for typescript code-based. You don’t have to imitate this tutorial 100%. You can adjust the specific parts based on your needs

Introduction

Lately, I’ve been too lazy if I have to rewrite the exact same ESLint rules for my personal projects. Look at this. You maybe noticed this in my previous blog titled, Standardize Your Next.js Project.

{
  "env": {
    "node": true
  },
  "extends": [
    "next/core-web-vitals",
    "eslint:recommended",
    "plugin:@typescript-eslint/recommended"
  ],
  "parser": "@typescript-eslint/parser",
  "plugins": ["import", "unused-imports", "@typescript-eslint"],
  "settings": {
    "import/resolver": {
      "node": {
        "extensions": [".js", ".jsx", ".ts", ".tsx"],
        "moduleDirectory": ["node_modules", "src/"]
      }
    }
  },
  "rules": {
    "no-unused-vars": "off",
    "@typescript-eslint/no-unused-vars": "off",
    "@typescript-eslint/explicit-module-boundary-types": "off",
    "@typescript-eslint/no-non-null-assertion": "off",
    "@typescript-eslint/no-inferrable-types": "off",
    "@next/next/no-img-element": "off",
    "unused-imports/no-unused-imports": "error",
    "unused-imports/no-unused-vars": [
      "warn",
      {
        "vars": "all",
        "varsIgnorePattern": "^_",
        "args": "after-used",
        "argsIgnorePattern": "^_"
      }
    ],

    "no-eq-null": "warn",
    "import/order": [
      "warn",
      {
        "groups": [
          ["builtin", "external"],
          "internal",
          "parent",
          ["sibling", "index"],
          "object"
        ],
        "newlines-between": "always",
        "alphabetize": {
          "order": "asc",
          "caseInsensitive": true
        }
      }
    ],
    "complexity": "warn",
    "no-console": ["error"]
  }
}
Enter fullscreen mode Exit fullscreen mode

Then I knew an old friend who told me that he created his own ESLint rules as an npm package. You can see his here. Like before, I asked him why he put an effort to create this thing? Simply because when he creates a new project (especially a personal project), he just needs to extend the ESLint rules. No need to rewrite the whole ESLint rules from scratch.

module.exports = {
  extends: ['sznm'],
};
Enter fullscreen mode Exit fullscreen mode

So, his statement inspires me to create my own ESLint config library.

Preparation

First thing first, don’t forget to make an empty directory, then run npm init or yarn init. You can change eslint-config-test with your preferred folder name. Remember that eslint-config prefix must exist so it can be published at the NPM registry as the ESLint Config library.

mkdir eslint-config-test
cd eslint-config-test
yarn init
Enter fullscreen mode Exit fullscreen mode

You will have package.json file like this.

{
  "name": "eslint-config-test",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC"
}
Enter fullscreen mode Exit fullscreen mode

Now, install the dependencies that we’ll use to make our ESLint config. Remember, you don’t have to imitate this 100%. You may have some other preferred tools, that’s okay.

yarn add @typescript-eslint/eslint-plugin @typescript-eslint/parser eslint eslint-plugin-import eslint-plugin-sonarjs eslint-plugin-unused-imports
Enter fullscreen mode Exit fullscreen mode

Setup The ESLint Rules

Now, you can start to write your own preferred ESLint rules. Start with creating eslintrc.js file, then modify it. Here’s mine, you can use it as a reference.

module.exports = {
  env: {
    node: true,
  },
  extends: [
    "eslint:recommended",
    "plugin:@typescript-eslint/recommended",
    "plugin:sonarjs/recommended",
  ],
  parser: "@typescript-eslint/parser",
  plugins: ["@typescript-eslint", "import", "unused-imports"],
  settings: {
    "import/resolver": {
      node: {
        extensions: [".js", ".jsx", ".ts", ".tsx"],
        moduleDirectory: ["node_modules", "src/"],
      },
    },
  },
  rules: {
    "no-unused-vars": "off",
    "no-var": "warn",
    "@typescript-eslint/no-unused-vars": "off",
    "unused-imports/no-unused-imports": "error",
    "unused-imports/no-unused-vars": [
      "warn",
      {
        vars: "all",
        varsIgnorePattern: "^_",
        args: "after-used",
        argsIgnorePattern: "^_",
      },
    ],
    "@typescript-eslint/explicit-module-boundary-types": "off",
    "@typescript-eslint/no-non-null-assertion": "off",
    "@typescript-eslint/no-inferrable-types": "off",
    "import/order": [
      "warn",
      {
        groups: [
          ["builtin", "external"],
          "internal",
          "parent",
          ["sibling", "index"],
          "object",
        ],
        "newlines-between": "always",
        alphabetize: {
          order: "asc",
          caseInsensitive: true,
        },
      },
    ],
    complexity: "warn",
    "no-console": ["error"],
  },
};
Enter fullscreen mode Exit fullscreen mode

After you finish this step, now you can import it at index.js file.

const eslintrc = require("./.eslintrc.js");
module.exports = eslintrc;
Enter fullscreen mode Exit fullscreen mode

Publish It To NPM Registry

Yep, technically you can now publish your rules. You can run npm publish or yarn publish. Then follow the step in the terminal. You can also create an NPM registry account if you don’t have it before.

Now how to use it? When you want to use it, you can easily extend it at your eslintrc file in your project folder. Here’s mine, you can access it at eslint-config-yehezgun.

Closing

This tutorial seems short, but it will have a long-term effect on you. You can now just need to adjust the ESLint config that has been published if you want to make some changes, then it will be implemented to all the projects that use the ESLint rules (you have to update the dependencies too).

Thanks for reading, hope it helps.

Reference:

Top comments (1)

Collapse
 
dustytrash profile image
Lionel

It should be mentioned that the repo needs to begin with the prefix eslint-config-. Although it's optional when extending the package inside .eslintrc.* file of the project using the package.