Lint eslint Found Some Errors Please Fix Them and Try Committing Again

🚫 💩 lint-staged GitHub Actions Build Status for Windows npm version Codecov

Run linters against staged git files and don't permit 💩 sideslip into your lawmaking base!

asciicast

Why

Linting makes more sense when run before committing your code. By doing so you can ensure no errors get into the repository and enforce code fashion. Merely running a lint process on a whole project is slow, and linting results can be irrelevant. Ultimately you merely desire to lint files that will exist committed.

This project contains a script that will run capricious beat out tasks with a listing of staged files as an argument, filtered by a specified glob pattern.

Related blog posts and talks

  • Introductory Medium mail - Andrey Okonetchnikov, 2016
  • Running Jest Tests Earlier Each Git Commit - Ben McCormick, 2017
  • AgentConf presentation - Andrey Okonetchnikov, 2018
  • SurviveJS interview - Juho Vepsäläinen and Andrey Okonetchnikov, 2018
  • Prettier your CSharp with dotnet-format and lint-staged

If you lot've written 1, please submit a PR with the link to it!

Installation and setup

The fastest mode to start using lint-staged is to run the following command in your terminal:

This command will install and configure husky and lint-staged depending on the lawmaking quality tools from your project's package.json dependencies, then please make sure yous install (npm install --save-dev) and configure all lawmaking quality tools like Prettier and ESLint prior to that.

Don't forget to commit changes to package.json and .husky to share this setup with your team!

At present change a few files, git add or git add together --patch some of them to your commit, and endeavor to git commit them.

See examples and configuration for more data.

Changelog

Meet Releases.

Migration

v10

  • From v10.0.0 onwards any new modifications to originally staged files will be automatically added to the commit. If your task previously independent a git add pace, please remove this. The automatic behaviour ensures at that place are less race-atmospheric condition, since trying to run multiple git operations at the same time usually results in an fault.
  • From v10.0.0 onwards, lint-staged uses git stashes to improve speed and provide backups while running. Since git stashes require at least an initial commit, you shouldn't run lint-staged in an empty repo.
  • From v10.0.0 onwards, lint-staged requires Node.js version ten.xiii.0 or afterward.
  • From v10.0.0 onwards, lint-staged will abort the commit if linter tasks disengage all staged changes. To allow creating an empty commit, please use the --permit-empty choice.

Control line flags

❯ npx lint-staged --aid Usage: lint-staged [options]  Options:   -Five, --version                      output the version number   --allow-empty                      allow empty commits when tasks revert all staged changes                                      (default: faux)   -c, --config [path]                path to configuration file, or - to                read                from stdin   -d, --debug                        print additional debug data (default: fake)   --no-reset                practice                not reset changes                in                case                of errors   -p, --concurrent                <parallel tasks>                the number of tasks to run concurrently, or                false                to run                                      tasks serially (default: true)   -q, --quiet                        disable lint-staged's own console output (default: false)   -r, --relative                     pass relative filepaths to tasks (default: fake)   -x, --shell [path]                 skip parsing of tasks                for                better shell support (default:                                      false)   -five, --verbose                      prove task output even when tasks succeed;                by default only                                      failed output is shown (default: imitation)   -h, --aid                         brandish                help                for                command              
  • --allow-empty : By default, when linter tasks undo all staged changes, lint-staged will exit with an error and abort the commit. Utilise this flag to allow creating empty git commits.
  • --config [path] : Manually specify a path to a config file or npm package proper noun. Note: when used, lint-staged won't perform the config file search and volition impress an error if the specified file cannot be found. If '-' is provided as the filename then the config will exist read from stdin, allowing piping in the config similar cat my-config.json | npx lint-staged --config -.
  • --debug : Run in debug manner. When set, it does the post-obit:
    • uses debug internally to log boosted information nearly staged files, commands existence executed, location of binaries, etc. Debug logs, which are automatically enabled by passing the flag, can also be enabled by setting the environment variable $DEBUG to lint-staged*.
    • uses verbose renderer for listr; this causes serial, uncoloured output to the final, instead of the default (beautified, dynamic) output.
  • --concurrent [number | (true/false)] : Controls the concurrency of tasks being run by lint-staged. NOTE: This does Not affect the concurrency of subtasks (they will always be run sequentially). Possible values are:
    • false: Run all tasks serially
    • true (default) : Infinite concurrency. Runs as many tasks in parallel as possible.
    • {number}: Run the specified number of tasks in parallel, where 1 is equivalent to false.
  • --no-reset : By default a backup stash volition be created before running the tasks, and all task modifications volition be reverted in case of an fault. This pick will disable creating the stash, and instead leave all modifications in the alphabetize when aborting the commit.
  • --placidity : Supress all CLI output, except from tasks.
  • --relative : Pass filepaths relative to process.cwd() (where lint-staged runs) to tasks. Default is simulated.
  • --crush : By default linter commands volition exist parsed for speed and security. This has the side-effect that regular shell scripts might not work as expected. Yous can skip parsing of commands with this choice. To use a specific shell, employ a path like --shell "/bin/bash".
  • --verbose : Bear witness chore output even when tasks succeed. By default merely failed output is shown.

