Create Ember Addon with command line support

Adding command line support to your Ember Addon is pretty straight-forward.

Disclaimer:
The script presented in this post might be written without Ember ecosystem and run via `npm run script` command. But it was the only thing that came to my mind and must serve us as an example.

It has been a while when I started working with Ember. So I need to maintain and actively develop some projects. Recently I’ve realized we have a problem with the number of components. Well… the problem is that I don’t know if we need them all.

So let’s build Ember Addon that will check that. A developer will just run

$ ember unused:components

in the root of the project and should see:

More than 20% of components is unused in this project

In case you would like to see the whole code — check the repo:

It is fully usable so let me know if you found any unused components in your project ;)

Create an Addon

Take a deep breath and run:

$ ember addon ember-awesome-addon-name

Plan the structure

There is no any strong preference towards how you will organize “command line addon” but I found the following pretty nice:

ember-awesome-addon-name/
├── addon/
├── app/
├── ...
├── lib/
│ ├── commands/
│ └── unused.js
│ └── components.js

├── test/
└── ...

The meat: add the command

Go to index.js and add following:

'use strict';module.exports = {
name: 'ember-awesome-addon-name',
includedCommands() {
return {
'unused:components': require('./lib/commands/unused')
};
}

};

When using includedCommands function you are expected to return an object with the key in align to command name. It will still work if your key will be different (e.g. unusedComponents) but ember help is not going to show the description in that case.

Define the command

Go to lib/commands/unused.js and define the following:

'use strict';const components = require('../components');module.exports = {
name: 'unused:components',
aliases: ['uc'],
availableOptions: [
{ name: 'pods', type: Boolean, default: false, aliases: ['p'] },
{ name: 'pods-dir', type: String, aliases: ['pd'] }
],
description: 'Search for unused components in your Ember project',
run(commandOptions) {
components.searchForUnusedComponents(commandOptions);
}
};

A brief description of properties:

  • name — it will be used as a command you put after ember, e.g. ember nice if name: 'nice'
  • aliases — just a list of aliases for your long command
  • availableOptions — these are the arguments you will allow the developer to pass with the command like ember nice --what=everything. Like you see we set the type, can set the default value and even aliases
  • description — keep it simple. It will be shown when someone uses ember help command:
Addon description via ember help command
  • run — this function is fired when the command was used. I recommend to again use a different file for that and keep commands directory tidy.

There are much more options to be specified but I believe these are the most common and easy to understand. Check Command API for more.

Run

Last thing worth mentioning is that run function receives commandOptions argument which is an object with arguments passed with the command (remember availableOptions?).

Just as a side note — there are all arguments, not only the ones defined in availableOptions.

That’s it. Have fun and check the repo if needed 🍻.

I connect humans and machines. Usually write about interfaces, digital products, and UX on tomekdev.com. Founder of checknlearn.com. A bit nerdy 🤓

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store