3

Is it possible to pass an argument to the npm command string? The info might be somewhere in docs, but brief digging didn't get me any results, moreover, it is probably beneficial to the large audience.

For example, i have a command build:docker in package.json:

   "scripts": {
      "build:docker": "tsc -b && sh dist.sh && docker build -t repo_name/image .",
   },

I want to pass the tag variable to the command string, ex:

"build:docker": "tsc -b && sh dist.sh && docker build -t repo_name/image:$tag ."

and run it as npm run build:docker --tag '1.0'.

Is something like this possible? Thanks!

user1935987
  • 3,136
  • 9
  • 56
  • 108
  • 1
    Use a shell function. For example redefine your npm script as: `"build:docker": "func() { tsc -b && sh dist.sh && docker build -t \"repo_name/image:${1}\" .; }; func"` - then run `npm run build:docker -- "1.0"` – RobC Feb 12 '21 at 17:08
  • Given that you want to pass `"1.0"` to the npm script, should the last part of your npm script example form: `... && docker build -t repo_name/image:1.0 ."` ? Presumable the `$tag` in your example is a placeholder for where `1.0` should go, or did I misunderstand? – RobC Feb 12 '21 at 17:27
  • yeah, thats right – user1935987 Feb 12 '21 at 17:37
  • So, have you tried what I suggested in my first comment? – RobC Feb 12 '21 at 17:37
  • yes, testing it now. seems like the param was passed correctly, however for some reasons the whole image is re-assembling. but the resulting `repo_name/image:1.0` was correct by logs - weird why is it re-building. – user1935987 Feb 12 '21 at 17:38
  • If you change your npm script to `"build:docker": "tsc -b && sh dist.sh && docker build -t repo_name/image:1.0 ."` _(i.e. the intended resultant compound command)_ and then run just `npm run build:docker` _(i.e. without arg `1.0` being passed)_ - does that also result in the whole image being re-assembled? ` – RobC Feb 12 '21 at 17:46
  • now not -it's already been re-built. now pushing it to hub to ensure. idk why was it re-built - repo, image, tag were unchanged. in any case maybe u want to write your comment as an answer? it seems to be a valid hack to achieve the result – user1935987 Feb 12 '21 at 17:51
  • For further explanation as to why the shell function (i.e. `func() { ...; }; func`) and the positional parameter `$1` is necessary refer to my answer [here](https://stackoverflow.com/questions/51388921/pass-command-line-args-to-npm-scripts-in-package-json/51401577#51401577). – RobC Feb 12 '21 at 17:51
  • right, it does, somehow didn't find that answer during the initial search. should i delete this question or just vote to close? – user1935987 Feb 12 '21 at 17:54
  • there is some strange behaviour - now when i try to change tag, or even build `repo_name/image` without the tag again, the image being re-built. maybe using the bash script sets separate context for script and somehow produces this effect? – user1935987 Feb 12 '21 at 18:12
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/228645/discussion-between-user1935987-and-robc). – user1935987 Feb 12 '21 at 18:13

1 Answers1

2

Yes, you can: For example (for simplicity), for the line:

"build": "tsc --project "

You can start it like so:

npm run build ./src

This will start:

> tsc --project  "./src"

And another solution (I didn't see the point without glasses :) ), more suitable for you is to prefix the name of the parameter with $npm_config_, so your line should look like this:

"build:docker": "tsc -b && sh dist.sh && docker build -t repo_name/image:$npm_config_mytag ."

And then run it as:

npm run build:docker --mytag=1.0

Watch out for =

Boris Kukec
  • 611
  • 3
  • 8
  • 1
    this will pass arguments as `string` and add them strictrly at the last position. in the sample command `tag` argument is not at the last position. – user1935987 Feb 12 '21 at 17:13
  • I have added the 2nd possibility, which is more suitable. – Boris Kukec Feb 12 '21 at 21:25
  • 2
    npm creates its own environment variable named `npm_config_tag` for internal purposes. It's value is typically set to `latest`. So, just be aware that you are overriding this internal env var with a new custom value (i.e. `1.0`) - so this has potential to produce unwanted results. If you `cd` to a project directory that contains a _package.json_, then run `npm run env` it will print many of the `npm_` prefixed variables that npm adds to the environment. You should find that `npm_config_tag=latest` already exists. – RobC Feb 13 '21 at 20:24
  • Thanks, @RobC you are right. – Boris Kukec Feb 14 '21 at 14:07