Configuration

Starting with v3.i you can now use different ways of configuring lint-staged:

  • lint-staged object in your packet.json
  • .lintstagedrc file in JSON or YML format, or yous tin can exist explicit with the file extension:
    • .lintstagedrc.json
    • .lintstagedrc.yaml
    • .lintstagedrc.yml
  • lint-staged.config.js, .lintstagedrc.js, or .lintstagedrc.cjs file in JS format
  • Pass a configuration file using the --config or -c flag

Encounter cosmiconfig for more details on what formats are supported.

Configuration should be an object where each value is a command to run and its central is a glob blueprint to apply for this control. This package uses micromatch for glob patterns.

package.json example:

{                                  "lint-staged"                : {                                  "*"                :                                  "your-cmd"                                } }

.lintstagedrc example

This config will execute your-cmd with the list of currently staged files passed every bit arguments.

So, considering yous did git add file1.ext file2.ext, lint-staged volition run the following control:

your-cmd file1.ext file2.ext

Filtering files

Linter commands work on a subset of all staged files, defined by a glob pattern. lint-staged uses micromatch for matching files with the post-obit rules:

  • If the glob design contains no slashes (/), micromatch's matchBase option will enabled, so globs match a file'south basename regardless of directory:
    • "*.js" will lucifer all JS files, like /test.js and /foo/bar/test.js
    • "!(*test).js" . will match all JS files, except those ending in test.js, so foo.js simply not foo.test.js
  • If the glob pattern does contain a slash (/), it volition match for paths too:
    • "./*.js" will lucifer all JS files in the git repo root, so /test.js but not /foo/bar/test.js
    • "foo/**/\*.js" will match all JS files inside the/foodirectory, so/foo/bar/test.jsmerely not/test.js

When matching, lint-staged volition do the post-obit

  • Resolve the git root automatically, no configuration needed.
  • Pick the staged files which are nowadays inside the project directory.
  • Filter them using the specified glob patterns.
  • Pass absolute paths to the linters as arguments.

Note: lint-staged will pass accented paths to the linters to avoid any defoliation in case they're executed in a different working directory (i.e. when your .git directory isn't the same as your package.json directory).

Also encounter How to utilize lint-staged in a multi-package monorepo?

Ignoring files

The concept of lint-staged is to run configured linter tasks (or other tasks) on files that are staged in git. lint-staged volition always pass a listing of all staged files to the job, and ignoring whatsoever files should be configured in the task itself.

Consider a project that uses prettier to continue code format consistent across all files. The projection likewise stores minified 3rd-party vendor libraries in the vendor/ directory. To keep prettier from throwing errors on these files, the vendor directory should exist added to prettier's ignore configuration, the .prettierignore file. Running npx prettier . will ignore the unabridged vendor directory, throwing no errors. When lint-staged is added to the project and configured to run prettier, all modified and staged files in the vendor directory will exist ignored by prettier, even though it receives them as input.

In advanced scenarios, where it is impossible to configure the linter job itself to ignore files, but some staged files should still be ignored by lint-staged, information technology is possible to filter filepaths before passing them to tasks past using the part syntax. See Example: Ignore files from lucifer.

