Important: This documentation covers Yarn 1 (Classic).
For Yarn 2+ docs and migration guide, see yarnpkg.com.

Package detail

ember-unused-components

vastec2.6kMIT1.2.2

Search for unused components in your Ember project

ember, components, cleanup, unused

readme

npm version Build Status

ember-unused-components

This script searches for unused components in your Ember project. It supports:

  • classic structure,
  • POD structure,
  • Module Unification structure,
  • {{curly-braces}} syntax,
  • <AngleBrackets> syntax (also nested ones like <Angle::MyBrackets>),
  • ember-light-table's way of defining cellComponent: 'component-name' and component: 'component-name'
  • (component "component-name") helper used in templates
  • ignoring files,
  • whitelisting components unused temporary,
  • addons,
  • and components being used in addons with --includeAddons option.

It also has a very interesting statistics module.

Installation

$ yarn add -D ember-unused-components

or

$ npm install ember-unused-components --save-dev

Usage

Run in your app root directory:

$ ./node_modules/.bin/ember-unused-components

or

$ npx ember-unused-components

Expected output (simplified):


 No. of components: 277
 No. of unused components: 2 (7.22%)

 Unused components:
  - app/app-tab-panel
  - user/user-birthday

If you feel like there are too many components listed then check Configuration Section.

Stats

Make sure to try optional parameter --stats so you'll see some interesting stuff:

$ npx ember-unused-components --stats

 No. of components: 304
 No. of unused components: 8 (2.63%)

 Unused components:
  - report-header
  - report-row-title
  - reports-settings-dropdown
  - ui-checkbox-list
  - ui-manage-screen-title
  - ui-phone/-body/-message
  - ui-table/-cell-currency
  - ui-table/-cell-date

 The most used component: ui-form-button (101 occurrences)
 The number of components used just once: 171 (56.25%)
 Usage of {{curly-braces}} vs <AngleBrackets> syntax: 509 (56.81%) vs 387 (43.19%)
 Usage of (component "component-name") helper in templates: 70
 Usage in JS files (e.g. through `import` or ELT): 63

Occurrences

You can also print all occurrences of components that were found. Use --occurrences or --o:

$ npx ember-unused-components --occurrences

// simplified

user-avatar:

   > ./app/templates/components/user-card.hbs
    - <UserAvatar @src={{_imageSource}} />

welcome-page:

   > ./app/templates/application.hbs
    - {{welcome-page}}

[EXPERIMENTAL] Searching components contained in other packages

You can also print all occurrences of components that were found in included addons. Use --includeAddons to include all found addons, or includeAddons=company-* to only include addons that match company-*

$ npx ember-unused-components --occurrences --includeAddons=company-*

// simplified

[company-buttons] button-a:

   > ./app/templates/components/user-card.hbs
    - <ButtonA>Button Text</ButtonA>

welcome-page:

   > ./app/templates/application.hbs
    - {{welcome-page}}

Advanced usage

Typically the script should realize if you are using POD structure or not and find its way to components directory.

If you have problems with that, consider:

Forcing POD

To force using POD use --pods argument (alias: -p). Like this:

$ npx ember-unused-components --pods

The script will use the default directory of POD components: app/components. Please let me know if you had to force using POD. I made a simple guessing algorithm that should handle PODs out-of-the-box.

Forcing POD with the custom directory

Your app should be configured to have podModulePrefix property in config/environment.js if you are using POD but if it somehow doesn't work you can specify it through --pods-dir (alias: -pd). Like this:

$ npx ember-unused-components --pods --pods-dir="modules/components-repository"

Configuration

In typical use cases, it should work out of the box and you don't have to configure anything but you can consider the following options. First, you need to create .eucrc.js file in the root directory:

module.exports = {
  whitelist: [
    'app/app-tab-panel' // we will use it again soon
  ],
  ignore: [
    'app/templates/freestyle.hbs' // this is our template with style guides
  ],
  failOnUnused: false // optional, default is false, should we throw errors when we find unused components (useful in CI)
};

Whitelist

