Running bash scripts with npm

126,540

Solution 1

Its totally possible...

"scripts": {
   "build": "./build.sh"
},

also, make sure you put a hash bang at the top of your bash file #!/usr/bin/env bash

also make sure you have permissions to execute the file

chmod +x ./build.sh

Finally, the command to run build in npm would be

npm run build

Solution 2

If you don't want to bother with giving permissions and the env you execute the script has for example sh, you could just do

"scripts": {
   "build": "sh ./build.sh"
}

Solution 3

Even Simpler:

I routinely do this for one-offs and PoC's not involving a VCS

package.json
{
    "scripts": {
        "ship": "rsync -avz deployable/* <some-server>:/var/www/some-site/sub-dir/"
    },
}
...
Share:
126,540

Related videos on Youtube

Mark McKelvy
Author by

Mark McKelvy

JavaScript / React / Node.js / Postgres.

Updated on March 13, 2021

Comments

  • Mark McKelvy
    Mark McKelvy about 3 years

    I want to try using npm to run my various build tasks for a web application. I know I can do this by adding a scripts field to my package.json like so:

    "scripts": {
       "build": "some build command"
    },
    

    This gets unwieldy when you have more complex commands with a bunch of options. Is it possible to move these commands to a bash script or something along those lines? Something like:

    "scripts": {
       "build": "build.sh"
    },
    

    where npm run build would execute the commands in the build.sh file?

    Reading through this post it seems like it is, but I'm not clear on exactly where I'm supposed to drop my build.sh file or if I'm missing something.

    • Mike 'Pomax' Kamermans
      Mike 'Pomax' Kamermans over 8 years
      Don't do this. Node runs everywhere. Bash does not. Whatever you're doing in bash you can do in node, and even CLI invocation can be done using package dependencies. Need rm? install rimraf, then use that in an npm script. mkdir -p? install mkdirp and then use that in an npm script. You have a platform independent universal scripting language, right there, don't then go and pretend it 'Nix only. Does the commandline get too complicated? Use a task runner like grunt or gulp. Keep it universal.
    • Mark McKelvy
      Mark McKelvy over 8 years
      When you say "even CLI invocation can be done using package dependencies" are you talking about something like this?
    • Mike 'Pomax' Kamermans
      Mike 'Pomax' Kamermans over 8 years
      close but no, read the slides I linked to. You can install node modules that come with CLI tools, like grunt, or gulp, or mkdirp, etc, without needing people to have them globally installed, and then invoke them as if they're globally installed in an npm script, like "build": "mkdirp build && less style/index.less > static/css/style.css && webpack". As long as the commands you invoke are npm-managed (i.e. in the package.json dependency listings), this just works. For any "this only works for one OS" command, use a node module that does the same thing universally.
    • Forbesmyester
      Forbesmyester over 6 years
      The comments above say no, for a good reason, portability. But it depends on your audience. If it's an internal project, if your developers are on UNIX like variants (Linux/Macs etc) it is perfectly fine. If you're creating a general purpose library it is probably not... There is distinct benefits to using BASH/SH, you will be able to achieve some things in one line that will need pages of Grunt/Gulp, but then, you're probably excluding Windows users, which may, or may not be a problem.
    • Chris Wood
      Chris Wood over 4 years
      Why is rimraf better than rm -rf for a web application? rimraf has to do things one file at a time, and just more packages you don't need. If a web server doesn't have bash then you can use del, but it likely has bash if the user is developing with node anyway and not .net or something. Even if it is .net it still probably has some form of gitbash or something.
    • skalee
      skalee about 4 years
      @Mike'Pomax'Kamermans The reasoning that every Node application must be portable just because Node is is simply incorrect.
    • Mike 'Pomax' Kamermans
      Mike 'Pomax' Kamermans about 4 years
      Yes, it is, but then I didn't say that. If your Node application can only ever work on a specific OS due to native bindings etc, then that's what it is. But there is no reason to not use the universal equivalents of unix tools when your code is not intrinsically linked to an OS. If your code itself is universal, then use rimraf, and shx, and cross-env, and etc. because they're just as easy, but don't tie your codebase to one OS for no good reason at all.
    • Steve Bennett
      Steve Bennett about 3 years
      There are lots of reasons to use familiar tools rather than invest time and energy meeting a portability requirement which doesn't necessarily exist in the given project.
  • Mark McKelvy
    Mark McKelvy over 8 years
    Where would the bash file go? Does it need to be in the node_modules bin directory?
  • eblahm
    eblahm over 8 years
    you can put it wherever you want just make sure you put the relative path in package.json eg "build": ". ./path/to/my/awesome/build/file/build.sh"
  • Alexander Mills
    Alexander Mills almost 8 years
    what is up with the . in front? Why isn't it just "build": "./build.sh" ?
  • eblahm
    eblahm almost 8 years
    it runs the script in the current shell superuser.com/questions/46139/what-does-source-do
  • Lajos Mészáros
    Lajos Mészáros about 7 years
    What about windows?
  • ToastedSoul
    ToastedSoul about 7 years
    @LajosMeszaros: In windows, I did not get bash scripts to run, but using cmd files works for me: "build-deploy": "build-deploy.cmd"
  • cjsimon
    cjsimon about 7 years
    On Windows gitbash: '.' is not recognized as an internal or external command, operable program or batch file. See here for details explaining why. Additionally, setting sh files to be opened up with gitbash by default or any other environment that can run bash scripts will get this to work.
  • Steven Stark
    Steven Stark over 6 years
    @LajosMeszaros If you want to use windows Power Shell, then you can set this up like this: "build": ".\\build.sh"
  • mtpultz
    mtpultz over 6 years
    @StevenStark doing .\\build.sh opens the file in my default editor using VSCode terminal (GitBash). Is there another way to run this on Windows?
  • Steven Stark
    Steven Stark over 6 years
    @mtpultz Yes, I am finding that this actually doesn't work in all cases. In my case, I have Git Bash installed and it opens with that. But your mileage may vary here, and I do not yet have a better solution.
  • Ashitakalax
    Ashitakalax over 6 years
    I'm using cygwin terminal And using "build":"sh ../../path/to/build.sh" works
  • Rashomon
    Rashomon over 5 years
    In windows bash following npm script worked for me: "name": "bash ./name.sh"