Intro to SHX
One of my personal goals with NPM package development is to get better at cross-OS support; I don’t want to distribute code that only works in one specific environment. As part of my effort in working towards this, I discovered the shx
CLI package, which is really mostly a wrapper around shelljs. Both of these tools let you write commands that use standard unix
built-ins, like cat
, but will work across any OS (Win / Mac / Linux).
For example, shx cat index.js
Using SHX to Delete Files Based on a Pattern
Problem:
If you are used to writing your commands without concern for portability, you might write a command to delete files based on a pattern like this:
# Delete all .md files in /dist
find dist -name '*.md' -delete
However, this command will fail with shx
:
shx find dist -name '*.md' -delete
# ERROR: find: no such file or directory: -name
This is because the arguments to find
are not currently supported by shx
– you can find this tracked as issue #177.
Solution:
Since shx
supports automatic glob expansion to standard commands, there is no reason why you can’t write the delete command as this:
shx rm 'dist/**/*.md'
Best Solution
There is a secondary problem here, which exists with many commands, which is that the command might exit with a non-zero code, preventing chained commands (ala &&
) from running. This is especially problematic for NPM packages and the scripts
section.
For example, if our package.json
has this:
{
"scripts": {
"clean": "shx rm 'dist/**/*.md' && yarn build"
}
}
… and there are no .md
files inside dist
, then the first part of the clean
command will exit with:
error Command failed with exit code 1
… and yarn build
will not execute.
There is any easy workaround though! Just use the &
instead of the &&
operator, which lets the second command execute regardless of the success of the first.
You can also force the command to return exit 0
, by piping and then returning true:
{
"scripts": {
"clean": "shx rm 'dist/**/*.md' || shx true && yarn build"
}
}
Tip: You can also use
shx --silent
to suppress the displaying of the error message.