You can specify which components should not be treated as unused even if the script couldn't find their usage occurrences. This happens when:

  • you know that the component will be used in the future and you don't want to remove it and being reminded of that
  • you use some kind of "dynamic name resolution" for your components

For the "dynamic name resolution" scenario consider following example. Typical dynamic component look like this:

Template

{{component name car=car}}

JavaScript

name: computed('car.type', function () {
  return `car-card-${this.get('car.type')}`;
});

Result

Which may result in having following components in use:

  • car.type = 'suv' => {{car-card-suv car=car}}
  • car.type = 'sport' => {{car-card-sport car=car}}
  • car.type = 'sedan' => {{car-card-sedan car=car}}

Unfortunately, this static analysis tool doesn't understand it yet and doesn't know that your component car-card-suv has been used anywhere. You can whitelist these components from being marked as unused by referencing to them directly:

module.exports = {
  whitelist: [
    'car-card-suv',
    'car-card-sport',
    'car-card-sedan'
  ]
};

or by using wildcard:

module.exports = {
  whitelist: ['car-card-*']
};

Ignored files

A component might be used in some files like guidelines template (see ember-freestyle) that in fact does not indicate that it is in use. The best practice is to ignore that file:

module.exports = {
  ignore: [
    'app/templates/freestyle.hbs' // this is our template with style guides
  ]
};

Fail on unused

You might want to throw errors when unused components are found. This is especially useful when running in CI. This behavior is turned off by default.

Turn this behavior on in 2 ways:

Setting the failOnUnused property of your .eucrc.js file to true.

module.exports = {
  failOnUnused: true
};

// In practice, it might look something like this:

module.exports = {
  failOnUnused: process.env.CI // many CI services like Travis-ci and Circle-ci inject a CI env variable by default.
};

Passing the --fail-on-unused flag to the cli:

./node_modules/.bin/ember-unused-components --fail-on-unused

The .eucrc.js configuration file takes precedence over the cli argument.

Removing components

Auto removing components might be useful but it's not yet supported. Please consider that simple removal of:

  • template.hbs or templates/component-name.hbs
  • component.js or components/component-name.js
  • style.css or styles/components/style.css

might not remove everything you would like. Examples:

  • global CSS classes that are no longer used
  • 3rd party JS libraries used only in that component
  • translation keys that are no longer needed
  • assets (images) that are no longer used
  • local overwrites/adjustments for that component made by parent's CSS

So you'll still have some dead code because of unused components.

I encourage you to remove components from the list manually.

Best Practices

Once you delete unused components run the script once again :) You might find that now some other components are no longer used. This happens when the component is used in the unused component.

Example:

{{!-- users-list component --}}
{{#each users as |user|}}
  {{user-card user=user}}
{{/each}}

So user-card is being used but in unused component users-list. Once you will delete users-list component then user-card will not be longer used.

Contributing

If you feel like you need some functionality please raise an issue or event better Contribute!

Testing

It's very important to prepare test cases for fixes and new features.

We have a directory test-apps with applications that have different configs and different Ember versions which support or does not support certain "features" like angle brackets components or module unification project structure.

Running tests

  • yarn run test

Linting

  • yarn run lint

Debugging

  • npx ember-unused-components --debug

License

This project is licensed under the MIT License.

changelog

ember-unused-components CHANGELOG

On master, to release

  • nothing yet

1.2.2 (May 7, 2024)

FIX:

  • #190 Fixed ignored files not being ignored

MAINTENANCE:

  • #191 Update package-lock.json

1.2.1 (August 2, 2023)

FEATURES:

  • #189 Support typescript files and component colocation

1.2.0 (January 28, 2020)

FEATURES:

  • #52 [EXPERIMENTAL] - Search for unused components from addons :fire: Maybe you don't need that addon anymore?

REFACTOR:

  • #52 Improvements to components detection + internal restructuring that sets things in the right direction for future development

Special thanks to @jkeen for his huge work on the refactor and the experimental feature!

MAINTENANCE:

  • (#39) Bump ava from 2.3.0 to 2.4.0
  • (#42) Bump colors from 1.3.3 to 1.4.0
  • (#43, #61) Bump eslint-plugin-prettier from 3.1.0 to 3.1.2
  • (#45, #65) Bump yargs from 14.0.0 to 15.1.0
  • (#48, #62) Bump eslint from 6.3.0 to 6.8.0
  • (#49, #64) Bump eslint-config-prettier from 6.2.0 to 6.9.0
  • (#63) Bump eslint-plugin-node from 10.0.0 to 11.0.0

1.1.0 (September 10, 2019)

Although, there are no breaking changes this version is released as a new minor version (not a patch version). It introduces a new option (failOnUnused) which is switched off by default but in general can be dangerous for some projects. The package files were reduced so it also introduces some danger here.

FEATURES:

  • (#31) New option failOnUnused which throws and error when unused components were found (useful for CI)

MAINTENANCE:

  • (#32) Bump eslint from 6.2.2 to 6.3.0
  • (#33 #36) Bump eslint-plugin-node from 9.1.0 to 10.0.0
  • (#34) Improve a hint how to use tests-app in development
  • (#35) Bump eslint-config-prettier from 6.1.0 to 6.2.0
  • (#38) Specify library files in package.json - npm package size reduced from 2.2MB to 42.1kB (unpacked)

1.0.4 (August 27, 2019)

MAINTENANCE:

  • (#19) Bump eslint-config-prettier from 4.3.0 to 6.1.0
  • (#20) [Security] Bump lodash.merge from 4.6.1 to 4.6.2
  • (#21 #28) Bump eslint from 5.16.0 to 6.2.2
  • (#22) [Security] Bump lodash from 4.17.11 to 4.17.15
  • (#23) Bump ava from 2.1.0 to 2.3.0
  • (#24) Bump fs-extra from 8.0.1 to 8.1.0
  • (#25) Bump yargs from 13.2.4 to 14.0.0
  • (#26) Bump prettier from 1.17.1 to 1.18.2
  • (#29) [Security] Bump eslint-utils from 1.3.1 to 1.4.2

1.0.3 (June 26, 2019)

FIX:

  • Support POD structure when podModulePrefix is empty

1.0.2 (June 5, 2019)

FIX:

  • Prepared to be run in an empty project (no usage in percentage calculations etc...)

MAINTENANCE:

1.0.1 (May 24, 2019)

FIX:

  • ember-addon removed from keywords in package.json to prevent ember from running index.js on startup

1.0.0 (May 24, 2019)

COMPLETE REWRITE:

This is no longer an Ember addon but a NodeJS command-line script. The reasons for changing the approach were:

  • It's faster than ember-cli interface.
  • It gives more freedom when it comes to testing. Finally, we have multiple Ember app instances with a different configuration for testing purposes. That gives us more confidence when introducing changes.

FEATURES:

  • Support for <AngleBrackets> components (also nested ones, e.g. <User::UserCard/>)
  • Support for ember-light-table's way of defining cellComponent: 'component-name' and component: 'component-name'
  • Support for (component "component-name") helper used in templates
  • Support for Module Unification structure
  • Show percentage of unused components in the report
  • Stats module that shows:
    • The most used component
    • The number of components used just once
    • Usage of {{curly-braces}} vs <AngleBrackets> syntax
    • Usage of (component "component-name") helper in templates
    • Usage in JS files (e.g. through import or ELT)
  • Show occurrences of a component (use --occurrences or --o argument). Example:

    user/user-card:
    
    > ./app/templates/application.hbs
    - {{user/user-card}}

MAINTENANCE:

  • Running Travis CI

0.2.0 (June 29, 2018)

BUG FIXES:

  • Better match mechanism for finding component occurrences

0.1.1 (June 5, 2018)

FEATURES:

  • Support non-pods structure

BUG FIXES:

  • The proper command name for ember help

MAINTENANCE:

0.1.0 (May 24, 2018)

FEATURES:

  • Configuration: Ignore files in search for component's usage

0.0.1 (May 15, 2018)

  • core functionality with:
    • POD support
    • whitelist support