CLI Command Plugins
The redwood CLI has experimental support for extending the commands available.
This feature should be available in version 6.3.0
and is currently available in our next
, rc
and canary
releases.
Motivation
We want you to be able to have additional commands available at the redwood CLI that we might not ship with by default. This allows developers to use and develop additional commands to fill niches we might have left open.
We also want to make it super smooth for your favourite tools to give you extra commands you want. E.g. If you wanted to create a new cron job for defer then why shouldn’t you be able to have something like?
yarn rw @defer cron
How
You can explore this feature by using the experimental TOML configuration:
[experimental.cli]
autoInstall = true
[[experimental.cli.plugins]]
package = "@example/package"
The first line autoInstall = true
tells the CLI that if you try to run a command from a plugin package which is not currently installed then it will attempt to install it for you. You can always install commands manually by yourself like you would for any other npm package you use.
The next lines are:
[[experimental.cli.plugins]]
package = "@example/package"
This tells Redwood to take the commands exported by the @example/package
package and merge them into the CLI for you to use. The commands are merged under the @example
scope so that it’s clear where commands are coming from. As an example if that @example/package
package provided a hello-world
command then you could run it by running the following command:
yarn rw @example hello-world
Okay so how do packages like @example/package
actually tell the Redwood CLI about additional commands? All they need to do is export an array of yargs commands from their index called commands
like so:
# index.ts or whatever the main file of the package is
export const commands = [
{ ... },
{ ... },
]
You’re free to use yargs exactly like you would normally and define all the commands you want. You don’t have to have them all in this index file as you can of course structure your plugin code however you like and imply import you commands into index file.
All the commands in that array will be merged into the Redwood CLI under the packages scope as the example above showed.
A very basic example of a package like this can be found at: https://www.npmjs.com/package/@joshgmw/rw-plugin-one
Side note
This is actually how the current yarn rw data-migrate
and yarn rw storybook
commands work. They are CLI plugins which are registered under the hood. This is why Redwood no longer ships with storybook in it’s dependencies making it take up >10% less disk space on a fresh install!
Known limitations
There are some limitation to what we can currently do with this experimental feature:
-
Merging hierarchies of commands
We often logically structure a CLI into a tree of commands which help us better understand and navigate the tool. Think ofyarn rw setup
which has a number of subcommands likeyarn rw setup ui
- which itself has subcommands likeyarn rw setup ui tailwindcss
.
We currently are able to merge only simple hierarchies of commands when they are integrated from third party packages. This means all of the root commands a particular scope have to come from the same package. Here’s an example to make this easier to follow, both of the following commands must come from the same package:
yarn rw @example setup feature-one
yarn rw @example setup feature-two
If you have one package which registers commands foryarn rw @example setup
and then another tries to register more commands foryarn rw @example setup
then you will only be able to use the commands from the first package which was registered. -
Scoped NPM packages
We currently require that the packages which integrate command into the CLI are published under an NPM scope - which is the@name
part of@name/package
. There is no cost to publish packages like this but we understand sometimes this might introduce friction when permission to publish under a particular scope is limited.
Feedback
As with all our experimental features, we’d like to hear any feedback you have on this! Good, bad, ugly we enjoy hearing it as it pushes us forward in the correct direction and let’s us make Redwood better.
The comments of this post is the best place to leave your feedback.