Skip to content

Instantly share code, notes, and snippets.

@aprilmintacpineda
Last active November 11, 2022 07:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aprilmintacpineda/bda5c8f7aa74e2860a9409e7e9c53209 to your computer and use it in GitHub Desktop.
Save aprilmintacpineda/bda5c8f7aa74e2860a9409e7e9c53209 to your computer and use it in GitHub Desktop.
Linting setup with TypeScript

This setup achieves:

  • Imports will be resolved from /src folder.
  • Code formatter and linter that works with the import module resolver.

1. Install dependencies

yarn add prettier eslint @typescript-eslint/typescript-estree @typescript-eslint/eslint-plugin eslint-plugin-react eslint-plugin-react-hooks eslint-plugin-module-resolver eslint-plugin-import  eslint-import-resolver-babel-module babel-plugin-module-resolver husky lint-staged eslint-plugin-jest @typescript-eslint/parser --dev

2. Code formatting

On your .prettierrc.js file, copy-paste the following codes:

module.exports = {
  tabWidth: 2,
  printWidth: 69,
  useTabs: false,
  semi: true,
  singleQuote: true,
  trailingComma: 'none',
  bracketSpacing: true,
  bracketSameLine: false,
  jsxSingleQuote: false,
  quoteProps: 'as-needed',
  arrowParens: 'avoid',
  insertPragma: false
};

3. Code Linting

On your .eslintrc.js, copy-paste one of the following codes:

const alias = require("./importAliases");

const unusedVarsIgnorePattern = "^_[0-9]+$";

module.exports = {
  settings: {
    "import/resolver": {
      "babel-module": {
        extensions: [".js", ".ts"],
        alias,
      },
    },
  },
  env: {
    browser: true,
    node: true,
    es6: true,
    "jest/globals": true,
  },
  root: true,
  plugins: ["@typescript-eslint", "jest", "module-resolver"],
  extends: [
    "eslint:recommended",
    "plugin:@typescript-eslint/recommended",
    "plugin:jest/recommended",
    "plugin:import/errors",
    "plugin:import/warnings",
  ],
  globals: {
    Atomics: "readonly",
  },
  parser: "@typescript-eslint/parser",
  parserOptions: {
    sourceType: "module",
  },
  rules: {
    "brace-style": ["error", "1tbs", { allowSingleLine: false }],
    "no-multiple-empty-lines": ["error", { max: 1 }],
    "no-case-declarations": 0,
    "no-return-await": "error",
    "import/no-unresolved": 0,
    "import/order": [
      "error",
      {
        "newlines-between": "never",
        alphabetize: {
          order: "asc",
          caseInsensitive: true,
        },
      },
    ],
    semi: ["error", "always"],
    quotes: ["error", "single", { avoidEscape: true }],
    curly: ["error", "multi-or-nest", "consistent"],
    "linebreak-style": ["error", "unix"],
    "no-duplicate-imports": [
      "error",
      {
        includeExports: true,
      },
    ],
    "rest-spread-spacing": ["error", "never"],
    "no-inline-comments": [
      "error",
      {
        ignorePattern: "_prettier-hack",
      },
    ],
    "prefer-spread": ["error"],
    "prefer-const": "error",
    "no-useless-call": ["error"],
    "no-trailing-spaces": ["error"],
    "space-before-blocks": ["error", "always"],
    "@typescript-eslint/no-unused-vars": [
      "error",
      {
        varsIgnorePattern: unusedVarsIgnorePattern,
        argsIgnorePattern: unusedVarsIgnorePattern,
        caughtErrorsIgnorePattern: unusedVarsIgnorePattern,
      },
    ],
    "no-floating-decimal": ["error"],
    "comma-dangle": ["error", "never"],
    "array-bracket-spacing": ["error", "never"],
    "object-curly-spacing": ["error", "always"],
    "switch-colon-spacing": [
      "error",
      {
        after: true,
        before: false,
      },
    ],
    "space-unary-ops": [
      "error",
      {
        words: true,
        nonwords: false,
      },
    ],
    "space-before-function-paren": [
      "error",
      {
        anonymous: "always",
        named: "always",
        asyncArrow: "always",
      },
    ],
    "keyword-spacing": [
      "error",
      {
        before: true,
        after: true,
      },
    ],
    "space-in-parens": ["error", "never"],
    "block-spacing": "error",
    "key-spacing": [
      "error",
      {
        singleLine: {
          beforeColon: false,
          afterColon: true,
          mode: "strict",
        },
        multiLine: {
          beforeColon: false,
          afterColon: true,
          mode: "strict",
        },
      },
    ],
    "generator-star-spacing": [
      "error",
      {
        before: false,
        after: true,
      },
    ],
    eqeqeq: "error",
    "no-empty": "error"
  },
};

4. Import aliases

Create a file on the root, same level as your .eslintrc, called importAliases.js, and copy-paste the following codes.

// you can setup whatever alias you need here
module.exports = {};

Using these aliases, you can do imports like this:

import myLib from "libs/myLib";

instead of this:

import myLib from "../../libs/myLib";

Feel free to add to these aliases as needed, you only need to update this file.

5. Setup husky and lint-staged

Add the following somewhere at the bottom of your package.json:

"lint-staged": {
  "*": [
    "prettier --write"
  ],
  "*.js|*.jsx|*.ts|*.tsx": [
    "eslint --fix"
  ]
}

Then on your the scripts, add the following:

"ts-check": "tsc --noEmit",
"eslint": "eslint . --fix",
"prettier": "prettier . --write",
"lint": "npm run prettier && npm run eslint",
"postinstall": "npx yarn-deduplicate yarn.lock && husky install"

Then run yarn husky install && yarn husky add .husky/pre-commit "yarn lint-staged && yarn ts-check"

6. jsconfig.json and tsconfig.json

create a file called jsconfig.json on your root directory, and copy-paste the following codes:

{
  "exclude": ["node_modules"],
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "*": ["src/*"]
    }
  }
}

create a file called tsconfig.json on your root directory, and copy-paste the following code:

{
  "exclude": ["node_modules"],
  "compilerOptions": {
    "baseUrl": ".",
    "paths": {
      "*": ["src/*"]
    }
  }
}

7. babel.config.js

On your babel.config.js file, add the following plugin:

plugins: [
  // .. other plugins

  // start here
  [
    "module-resolver",
    {
      root: ["./src"],
      alias,
    },
  ],
  // end here
];

and also add the following require at the top:

const alias = require("./importAliases");

After this, you should be able to run your app successfully.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment