1

i have react library created inside nx mono repo using this version

nx: 15.6.3

i've added inside the packages/my-library command to run multiple commands

generate react component generate react-stories

using these plugins @nrwl/react:component - @nrwl/react:component-story

this is the target

"generate-atom": {
      "executor": "nx:run-commands",
      "options": {
        "commands": [
          {
            "command": "nx g @nrwl/react:component --project=core --style=@emotion/styled --export --directory=atoms/{args.group} --name={args.name}",
            "forwardAllArgs": true,
            "bgColor": "bgBlue"
          },
          {
            "command": "nx g @nrwl/react:component-story --project=core --componentPath=atoms/{args.group || 'common'}/{args.name}/{args.name}.tsx",
            "forwardAllArgs": true
          }
        ],
        "cwd": "packages/core",
        "parallel": false
      }
    },

the components is been created inside when i call this target from nx packages/core/src/atoms/undefined/button

this is the command i'm using npx nx run core:generate-atom --args="--name=button"

any idea how can we default the value of group if was not passed?

2 Answers2

1

You should use the combination of Args Interpolation by nx:run-commands and Shell Parameter Expansion, as follows:

    "generate-atom": {
      "executor": "nx:run-commands",
      "options": {
        "commands": [
          {
            "command": "nx g @nrwl/react:component --project=core --style=@emotion/styled --export --directory=atoms/{args.group} --name={args.name}",
            "forwardAllArgs": true,
            "bgColor": "bgBlue"
          },
          {
            "command": "nx g @nrwl/react:component-story --project=core --componentPath=atoms/${\"{args.group}\"/undefined/common}/{args.name}/{args.name}.tsx",
            "forwardAllArgs": true
          }
        ],
        "cwd": "packages/core",
        "parallel": false
      }
    },

In the above sample, nx:run-commands executor will replace any occurrences of /{args\.([^}]+)}/g regex with the corresponding value, passed to the command as an arg, where missing args will be treated as undefined. So, the resulting command passed to Shell would look like ${"undefined"/undefined/common}, where we use Shell Parameter Expansion to match it against "undefined" and replace it with "common".

SevanEl
  • 11
  • 2
1

TL;DR the answer:

bash -c \"nx g @nrwl/react:component-story --project=core --componentPath=atoms/$([[ {args.group} = undefined ]] && echo common || echo {args.group})/{args.name}/{args.name}.tsx 

The explanation:

Nx's run-command uses node's child_process.exec under the hood (see source code).

const childProcess = exec(commandConfig.command, {
  maxBuffer: LARGE_BUFFER,
  env: processEnv(color),
  cwd,
});

It unfortunately doesn't play nice with shell interpolation (in my experience). To give the simplest possible example, executing exec('echo $0', (error, stdout) => console.log(stdout) prints $0 instead of the shell as it's supposed to.

To work around this, I've taken to add bash -c "<your actual command here>".

The next step to setting the default value is using the ternary operator from this answer to print the wanted value:

[[ {args.group} = undefined ]] && echo <your default value> || echo {args.group}

The javascript equivalent would be:

args.group === "undefined" ? <your default value> : args.group

You can then place it in a subshell to get back the wanted value:

$([[ {args.group} = undefined ]] && echo <your default value> || echo {args.group})

And finally use its result in your command like so:

bash -c \"nx g @nrwl/react:component-story --project=core --componentPath=atoms/$([[ {args.group} = undefined ]] && echo common || echo {args.group})/{args.name}/{args.name}.tsx 

This is pretty hard to read, but I haven't found a more concise way that works.

jsouchet
  • 38
  • 5