What commands are supported?

Supported are any executables installed locally or globally via npm likewise every bit any executable from your $PATH.

Using globally installed scripts is discouraged, since lint-staged may not work for someone who doesn't have it installed.

lint-staged uses execa to locate locally installed scripts. Then in your .lintstagedrc you can write:

{                                  "*.js"                :                                  "eslint --set up"                                }

Pass arguments to your commands separated by space as yous would do in the shell. Meet examples below.

Running multiple commands in a sequence

You tin run multiple commands in a sequence on every glob. To do so, pass an array of commands instead of a unmarried one. This is useful for running autoformatting tools like eslint --fix or stylefmt just can be used for any arbitrary sequences.

For example:

{                                  "*.js"                : [                  "eslint"                ,                                  "prettier --write"                ] }

going to execute eslint and if it exits with 0 code, it will execute prettier --write on all staged *.js files.

Using JS configuration file

Writing the configuration file in JavaScript is the most powerful way to configure lint-staged (lint-staged.config.js, like, or passed via --config). From the configuration file, you can export either a single function or an object.

If the exports value is a part, it will receive an array of all staged filenames. You can then build your own matchers for the files and return a command string or an array of command strings. These strings are considered consummate and should include the filename arguments, if wanted.

If the exports value is an object, its keys should be glob matches (like in the normal non-js config format). The values tin can either be similar in the normal config or individual functions like described above. Instead of receiving all matched files, the functions in the exported object will merely receive the staged files matching the respective glob key.

Office signature

The role can also exist async:

                (                filenames:                string                [                ]                )                =>                string                |                string                [                                ]                |                Promise                <                string                |                string                [                ]                >              

Example: Export a part to build your ain matchers

Click to aggrandize
                  // lint-staged.config.js                  const                  micromatch                  =                  require                  (                  'micromatch'                  )                  module                  .                  exports                  =                  (                  allStagedFiles                  )                  =>                  {                  const                  shFiles                  =                  micromatch                  (                  allStagedFiles                  ,                  [                  '**/src/**/*.sh'                  ]                  )                  if                  (                  shFiles                  .                  length                  )                  {                  return                  `printf '%southward\north' "Script files aren't allowed in src directory" >&2`                  }                  const                  codeFiles                  =                  micromatch                  (                  allStagedFiles                  ,                  [                  '**/*.js'                  ,                  '**/*.ts'                  ]                  )                  const                  docFiles                  =                  micromatch                  (                  allStagedFiles                  ,                  [                  '**/*.doctor'                  ]                  )                  return                  [                  `eslint                                          ${                      codeFiles                      .                      join                      (                      ' '                      )                      }                    `                  ,                  `mdl                                          ${                      docFiles                      .                      join                      (                      ' '                      )                      }                    `                  ]                  }                

Instance: Wrap filenames in single quotes and run once per file

Click to expand
                  // .lintstagedrc.js                  module                  .                  exports                  =                  {                  '**/*.js?(ten)':                  (                  filenames                  )                  =>                  filenames                  .                  map                  (                  (                  filename                  )                  =>                  `prettier --write '                      ${                      filename                      }                    '`                  )                  ,                  }                

Instance: Run tsc on changes to TypeScript files, only practice not pass any filename arguments

Click to aggrandize
                  // lint-staged.config.js                  module                  .                  exports                  =                  {                  '**/*.ts?(x)':                  (                  )                  =>                  'tsc -p tsconfig.json --noEmit'                  ,                  }                

Example: Run ESLint on unabridged repo if more than 10 staged files

Click to expand
                  // .lintstagedrc.js                  module                  .                  exports                  =                  {                  '**/*.js?(x)':                  (                  filenames                  )                  =>                  filenames                  .                  length                  >                  10                  ?                  'eslint .'                  :                  `eslint                                          ${                      filenames                      .                      join                      (                      ' '                      )                      }                    `                  ,                  }                

Instance: Employ your own globs

Click to expand

