Basics
With NodeJS, it's fairly simple to create a command-line tool. First, you need to add bin
field into package.json file.
# File: package.json
"bin": {
"command1": "path/to/command1/implementation",
"command2": "path/to/command2/implementation",
"command3": "path/to/command3/implementation"
}
You can have as many commands as you want. I like to store all the executable files in bin/
directory. Let say I want to create a command named node-greet
to simply print out a greeting message. Here's the bin
field of my package.json
"bin": {
"node-greet": "bin/greeting.js"
}
Note that the command name and the name of js file can be totally different. Now, let's create the bin/greeting.js
file to implement an overly simplified greeting function.
#!/usr/bin/env node
console.log('Hello,', process.argv[2], '!');
That's it! The only difference between this file and a normal js file is the shebang in the very first line. Now you can install this package globally and use the command anywhere in the terminal.
$ node-greet Khanh
Hello, Khanh!
or you can install it as a dependency or devDependency in other package and use the command in the scripts
field.
"scripts": {
"say-hi": "node-greet name"
},
However, things get a bit more complicated when you want to support new features of ES6, which requires --harmony
.
Harmony
Things get complicated when you need --harmony
because shebang's arguments are interpreted differently in different operating systems. In Mac OS, you can just add --harmony
to the end of the shebang above and it will work just fine. However, the same thing does not work on Linux. Fortunately, I found a solution by Olov Lassus on github. He wrote a shell script wrapper to execute js script with --harmony
option and other input arguments. You can find the solution here. I simply copy it here, break it in several lines and add some comments to make it easier to read and understand.
In the bin/
directory, add a file named node-greet
(no extension) and fill it with the following content.
#!/bin/sh
rdlkf() {
# if command is symlink
[ -L "$1" ] && \
( \
# resolve the link
local lk="$(readlink "$1")"; \
# get directory name
local d="$(dirname "$1")"; \
# go to the directory
cd "$d"; \
# recursively call rdlkf on the path
local l="$(rdlkf "$lk")"; \
# if l is absolute path
([[ "$l" = /* ]] && \
# then return l
echo "$l" || \
# otherwise, return d/l
echo "$d/$l") \
) || \
# otherwise, return the command
echo "$1";
}
# run rdlkf on the script and get the directory name
DIR="$(dirname "$(rdlkf "$0")")"
# execute the js file
/usr/bin/env node --harmony "$DIR/greeting.js" "$@"
Now, if you run bin/node-greet
, greeting.js
will be executed with harmony option.
No comments:
Post a Comment