Hone logo
Hone
Problems

Angular Unused Code Detector

Identifying and removing unused code is crucial for maintaining a clean, performant, and manageable Angular application. This challenge asks you to build a utility function that analyzes an Angular project's TypeScript files and identifies unused components, services, pipes, and directives. This will help developers reduce bundle sizes and improve code clarity.

Problem Description

You are tasked with creating a TypeScript function called findUnusedAngularCode that takes the absolute path to an Angular project's root directory as input. The function should analyze all .ts files within the project (recursively) and identify Angular components, services, pipes, and directives that are not imported or referenced anywhere else in the project.

What needs to be achieved:

  1. File Traversal: Recursively traverse the project directory to find all .ts files.
  2. Angular Class Identification: Identify Angular components, services, pipes, and directives within each .ts file based on their decorators (@Component, @Service, @Pipe, @Directive).
  3. Dependency Analysis: Analyze each .ts file to determine which Angular classes are imported and used.
  4. Unused Code Detection: Compare the identified Angular classes with the imported/used classes to determine which are unused.
  5. Return Results: Return a list of unused Angular classes, including their full file paths and class names.

Key Requirements:

  • The function must handle circular dependencies gracefully.
  • The function should be able to identify classes decorated with multiple decorators (e.g., a component that also implements an interface).
  • The function should ignore files in node_modules.
  • The function should be robust and handle various project structures.

Expected Behavior:

The function should return an array of objects, where each object represents an unused Angular class and has the following properties:

  • filePath: The absolute path to the file containing the unused class.
  • className: The name of the unused class.
  • type: The type of Angular class (e.g., "Component", "Service", "Pipe", "Directive").

Edge Cases to Consider:

  • Empty projects.
  • Projects with no Angular classes.
  • Projects with complex module structures.
  • Files with syntax errors (should be skipped).
  • Dynamically imported modules (these are difficult to detect and can be ignored for this challenge).
  • Classes used via reflection (very difficult to detect and can be ignored).

Examples

Example 1:

Input: "/path/to/my-angular-project"
Output: [
  {
    "filePath": "/path/to/my-angular-project/src/app/unused/UnusedComponent.ts",
    "className": "UnusedComponent",
    "type": "Component"
  },
  {
    "filePath": "/path/to/my-angular-project/src/app/unused/UnusedService.ts",
    "className": "UnusedService",
    "type": "Service"
  }
]
Explanation: The project contains two Angular classes, `UnusedComponent` and `UnusedService`, which are not imported or used anywhere else in the project.

Example 2:

Input: "/path/to/another-angular-project"
Output: []
Explanation: The project contains no unused Angular classes. All identified classes are imported and used elsewhere.

Example 3: (Edge Case - Empty Project)

Input: "/path/to/empty-angular-project"
Output: []
Explanation: The project is empty and contains no TypeScript files, so no unused classes are found.

Constraints

  • File System Access: The function must be able to read files from the file system.
  • Performance: The function should be reasonably efficient. Analyzing a project with 100+ TypeScript files should take no longer than 5 seconds.
  • Input: The input must be a string representing the absolute path to the Angular project's root directory.
  • Output: The output must be an array of objects conforming to the structure described above.
  • Error Handling: The function should gracefully handle errors such as invalid file paths or file access issues. Log errors to the console, but do not throw exceptions.

Notes

  • Consider using a library like glob or fs-extra to simplify file system traversal.
  • Regular expressions can be helpful for identifying Angular classes based on their decorators.
  • A simple import analysis can be performed by searching for import statements within each .ts file.
  • Focus on identifying the most common types of unused Angular code (components, services, pipes, directives). More advanced analysis (e.g., detecting unused methods within a class) is beyond the scope of this challenge.
  • Prioritize correctness and clarity over extreme optimization. A functional solution that accurately identifies unused code is more valuable than a highly optimized but potentially buggy solution.
Loading editor...
typescript