It's better to use the part-based configuration (seen above), if your employ case is this.

                  // lint-staged.config.js                  const                  micromatch                  =                  require                  (                  'micromatch'                  )                  module                  .                  exports                  =                  {                  '*':                  (                  allFiles                  )                  =>                  {                  const                  codeFiles                  =                  micromatch                  (                  allFiles                  ,                  [                  '**/*.js'                  ,                  '**/*.ts'                  ]                  )                  const                  docFiles                  =                  micromatch                  (                  allFiles                  ,                  [                  '**/*.md'                  ]                  )                  return                  [                  `eslint                                          ${                      codeFiles                      .                      join                      (                      ' '                      )                      }                    `                  ,                  `mdl                                          ${                      docFiles                      .                      bring together                      (                      ' '                      )                      }                    `                  ]                  }                  ,                  }                

Example: Ignore files from friction match

Click to expand

If for some reason y'all want to ignore files from the glob friction match, you can employ micromatch.not():

                  // lint-staged.config.js                  const                  micromatch                  =                  crave                  (                  'micromatch'                  )                  module                  .                  exports                  =                  {                  '*.js':                  (                  files                  )                  =>                  {                  // from `files` filter those _NOT_ matching `*test.js`                  const                  match                  =                  micromatch                  .                  non                  (                  files                  ,                  '*examination.js'                  )                  return                  `eslint                                          ${                      friction match                      .                      join                      (                      ' '                      )                      }                    `                  }                  ,                  }                

Delight note that for most cases, globs tin achieve the same effect. For the above example, a matching glob would be !(*test).js.

Example: Use relative paths for commands

Click to aggrandize
                  const                  path                  =                  require                  (                  'path'                  )                  module                  .                  exports                  =                  {                  '*.ts':                  (                  absolutePaths                  )                  =>                  {                  const                  cwd                  =                  process                  .                  cwd                  (                  )                  const                  relativePaths                  =                  absolutePaths                  .                  map                  (                  (                  file                  )                  =>                  path                  .                  relative                  (                  cwd                  ,                  file                  )                  )                  return                  `ng lint myProjectName --files                                          ${                      relativePaths                      .                      join                      (                      ' '                      )                      }                    `                  }                  ,                  }                

Reformatting the code

Tools like Prettier, ESLint/TSLint, or stylelint tin can reformat your code according to an appropriate config by running prettier --write/eslint --set/tslint --fix/stylelint --fix. Lint-staged will automatically add together any modifications to the commit as long as there are no errors.

{                                  "*.js"                :                                  "prettier --write"                                }

Prior to version 10, tasks had to manually include git add as the last step. This behavior has been integrated into lint-staged itself in social club to forbid race conditions with multiple tasks editing the same files. If lint-staged detects git add together in task configurations, it will bear witness a warning in the console. Delight remove git add from your configuration later on upgrading.

Examples

All examples assume you've already prepare lint-staged in the package.json file and husky in its own config file.

{                                  "proper noun"                :                                  "My projection"                ,                                  "version"                :                                  "0.one.0"                ,                                  "scripts"                : {                                  "my-custom-script"                :                                  "linter --arg1 --arg2"                                },                                  "lint-staged"                : {} }

In .husky/pre-commit

                                  #!/usr/bin/env sh                .                                  "                                      $(dirname                                          "                      $0                      "                                        )                  /_/husky.sh"                                npx lint-staged

Notation: we don't pass a path as an argument for the runners. This is important since lint-staged will do this for you.

ESLint with default parameters for *.js and *.jsx running as a pre-commit claw

Click to expand
{                                      "*.{js,jsx}"                  :                                      "eslint"                                    }

Automatically fix code style with --set up and add to commit

Click to expand
{                                      "*.js"                  :                                      "eslint --prepare"                                    }

This volition run eslint --ready and automatically add changes to the commit.

Reuse npm script

Click to aggrandize

If you wish to reuse a npm script defined in your parcel.json:

{                                      "*.js"                  :                                      "npm run my-custom-script --"                                    }

The following is equivalent:

{                                      "*.js"                  :                                      "linter --arg1 --arg2"                                    }

Use environment variables with linting commands

Click to expand

