The developer can define script in the
package.json file easily:
foo script can be executed with
npm run foo command. Quite simple, huh?
But that task was relatively simple, what about some real world usage? Let’s take a look at Browserify and let’s try to tun it via Gulp & via npm scripts.
The first snippet looks a bit better, doesn’t it? What about some other tool? Let’s take a look at Webpack example.
Now it’s time for a real real-world example, a
package.json file for react-router-bootstrap library.
As can be seen in the example above, an almost complex set up is relatively easy to write, understand & maintain.
Another huge advantage of using npm as a build tool is the fact that npm supports the lifecycle scripts of the “scripts” property of package.json. You can find the complete reference in the npm docs.
Lifecycle scripts might be used to automate
post- task scripts.
As can be seen in the examples above, lifeback scripts might be a real powerful tool to automate any
Every single good automation system should be as simple as possible. Configuration should be easy to understand and even easier to maintain. As maintaining shell commands might be relatively hard for a non-geeky person, it’s important to create simple scripts that can be executed subsequently or “merged” runtime.
Let’s take a look at the example of bad practices:
Why do I consider the example above a bad practice? It doesn’t allow the developer to execute the command separately (in this example a separate script will be required to run
karma separately). It’s also hard to read and maintain.
Now, the second version of the same package.json file:
I think the second version is way better, as it gives the developer possibility to run every single command separately. Additionally, it follows the single responsibility principle, as every single task is responsible only for running single tool according to it’s name. On the other hand, the
test scripts runs all test-related scripts.
Using npm scripts as a build tool is a fantastic approach, however, there are few drawbacks that need to be mentioned:
- less extensible code – while keeping scripts clean & easy to maintain, they become less extensible
- multi-platform compatibility – one does not simply use
- lack of CLI – some tools don’t provide any CLI.
I don’t want to negate the point of build tools. The idea of this blog post is to show an alternative approach which might be a better solution for common problems. As a build tool already depends on a CLI library, why introduce an extra layer? Why not try to drop all intermediate dependencies and communicate with a tool directly via CLI?
I recently switched to npm scripts in my every single personal project & to be honest I’m not even thinking about switching back to Gulp or Grunt anymore.