{"id":13483422,"url":"https://github.com/kaelzhang/node-ignore","last_synced_at":"2025-05-13T19:09:22.651Z","repository":{"id":10374947,"uuid":"12519245","full_name":"kaelzhang/node-ignore","owner":"kaelzhang","description":"🔍 node-ignore is the manager and filter for .gitignore rules, the one used by eslint, prettier and many others.","archived":false,"fork":false,"pushed_at":"2025-04-25T02:29:19.000Z","size":289,"stargazers_count":466,"open_issues_count":3,"forks_count":46,"subscribers_count":10,"default_branch":"master","last_synced_at":"2025-04-25T21:58:47.817Z","etag":null,"topics":["gitignore","ignore-files","ignore-patterns","ignore-rules","javascript","nodejs"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kaelzhang.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE-MIT","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null},"funding":{"github":"kaelzhang","patreon":null,"open_collective":"node-ignore","ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"otechie":null,"custom":null}},"created_at":"2013-09-01T10:52:11.000Z","updated_at":"2025-04-25T02:29:22.000Z","dependencies_parsed_at":"2024-01-13T18:24:05.987Z","dependency_job_id":"8e8a152b-7974-4fb1-9245-4b0130598b28","html_url":"https://github.com/kaelzhang/node-ignore","commit_stats":{"total_commits":290,"total_committers":18,"mean_commits":16.11111111111111,"dds":0.4724137931034482,"last_synced_commit":"d88109f144dca3e1502d356983d99606a837c5c3"},"previous_names":[],"tags_count":74,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kaelzhang%2Fnode-ignore","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kaelzhang%2Fnode-ignore/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kaelzhang%2Fnode-ignore/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kaelzhang%2Fnode-ignore/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kaelzhang","download_url":"https://codeload.github.com/kaelzhang/node-ignore/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250921933,"owners_count":21508242,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["gitignore","ignore-files","ignore-patterns","ignore-rules","javascript","nodejs"],"created_at":"2024-07-31T17:01:11.104Z","updated_at":"2025-05-13T19:09:22.644Z","avatar_url":"https://github.com/kaelzhang.png","language":"JavaScript","readme":"| Linux / MacOS / Windows | Coverage | Downloads |\n| ----------------------- | -------- | --------- |\n| [![build][bb]][bl]      | [![coverage][cb]][cl] | [![downloads][db]][dl] |\n\n[bb]: https://github.com/kaelzhang/node-ignore/actions/workflows/nodejs.yml/badge.svg\n[bl]: https://github.com/kaelzhang/node-ignore/actions/workflows/nodejs.yml\n\n[cb]: https://codecov.io/gh/kaelzhang/node-ignore/branch/master/graph/badge.svg\n[cl]: https://codecov.io/gh/kaelzhang/node-ignore\n\n[db]: http://img.shields.io/npm/dm/ignore.svg\n[dl]: https://www.npmjs.org/package/ignore\n\n# ignore\n\n`ignore` is a manager, filter and parser which implemented in pure JavaScript according to the [.gitignore spec 2.22.1](http://git-scm.com/docs/gitignore).\n\n`ignore` is used by eslint, gitbook and [many others](https://www.npmjs.com/browse/depended/ignore).\n\nPay **ATTENTION** that [`minimatch`](https://www.npmjs.org/package/minimatch) (which used by `fstream-ignore`) does not follow the gitignore spec.\n\nTo filter filenames according to a .gitignore file, I recommend this npm package, `ignore`.\n\nTo parse an `.npmignore` file, you should use `minimatch`, because an `.npmignore` file is parsed by npm using `minimatch` and it does not work in the .gitignore way.\n\n### Tested on\n\n`ignore` is fully tested, and has more than **five hundreds** of unit tests.\n\n- Linux + Node: `0.8` - `7.x`\n- Windows + Node: `0.10` - `7.x`, node \u003c `0.10` is not tested due to the lack of support of appveyor.\n\nActually, `ignore` does not rely on any versions of node specially.\n\nSince `4.0.0`, ignore will no longer support `node \u003c 6` by default, to use in node \u003c 6, `require('ignore/legacy')`. For details, see [CHANGELOG](https://github.com/kaelzhang/node-ignore/blob/master/CHANGELOG.md).\n\n## Table Of Main Contents\n\n- [Usage](#usage)\n- [`Pathname` Conventions](#pathname-conventions)\n- See Also:\n  - [`glob-gitignore`](https://www.npmjs.com/package/glob-gitignore) matches files using patterns and filters them according to gitignore rules.\n- [Upgrade Guide](#upgrade-guide)\n\n## Install\n\n```sh\nnpm i ignore\n```\n\n## Usage\n\n```js\nimport ignore from 'ignore'\nconst ig = ignore().add(['.abc/*', '!.abc/d/'])\n```\n\n### Filter the given paths\n\n```js\nconst paths = [\n  '.abc/a.js',    // filtered out\n  '.abc/d/e.js'   // included\n]\n\nig.filter(paths)        // ['.abc/d/e.js']\nig.ignores('.abc/a.js') // true\n```\n\n### As the filter function\n\n```js\npaths.filter(ig.createFilter()); // ['.abc/d/e.js']\n```\n\n### Win32 paths will be handled\n\n```js\nig.filter(['.abc\\\\a.js', '.abc\\\\d\\\\e.js'])\n// if the code above runs on windows, the result will be\n// ['.abc\\\\d\\\\e.js']\n```\n\n## Why another ignore?\n\n- `ignore` is a standalone module, and is much simpler so that it could easy work with other programs, unlike [isaacs](https://npmjs.org/~isaacs)'s [fstream-ignore](https://npmjs.org/package/fstream-ignore) which must work with the modules of the fstream family.\n\n- `ignore` only contains utility methods to filter paths according to the specified ignore rules, so\n  - `ignore` never try to find out ignore rules by traversing directories or fetching from git configurations.\n  - `ignore` don't cares about sub-modules of git projects.\n\n- Exactly according to [gitignore man page](http://git-scm.com/docs/gitignore), fixes some known matching issues of fstream-ignore, such as:\n  - '`/*.js`' should only match '`a.js`', but not '`abc/a.js`'.\n  - '`**/foo`' should match '`foo`' anywhere.\n  - Prevent re-including a file if a parent directory of that file is excluded.\n  - Handle trailing whitespaces:\n    - `'a '`(one space) should not match `'a  '`(two spaces).\n    - `'a \\ '` matches `'a  '`\n  - All test cases are verified with the result of `git check-ignore`.\n\n# Methods\n\n## .add(pattern: string | Ignore): this\n## .add(patterns: Array\u003cstring | Ignore\u003e): this\n## .add({pattern: string, mark?: string}): this  since 7.0.0\n\n- **pattern** `string | Ignore` An ignore pattern string, or the `Ignore` instance\n- **patterns** `Array\u003cstring | Ignore\u003e` Array of ignore patterns.\n- **mark?** `string` Pattern mark, which is used to associate the pattern with a certain marker, such as the line no of the `.gitignore` file. Actually it could be an arbitrary string and is optional.\n\nAdds a rule or several rules to the current manager.\n\nReturns `this`\n\nNotice that a line starting with `'#'`(hash) is treated as a comment. Put a backslash (`'\\'`) in front of the first hash for patterns that begin with a hash, if you want to ignore a file with a hash at the beginning of the filename.\n\n```js\nignore().add('#abc').ignores('#abc')    // false\nignore().add('\\\\#abc').ignores('#abc')   // true\n```\n\n`pattern` could either be a line of ignore pattern or a string of multiple ignore patterns, which means we could just `ignore().add()` the content of a ignore file:\n\n```js\nignore()\n.add(fs.readFileSync(filenameOfGitignore).toString())\n.filter(filenames)\n```\n\n`pattern` could also be an `ignore` instance, so that we could easily inherit the rules of another `Ignore` instance.\n\n## .ignores(pathname: [Pathname](#pathname-conventions)): boolean\n\n\u003e new in 3.2.0\n\nReturns `Boolean` whether `pathname` should be ignored.\n\n```js\nig.ignores('.abc/a.js')    // true\n```\n\nPlease **PAY ATTENTION** that `.ignores()` is **NOT** equivalent to `git check-ignore` although in most cases they return equivalent results.\n\nHowever, for the purposes of imitating the behavior of `git check-ignore`, please use `.checkIgnore()` instead.\n\n### `Pathname` Conventions:\n\n#### 1. `Pathname` should be a `path.relative()`d pathname\n\n`Pathname` should be a string that have been `path.join()`ed, or the return value of `path.relative()` to the current directory,\n\n```js\n// WRONG, an error will be thrown\nig.ignores('./abc')\n\n// WRONG, for it will never happen, and an error will be thrown\n// If the gitignore rule locates at the root directory,\n// `'/abc'` should be changed to `'abc'`.\n// ```\n// path.relative('/', '/abc')  -\u003e 'abc'\n// ```\nig.ignores('/abc')\n\n// WRONG, that it is an absolute path on Windows, an error will be thrown\nig.ignores('C:\\\\abc')\n\n// Right\nig.ignores('abc')\n\n// Right\nig.ignores(path.join('./abc'))  // path.join('./abc') -\u003e 'abc'\n```\n\nIn other words, each `Pathname` here should be a relative path to the directory of the gitignore rules.\n\nSuppose the dir structure is:\n\n```\n/path/to/your/repo\n    |-- a\n    |   |-- a.js\n    |\n    |-- .b\n    |\n    |-- .c\n         |-- .DS_store\n```\n\nThen the `paths` might be like this:\n\n```js\n[\n  'a/a.js'\n  '.b',\n  '.c/.DS_store'\n]\n```\n\n#### 2. filenames and dirnames\n\n`node-ignore` does NO `fs.stat` during path matching, so `node-ignore` treats\n- `foo` as a file\n- **`foo/` as a directory**\n\nFor the example below:\n\n```js\n// First, we add a ignore pattern to ignore a directory\nig.add('config/')\n\n// `ig` does NOT know if 'config', in the real world,\n//   is a normal file, directory or something.\n\nig.ignores('config')\n// `ig` treats `config` as a file, so it returns `false`\n\nig.ignores('config/')\n// returns `true`\n```\n\nSpecially for people who develop some library based on `node-ignore`, it is important to understand that.\n\nUsually, you could use [`glob`](http://npmjs.org/package/glob) with `option.mark = true` to fetch the structure of the current directory:\n\n```js\nimport glob from 'glob'\n\nglob('**', {\n  // Adds a / character to directory matches.\n  mark: true\n}, (err, files) =\u003e {\n  if (err) {\n    return console.error(err)\n  }\n\n  let filtered = ignore().add(patterns).filter(files)\n  console.log(filtered)\n})\n```\n\n\n## .filter(paths: Array\u0026lt;Pathname\u0026gt;): Array\u0026lt;Pathname\u0026gt;\n\n```ts\ntype Pathname = string\n```\n\nFilters the given array of pathnames, and returns the filtered array.\n\n- **paths** `Array.\u003cPathname\u003e` The array of `pathname`s to be filtered.\n\n## .createFilter()\n\nCreates a filter function which could filter an array of paths with `Array.prototype.filter`.\n\nReturns `function(path)` the filter function.\n\n## .test(pathname: Pathname): TestResult\n\n\u003e New in 5.0.0\n\nReturns `TestResult`\n\n```ts\n// Since 5.0.0\ninterface TestResult {\n  ignored: boolean\n  // true if the `pathname` is finally unignored by some negative pattern\n  unignored: boolean\n  // The `IgnoreRule` which ignores the pathname\n  rule?: IgnoreRule\n}\n\n// Since 7.0.0\ninterface IgnoreRule {\n  // The original pattern\n  pattern: string\n  // Whether the pattern is a negative pattern\n  negative: boolean\n  // Which is used for other packages to build things upon `node-ignore`\n  mark?: string\n}\n```\n\n- `{ignored: true, unignored: false}`: the `pathname` is ignored\n- `{ignored: false, unignored: true}`: the `pathname` is unignored\n- `{ignored: false, unignored: false}`: the `pathname` is never matched by any ignore rules.\n\n## .checkIgnore(target: string): TestResult\n\n\u003e new in 7.0.0\n\nDebugs gitignore / exclude files, which is equivalent to `git check-ignore -v`. Usually this method is used for other packages to implement the function of `git check-ignore -v` upon `node-ignore`\n\n- **target** `string` the target to test.\n\nReturns `TestResult`\n\n```js\nig.add({\n  pattern: 'foo/*',\n  mark: '60'\n})\n\nconst {\n  ignored,\n  rule\n} = checkIgnore('foo/')\n\nif (ignored) {\n  console.log(`.gitignore:${result}:${rule.mark}:${rule.pattern} foo/`)\n}\n\n// .gitignore:60:foo/* foo/\n```\n\nPlease pay attention that this method does not have a strong built-in cache mechanism.\n\nThe purpose of introducing this method is to make it possible to implement the `git check-ignore` command in JavaScript based on `node-ignore`.\n\nSo do not use this method in those situations where performance is extremely important.\n\n## static `isPathValid(pathname): boolean` since 5.0.0\n\nCheck whether the `pathname` is an valid `path.relative()`d path according to the [convention](#1-pathname-should-be-a-pathrelatived-pathname).\n\nThis method is **NOT** used to check if an ignore pattern is valid.\n\n```js\nimport {isPathValid} from 'ignore'\n\nisPathValid('./foo')  // false\n```\n\n## \u003cstrike\u003e.addIgnoreFile(path)\u003c/strike\u003e\n\nREMOVED in `3.x` for now.\n\nTo upgrade `ignore@2.x` up to `3.x`, use\n\n```js\nimport fs from 'fs'\n\nif (fs.existsSync(filename)) {\n  ignore().add(fs.readFileSync(filename).toString())\n}\n```\n\ninstead.\n\n## ignore(options)\n\n### `options.ignorecase` since 4.0.0\n\nSimilar to the `core.ignorecase` option of [git-config](https://git-scm.com/docs/git-config), `node-ignore` will be case insensitive if `options.ignorecase` is set to `true` (the default value), otherwise case sensitive.\n\n```js\nconst ig = ignore({\n  ignorecase: false\n})\n\nig.add('*.png')\n\nig.ignores('*.PNG')  // false\n```\n\n### `options.ignoreCase?: boolean` since 5.2.0\n\nWhich is an alternative to `options.ignoreCase`\n\n### `options.allowRelativePaths?: boolean` since 5.2.0\n\nThis option brings backward compatibility with projects which based on `ignore@4.x`. If `options.allowRelativePaths` is `true`, `ignore` will not check whether the given path to be tested is [`path.relative()`d](#pathname-conventions).\n\nHowever, passing a relative path, such as `'./foo'` or `'../foo'`, to test if it is ignored or not is not a good practise, which might lead to unexpected behavior\n\n```js\nignore({\n  allowRelativePaths: true\n}).ignores('../foo/bar.js') // And it will not throw\n```\n\n****\n\n# Upgrade Guide\n\n## Upgrade 4.x -\u003e 5.x\n\nSince `5.0.0`, if an invalid `Pathname` passed into `ig.ignores()`, an error will be thrown, unless `options.allowRelative = true` is passed to the `Ignore` factory.\n\nWhile `ignore \u003c 5.0.0` did not make sure what the return value was, as well as\n\n```ts\n.ignores(pathname: Pathname): boolean\n\n.filter(pathnames: Array\u003cPathname\u003e): Array\u003cPathname\u003e\n\n.createFilter(): (pathname: Pathname) =\u003e boolean\n\n.test(pathname: Pathname): {ignored: boolean, unignored: boolean}\n```\n\nSee the convention [here](#1-pathname-should-be-a-pathrelatived-pathname) for details.\n\nIf there are invalid pathnames, the conversion and filtration should be done by users.\n\n```js\nimport {isPathValid} from 'ignore' // introduced in 5.0.0\n\nconst paths = [\n  // invalid\n  //////////////////\n  '',\n  false,\n  '../foo',\n  '.',\n  //////////////////\n\n  // valid\n  'foo'\n]\n.filter(isPathValid)\n\nig.filter(paths)\n```\n\n## Upgrade 3.x -\u003e 4.x\n\nSince `4.0.0`, `ignore` will no longer support node \u003c 6, to use `ignore` in node \u003c 6:\n\n```js\nvar ignore = require('ignore/legacy')\n```\n\n## Upgrade 2.x -\u003e 3.x\n\n- All `options` of 2.x are unnecessary and removed, so just remove them.\n- `ignore()` instance is no longer an [`EventEmitter`](nodejs.org/api/events.html), and all events are unnecessary and removed.\n- `.addIgnoreFile()` is removed, see the [.addIgnoreFile](#addignorefilepath) section for details.\n\n****\n\n# Collaborators\n\n- [@whitecolor](https://github.com/whitecolor) *Alex*\n- [@SamyPesse](https://github.com/SamyPesse) *Samy Pessé*\n- [@azproduction](https://github.com/azproduction) *Mikhail Davydov*\n- [@TrySound](https://github.com/TrySound) *Bogdan Chadkin*\n- [@JanMattner](https://github.com/JanMattner) *Jan Mattner*\n- [@ntwb](https://github.com/ntwb) *Stephen Edgar*\n- [@kasperisager](https://github.com/kasperisager) *Kasper Isager*\n- [@sandersn](https://github.com/sandersn) *Nathan Shively-Sanders*\n","funding_links":["https://github.com/sponsors/kaelzhang","https://opencollective.com/node-ignore"],"categories":["JavaScript"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkaelzhang%2Fnode-ignore","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkaelzhang%2Fnode-ignore","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkaelzhang%2Fnode-ignore/lists"}