Linting commands do not support the beat out convention of expanding surround variables. To enable the convention yourself, use a tool like cross-env.

For example, here is jest running on all .js files with the NODE_ENV variable being set to "test":

{                                      "*.js"                  : [                    "cantankerous-env NODE_ENV=test jest --bail --findRelatedTests"                  ] }

Automatically prepare code style with prettier for whatsoever format Prettier supports

Click to expand
{                                      "*"                  :                                      "prettier --ignore-unknown --write"                                    }

Automatically fix code style with prettier for JavaScript, TypeScript, Markdown, HTML, or CSS

Click to aggrandize
{                                      "*.{js,jsx,ts,tsx,doc,html,css}"                  :                                      "prettier --write"                                    }

Stylelint for CSS with defaults and for SCSS with SCSS syntax

Click to aggrandize
{                                      "*.css"                  :                                      "stylelint"                  ,                                      "*.scss"                  :                                      "stylelint --syntax=scss"                                    }

Run PostCSS sorting and Stylelint to check

Click to expand
{                                      "*.scss"                  : [                    "postcss --config path/to/your/config --replace"                  ,                                      "stylelint"                  ] }

Minify the images

Click to expand
{                                      "*.{png,jpeg,jpg,gif,svg}"                  :                                      "imagemin-lint-staged"                                    }
More near imagemin-lint-staged

imagemin-lint-staged is a CLI tool designed for lint-staged usage with sensible defaults.

Run into more on this blog mail for benefits of this approach.

Typecheck your staged files with flow

Click to expand
{                                      "*.{js,jsx}"                  :                                      "menstruum focus-check"                                    }

Frequently Asked Questions

Can I use lint-staged via node?

Click to expand

