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 --silentto suppress the displaying of the error message.