1

I am new to SFDX plugin development. I have a node CLI tool I am trying to integrate into the SFDX CLI. I have added my js file with node modules to the directory src/commands/digitsec/s4/

When I run bin/run commands:digitsec:s4:runScan it starts the process, I can see my CLI hit my server and logs in successfully, but after this, I get a bunch of errors saying that node modules are not found:

(node:5268) Error Plugin: s4: command digitsec:s4:node_modules:axios:lib:helpers:spread not found
module: @oclif/config@1.17.0
task: toCached
plugin: s4
root: C:\Documents\Desktop\Digitsec\S4SalesforceCLIPlugin\s4
See more details with DEBUG=*
 »   Error: command commands:digitsec:s4:runScan not found

The thing is though, the command has already started and run the first function of my CLI. How does the SFDX cli lose track of my command after it has already been started?

Also, I have tried installing the @oclif and @salesforce dependencies in the S4 folder to try and see if the issue was missing those dependencies. When I install these dependencies within my plugin folder though, the entire command fails to run, and just prints out i: 1++ to infinity in console.

After installing just the @oclif/config package within the S4 folder, I no longer get the errors popping up, but when running my command it hangs after starting and console logs 'the result is 84'

After installing either @salesforce/core or @salesforce/command is when the problem starts. I guess the issue has to be in in one/both of these packages.

Thank you in advance

Edit: To be able to reproduce, follow the steps here https://developer.salesforce.com/docs/atlas.en-us.sfdx_cli_plugins.meta/sfdx_cli_plugins/cli_plugins_generate_scaffold.htm

After setting up the basic hello world tutorial, we are going to adjust the org.ts file to be

import { flags, SfdxCommand } from '@salesforce/command';
import { Messages, SfdxError } from '@salesforce/core';
import { AnyJson } from '@salesforce/ts-types';
import * as child from 'child_process';
import { Console } from 'console';
import * as util from 'util';

// Initialize Messages with the current plugin directory
Messages.importMessagesDirectory(__dirname);

// Load the specific messages for this file. Messages from @salesforce/command, @salesforce/core,
// or any library that is using the messages framework can also be loaded this way.
const messages = Messages.loadMessages('test', 'org');

export default class Org extends SfdxCommand {

  public static description = messages.getMessage('commandDescription');

  public static examples = [
  `$ sfdx hello:org --targetusername myOrg@example.com --targetdevhubusername devhub@org.com
  Hello world! This is org: MyOrg and I will be around until Tue Mar 20 2018!
  My hub org id is: 00Dxx000000001234
  `,
  `$ sfdx hello:org --name myname --targetusername myOrg@example.com
  Hello myname! This is org: MyOrg and I will be around until Tue Mar 20 2018!
  `
  ];

  public static args = [{name: 'file'}];

  protected static flagsConfig = {
    // flag with a value (-n, --name=VALUE)
    name: flags.string({char: 'n', description: messages.getMessage('nameFlagDescription')}),
    force: flags.boolean({char: 'f', description: messages.getMessage('forceFlagDescription')})
  };

  public async run(): Promise<AnyJson> {
    var output = '';
    console.log(__dirname);
    var foo: child.ChildProcess = child.exec("node ./src/commands/hello/testcli/s4", (stdout) => {
      console.log(stdout);   
    });

    foo.stdout.pipe(process.stdout);
    foo.stdout.on('data', function(data) {
        if(data.toString().search('pending') >= 0 || data.toString().search('completed') >= 0 ){
          console.log(data.toString()); 
          output += data.toString();
        }
    });
    foo.on('close', function (req, res) {
        console.log(`req: ${req}`);
        console.log(`res: ${res}`);
    })
    // Return an object to be displayed with --json
    return { orgId: output };
  }
}

Then, generate a new folder within commands/hello/ called testcli. We will generate a js file named s4.js within here. This will contain

module.exports = async function (user, pass, file, org, orgid, s4url) {
    var fs = require('fs');
    const axios = require('axios');
    var FormData = require('form-data');
    const Path = require('path');
    const https = require('https');
}

Create a package.json file within the testcli and install the required modules. When you then try to run bin/run hello:org you should get this in the errors

(node:18136) [MODULE_NOT_FOUND] Error Plugin: test: Cannot find module 'async'
Require stack:
- C:\Users\Documents\Desktop\test\src\commands\hello\testcli\node_modules\asynckit\bench.js
- C:\Users\Documents\Desktop\test\node_modules\@oclif\config\lib\plugin.js
- C:\Users\Documents\Desktop\test\node_modules\@oclif\config\lib\config.js
- C:\Users\Documents\Desktop\test\node_modules\@oclif\config\lib\index.js
- C:\Users\Documents\Desktop\test\node_modules\@oclif\command\lib\command.js
- C:\Users\Documents\Desktop\test\node_modules\@oclif\command\lib\index.js
- C:\Users\Documents\Desktop\test\bin\run
module: @oclif/config@1.17.0

If you then cd into the testcli folder, and try to install the @oclif without the @salesforce modules. Then you try to run, I get a response in console of:

the result is 84

And then if you install the @salesforce modules on top of that, we go back to i:++ to 1,000,000. Same result if you remove the @oclif modules and just keep the @salesforce modules

Edit2: So not exactly sure what the issue was, but after removing the node_modules from testCLI folder, reinstalling just the necessary node_modules, then running "yarn test" seemed to resolve the issue. I am still not sure what exactly caused this.

2
  • Is there a way we can repro it? I suggest deleting yarn.lock file and do a yarn install and then yarn build! Mar 12 at 0:05
  • Yes, just edited with reproduction steps Mar 12 at 17:48
0

Try running node ./src/commands/hello/testcli/s4 in our terminal, it'll probably fail with the same error it fails in your command.

I think in your s4 folder you need node_modules and you need to install there the modules for your script (i.e. axios, form-data, path), you don't need salesforce packages in your s4 folder, because it doesn't use them

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.