Yes!

                  const                  lintStaged                  =                  require                  (                  'lint-staged'                  )                  effort                  {                  const                  success                  =                  wait                  lintStaged                  (                  )                  panel                  .                  log                  (                  success                  ?                  'Linting was successful!'                  :                  'Linting failed!'                  )                  }                  catch                  (                  east                  )                  {                  // Failed to load configuration                  console                  .                  error                  (                  due east                  )                  }                

Parameters to lintStaged are equivalent to their CLI counterparts:

                  const                  success                  =                  expect                  lintStaged                  (                  {                  allowEmpty:                  faux                  ,                  concurrent:                  truthful                  ,                  configPath:                  './path/to/configuration/file'                  ,                  cwd:                  process                  .                  cwd                  (                  )                  ,                  debug:                  false                  ,                  maxArgLength:                  null                  ,                  quiet:                  false                  ,                  relative:                  false                  ,                  reset:                  true                  ,                  shell:                  false                  verbose:                  false                  }                  )                

Yous tin can too pass config direct with config option:

                  const                  success                  =                  await                  lintStaged                  (                  {                  allowEmpty:                  false                  ,                  concurrent:                  true                  ,                  config:                  {                  '*.js':                  'eslint --fix'                  }                  ,                  cwd:                  procedure                  .                  cwd                  (                  )                  ,                  debug:                  false                  ,                  maxArgLength:                  null                  ,                  quiet:                  imitation                  ,                  relative:                  faux                  ,                  reset:                  true                  ,                  beat:                  false                  ,                  verbose:                  false                  ,                  }                  )                

The maxArgLength option configures chunking of tasks into multiple parts that are run one after the other. This is to avoid issues on Windows platforms where the maximum length of the command line argument string is limited to 8192 characters. Lint-staged might generate a very long argument cord when there are many staged files. This choice is set automatically from the cli, simply not via the Node.js API past default.

Using with JetBrains IDEs (WebStorm, PyCharm, IntelliJ Idea, RubyMine, etc.)

Click to expand

Update : The latest version of JetBrains IDEs now support running hooks as you would expect.

When using the IDE'southward GUI to commit changes with the precommit hook, you might see inconsistencies in the IDE and control line. This is known effect at JetBrains so if you desire this fixed, please vote for it on YouTrack.

Until the issue is resolved in the IDE, you can employ the following config to work around it:

husky v1.ten

{                                      "husky"                  : {                                      "hooks"                  : {                                      "pre-commit"                  :                                      "lint-staged"                  ,                                      "mail-commit"                  :                                      "git update-index --again"                                    }   } }

croaking v0.x

{                                      "scripts"                  : {                                      "precommit"                  :                                      "lint-staged"                  ,                                      "postcommit"                  :                                      "git update-index --once again"                                    } }

Thanks to this comment for the set!

How to use lint-staged in a multi-package monorepo?

Click to aggrandize

Starting with v5.0, lint-staged automatically resolves the git root without any boosted configuration. Yous configure lint-staged as you lot normally would if your project root and git root were the aforementioned directory.

If you wish to use lint-staged in a multi bundle monorepo, information technology is recommended to install croaking in the root package.json. lerna tin be used to execute the precommit script in all sub-packages.

Case repo: sudo-suhas/lint-staged-multi-pkg.

Tin can I lint files exterior of the electric current project folder?

Click to aggrandize

tl;dr: Yes, but the design should kickoff with ../.

By default, lint-staged executes linters only on the files present within the project folder(where lint-staged is installed and run from). And so this question is relevant only when the projection folder is a child folder inside the git repo. In certain project setups, it might be desirable to bypass this restriction. See #425, #487 for more context.

lint-staged provides an escape hatch for the same(>= v7.3.0). For patterns that starting time with ../, all the staged files are allowed to match against the blueprint. Note that patterns like *.js, **/*.js will still only match the project files and not any of the files in parent or sibling directories.

Case repo: sudo-suhas/lint-staged-django-react-demo.

How tin can I ignore files from .eslintignore?

Click to expand

ESLint throws out warning File ignored considering of a matching ignore pattern. Utilize "--no-ignore" to override warnings that breaks the linting process ( if you lot used --max-warnings=0 which is recommended ).

ESLint < vii

Click to aggrandize

Based on the give-and-take from this upshot, it was decided that using the outlined script is the best route to fix this.

So you lot tin can setup a .lintstagedrc.js config file to do this:

                    const                    {                    CLIEngine                    }                    =                    require                    (                    'eslint'                    )                    const                    cli                    =                    new                    CLIEngine                    (                    {                    }                    )                    module                    .                    exports                    =                    {                    '*.js':                    (                    files                    )                    =>                    'eslint --max-warnings=0 '                    +                    files                    .                    filter                    (                    (                    file                    )                    =>                    !                    cli                    .                    isPathIgnored                    (                    file                    )                    )                    .                    join                    (                    ' '                    )                    ,                    }                  

ESLint >= 7

Click to expand

In versions of ESLint > seven, isPathIgnored is an async part and now returns a promise. The code below tin can exist used to reinstate the higher up functionality.

Since 10.v.3, any errors due to a bad ESLint config will come up through to the console.

                    const                    {                    ESLint                    }                    =                    require                    (                    'eslint'                    )                    const                    removeIgnoredFiles                    =                    async                    (                    files                    )                    =>                    {                    const                    eslint                    =                    new                    ESLint                    (                    )                    const                    isIgnored                    =                    wait                    Promise                    .                    all                    (                    files                    .                    map                    (                    (                    file                    )                    =>                    {                    return                    eslint                    .                    isPathIgnored                    (                    file                    )                    }                    )                    )                    const                    filteredFiles                    =                    files                    .                    filter                    (                    (                    _                    ,                    i                    )                    =>                    !                    isIgnored                    [                    i                    ]                    )                    render                    filteredFiles                    .                    join                    (                    ' '                    )                    }                    module                    .                    exports                    =                    {                    '**/*.{ts,tsx,js,jsx}':                    async                    (                    files                    )                    =>                    {                    const                    filesToLint                    =                    look                    removeIgnoredFiles                    (                    files                    )                    return                    [                    `eslint --max-warnings=0                                              ${                        filesToLint                        }                      `                    ]                    }                    ,                    }                  

reynoldsactics.blogspot.com

Source: https://www.npmjs.com/package/lint-staged/v/11.2.0-beta.1

0 Response to "Lint eslint Found Some Errors Please Fix Them and Try Committing Again"

Post a Comment

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel