How to automate development tasks using NPX

"Give me six hours to chop down a tree and I will spend the first four sharpening the axe." - Abraham Lincoln

6 mins

When I look at what I do as a developer, most of the things are repeated actions that I don’t automate because “this is the last time I need to do this”. Editing a file, restarting some server, switching to the browser, refreshing and navigating it. Then I make another small change and do the same process again.

There is a bias I see throughout my work. It goes like this: I feel that the task is almost finished, so I don’t automate. But then it is not, and I find myself working on the same task an hour and 20 refreshes later. If I look back what I did in that hour, I mostly wasted time on things I could automate in 5 minutes.

To battle this, the best thing is to make these automations as easy as possible. Did you know that in economics there is an enormous difference between ridiculously cheap and free? The same applies to scripts. The difference between creating a package.json and add some scripts versus a one-liner that can be copy-pasted can not be overestimated.

In this mindset, I learned about NPX, the NPM package runner. This is the perfect tool for one-liners as you get the full ecosystem of the CLI tools in the NPM repository but you don’t need to install anything. Just learn some of the most helpful tools and you will be able to automate the mundane work when you start working on a task.

Usage

NPX can replace globally installed packages. Instead of the usual route of doing an npm i -g package then use the package, you can achieve the same with npx package.

There are a few configurations NPX supports. When you need multiple packages installed specify them with -p <package>. In this case, you need to define the package to run separately:

npx -p package1 -p package2 package-to-run

For example, webpack-cli requires webpack to run but it is a peer dependency, so you need to install both:

npx -p webpack -p webpack-cli webpack-cli

The default case of npx package translates to:

npx -p package package

If you need to run a specific version of a package, define it with package@version.

The downside of using NPX is that it runs an install every time which takes a few seconds. In cases when you need it to run as fast as possible, this can be a problem.

Recipes

Let’s see a few use-cases for NPX! And contrary to all other articles about NPX, this list won’t include cowsay.

Autorun

I find nodemon to be an indispensable tool in my toolkit. It watches files and whenever they change it runs a command. Simple, and I’m sure there are million other ones, but with NPX nodemon can be run as a one-liner and it just works.

To run the project every time a source file is changed, use:

npx nodemon --watch src/ --exec "npm run"

One source of problems is that it watches only js files. To specify other extensions, use the -e <extensions> argument. For a React+TS project, you’d want -e ts,tsx.

Livereload

Another gem that supercharges the development workflow:

npx livereload . -d

No more alt-tab, ctrl-r. By the time you get there, the browser is already refreshed.

Note that you need a browser extension installed and activated.

Obfuscation

JS obfuscation can not be easier than this:

npx javascript-obfuscator main.js -o main.obf.js

It runs the code through javascript-obfuscator, the only open-source project I know about that provides robust obfuscation.

Compile Typescript

Use all the goodness of Typescript and compile it back to traditional Javascript:

npx typescript main.ts --out main.js

Webpack compile

While it is better to have a package.json and have scripts that run Webpack, it is nevertheless possible to run it without all that:

npx -p webpack -p webpack-cli webpack-cli main.js

HTTP server

Serve the current directory as a web server:

npx http-server

Do you also have an API along with your static assets? Specify another URL that will be used for everything but the local files:

npx http-server --proxy http://api

In case you need HTTPS, generate a self-signed certificate and specify that:

npx devcert-cli generate localhost && http-server -S -C localhost.cert -K localhost.key

Minify Javascript

To run your code through a minifier:

npx terser file.js > file.min.js

Check for new versions

How to know if a dependency has a new version? Run this:

npx npm-check-updates

Parallel commands

To run two things in parallel, use the concurrently package:

npx concurrently "<command1>" "<command2>"

You can easily run http-server and livereload together with this:

npx concurrently "npx livereload . -d" "npx http-server"

Pretty print Javascript

To have a minified script printed out in a more readable format, use the js-beautify project:

npx js-beautify main.js

Highlight Javascript for the console

Syntax highlighting can also easy readability:

npx cli-highlight

You can also combine the above two:

npx js-beautify main.js | npx cli-highlight

Compile SCSS

Easily compile SCSS into CSS:

npx node-sass custom.scss

Linting

Run eslint with the default configuration:

npx eslint main.js

Formatting

Easily format your code without installing anything with prettier:

npx prettier main.js

Or with standard:

npx standard --fix

Tunnel

To show your work to someone, tunnel a local port through the internet with localtunnel:

npx localtunnel --port 8080

By combining it with http-server you can showcase a local project without installing anything:

npx concurrently "npx localtunnel --port 8080" "http-server"

Combinations

When you need to code short functions, setting up a full-fledged package.json and all the dependencies and scripts just to use a better technology usually does not pay off. But with the above simple one-liners, you can easily compose useful short scripts.

Have you ever wanted to use Typescript for Lambda?

To continually compile and exec your code, you can use this script:

npx nodemon --watch main.ts --exec "npx --quiet typescript main.ts && node main.js"

And when you are ready to deploy, compile and minify with this script:

npx typescript main.ts --out >(npx terser > res.js)

Conclusion

I’ve been using NPX packages for quite a while, and I see enormous benefits. With just a few tools I can automate most of the non-creative work I do. That leaves me with more time to do my job.

12 March 2019