5

I'm trying to install a sfdx plugin, and the only install instructions I can find are sfdx plugins:install plugin-name.

With modern development practices, we define our project's Node development dependencies in a root package.json file. To install and update dependencies and ensure we're using specific versions, we update the package.json file to include the project's dependencies, and use npm to install and update dependencies. "We" meaning all engineers using Node for the last 10 years.

sfdx plugins:install is bad practice for a few reasons:

  • It's an extra manual step for all engineers
  • It's an extra manual step for build tools
  • The version isn't declaratively controllable
  • It's against the grain of modern development practices

How can we install a sfdx plugin without forcing manual out of band steps?

If I try this:

npm install --save-dev pluginname

It works, but sfdx doesn't find the plugin:

Warning: pluginname:action is not a sfdx command.
2
  • So, I know there's a way (I've seen a plugin that does it), but it depends on the developer to make this happen. I don't know what it is though, but I've asked around for you.
    – sfdcfox
    Apr 20, 2021 at 23:37
  • See this thread, includes a link to a repo that does this. Basically, the scripts just do sfdx plugins:link node_modules/plugin-name when they need to link various commands. This runs on Heroku automatically, as no out-of-band/manual steps, it's just a matter of linking. Hope this helps.
    – sfdcfox
    Apr 21, 2021 at 10:20

3 Answers 3

3

There's a workaround you can put in place to avoid the extra sfdx plugin:install step. Sadly sfdx doesn't play very nicely with the Node ecosystem so you still have to jump through a hoop to make it work.

Under the hood sfdx plugin:install apparently runs a command to link the plugin install location to somewhere sfdx can find it.

To replicate the sfdx behavior without the manual step: install the plugin as normal:

npm install --save-dev myplugin

Then set up an npm script to link and run the package. This isn't great because the link has globally polluting side effects on sfdx, but it will work.

Open your root package.json file and add something to the scripts section, like:

  "scripts": {
    "do-the-thing": "sfdx plugins:link node_modules/myplugin && sfdx myplugin --do-whatever"
  },

Then to use your plugin, you can run:

npm run do-the-thing

npm also supports passing arguments to scripts with the bash end-positional-argument separator --, such as

npm run do-the-thing -- --my-plugin-flag

If you really wanted to, you could also run the plugin install command instead in the script:

  "scripts": {
    "do-the-thing": "sfdx plugins:install myplugin && sfdx myplugin --do-whatever"
  },

This doesn't let you version control the plugin dependency+version though.

I hope sfdx matures and becomes more standard in terms of development practices. I've filed a feature request with the project to see if they'll consider supporting this as a first class workflow.

2

Probably there are other ways, but I typically do the following to make my plugins available for install with npm and package.json.

1. Prepare the plugin

We need to expose the binary (bin/run) of the plugin. My recommendation is to use the name of your npm package as binary name (see the notes about npx down).

Let's assume you've generated your plugin using the sfdx plugins:generate sfdx-plugin-myawesomeplugin command and your main topic is hello (sfdx hello).

You would then need to modify the plugin's package.json file as follows:

    ...
    "bin": {
        "sfdx-plugin-myawesomeplugin": "bin/run"
    },
    ...
    "files": {
        "/bin",
        ...
    },
    ...

2. Install and use the plugin

Assuming you now want to use your plugin in another project called acme-project.

Install the plugin with npm inside the acme-project directory:

npm install --save-dev sfdx-plugin-myawesomeplugin

Now instead of calling your plugin with sfdx you'd need to use npx sfdx-plugin-myawesomeplugin:

Example:

Instead of

sfdx hello --help

use

npx sfdx-plugin-myawesomeplugin hello --help

Here npx sfdx-plugin-myawesomeplugin resolves the binary named sfdx-plugin-myawesomeplugin from the package also named sfdx-plugin-myawesomeplugin. They can have different names but this keeps the npx command short (see npx docs for more info).

1
  • This looks like a good answer for plugin authors, if you have control over the plugin itself. I'm not sure I even understand why it would be an sfdx plugin (or why anyone would make an sfdx plugin) when all it's doing is running a bin/ file.
    – Andy Ray
    Apr 22, 2021 at 16:33
1

I've just recently found another way - without linking plugins to the global installation path or preparing the plugin itself. So I've documented this approach in an article: https://hutte.io/trails/dependency-management-for-sfdx-projects/

In short, you can install and use sfdx plugins in your sfdx project by setting the environment variable SFDX_DATA_DIR to "$(pwd)" (the current directory). This will register the dependency in package.json and install it to ./node_modules.

Example:

export SFDX_DATA_DIR="$(pwd)"
sfdx plugins install sfdmu
sfdx sfdmu --help

Now other developers will be able to setup their development environment for this sfdx project by running:

export SFDX_DATA_DIR="$(pwd)"
yarn install

Please note that you'll need to set this environment variable not only for the installation but also when using the plugins. So tools like direnv might be useful to accomplish that.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .