Skip to content

ignorePatterns not applied to package.json discovery in unused_dependencies analysis #124

@OmerGronich

Description

@OmerGronich

What happened?

When **/dist/** is in ignorePatterns, fallow correctly excludes dist/ files from source analysis (unused_files, unused_exports, unused_class_members, etc.) but does not exclude dist/package.json files from unused_dependencies scanning.

This causes false positive unused dependency reports for every dependency listed in build-artifact package.json files (e.g., those generated by ng-packagr, tsc, or Rollup into dist/).

This is common in Angular/TypeScript monorepos where libraries compile to dist/ and ng-packagr generates a dist/package.json with the library's runtime dependencies. Even when dist/ is excluded via ignorePatterns: ["**/dist/**"] in .fallowrc.json, fallow still discovers and scans dist/package.json files for unused_dependencies.

Reproduction

Create the following files in an empty directory:

package.json:

{
	"name": "b23-ignore-patterns-unused-deps",
	"version": "1.0.0",
	"private": true,
	"workspaces": [
		"packages/**",
		"!**/dist/**"
	]
}

tsconfig.json:

{
	"compilerOptions": {
		"target": "ES2022",
		"module": "ES2022",
		"moduleResolution": "bundler",
		"strict": true,
		"esModuleInterop": true,
		"declaration": true,
		"outDir": "dist",
		"baseUrl": ".",
		"paths": {
			"@repro/my-lib": ["packages/my-lib/src/index.ts"]
		}
	},
	"include": ["packages/*/src/**/*.ts"]
}

.fallowrc.json:

{
	"ignorePatterns": ["**/dist/**"]
}

packages/my-lib/package.json (source — the real dependency declaration):

{
	"name": "@repro/my-lib",
	"version": "1.0.0",
	"private": true,
	"module": "./dist/esm2022/index.js",
	"dependencies": {
		"lodash": "^4.17.21",
		"is-odd": "^3.0.1"
	}
}

packages/my-lib/src/index.ts:

import { chunk } from 'lodash';

export function splitItems<T>(items: T[], size: number): T[][] {
	return chunk(items, size);
}

packages/my-lib/dist/package.json (build artifact — generated by ng-packagr/tsc):

{
	"name": "@repro/my-lib",
	"version": "1.0.0",
	"module": "./esm2022/index.js",
	"dependencies": {
		"lodash": "^4.17.21",
		"is-odd": "^3.0.1",
		"moment": "^2.30.1",
		"uuid": "^9.0.0",
		"chalk": "^5.3.0"
	}
}

packages/my-lib/dist/esm2022/index.js:

import { chunk } from 'lodash';
export function splitItems(items, size) {
	return chunk(items, size);
}

packages/my-app/package.json:

{
	"name": "@repro/my-app",
	"version": "1.0.0",
	"private": true,
	"dependencies": {
		"@repro/my-lib": "1.0.0"
	}
}

packages/my-app/src/index.ts:

import { splitItems } from '@repro/my-lib';

const result = splitItems([1, 2, 3, 4, 5], 2);
console.log(result);

Then run:

npm install --ignore-scripts
fallow dead-code --unused-deps --format json --no-cache --quiet

Expected behavior

Only is-odd in packages/my-lib/package.json should be reported as unused (it's genuinely not imported by any source file). Nothing from packages/my-lib/dist/package.json should appear because dist/ is in ignorePatterns.

Expected: 1 issue

Actual behavior

UNUSED DEPENDENCIES (6):
  lodash    -> packages/my-lib/dist/package.json    ← FP
  is-odd    -> packages/my-lib/dist/package.json    ← FP
  moment    -> packages/my-lib/dist/package.json    ← FP
  uuid      -> packages/my-lib/dist/package.json    ← FP
  chalk     -> packages/my-lib/dist/package.json    ← FP
  is-odd    -> packages/my-lib/package.json         ← correct

5 of 6 findings are false positives from dist/package.json, which is in an ignored directory.

Actual: 6 issues (5 false positives)

Evidence that ignorePatterns works for other analysis types

fallow list correctly excludes dist/ files from source discovery:

{
  "files": [
    "packages/my-app/src/index.ts",
    "packages/my-lib/src/index.ts"
  ]
}

No dist/ files appear. The ignorePatterns filter is applied to source file discovery but not to package.json discovery for dependency analysis.

Fallow version

2.35.0

Operating system

macOS

Configuration

{"ignorePatterns": ["**/dist/**"]}

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions