Running bash scripts with npm
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/"
},
}
...
Related videos on Youtube
Comments
-
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 mypackage.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 thebuild.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 over 8 yearsDon'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
? installmkdirp
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 likegrunt
orgulp
. Keep it universal. -
Mark McKelvy over 8 yearsWhen you say "even CLI invocation can be done using package dependencies" are you talking about something like this?
-
Mike 'Pomax' Kamermans over 8 yearsclose but no, read the slides I linked to. You can install node modules that come with CLI tools, like
grunt
, orgulp
, ormkdirp
, 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 over 6 yearsThe 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 over 4 yearsWhy 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 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 about 4 yearsYes, 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
, andshx
, andcross-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 about 3 yearsThere 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 over 8 yearsWhere would the bash file go? Does it need to be in the node_modules
bin
directory? -
eblahm over 8 yearsyou 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 almost 8 yearswhat is up with the . in front? Why isn't it just "build": "./build.sh" ?
-
eblahm almost 8 yearsit runs the script in the current shell superuser.com/questions/46139/what-does-source-do
-
Lajos Mészáros about 7 yearsWhat about windows?
-
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 about 7 yearsOn 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 over 6 years@LajosMeszaros If you want to use windows Power Shell, then you can set this up like this:
"build": ".\\build.sh"
-
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 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 over 6 yearsI'm using cygwin terminal And using "build":"sh ../../path/to/build.sh" works
-
Rashomon over 5 yearsIn windows bash following npm script worked for me:
"name": "bash ./name.sh"