Task runners significantly simplified the life of web developers by automating the routine actions associated with running tests, checking code, merging into one file, transpiling, and other equally useful things. Omitting the question of the need for such tools, of course, is possible without them, but they greatly simplify life and make the development process more qualitative.
Everyone uses the task runners in one way or another: someone with an old grant , someone gradually leaving the arena galp and many others , while others already use npm-scripts .
The latter we will analyze today in detail, as well as ways to accelerate and expand their capabilities.
Written below is a subjective experience, and does not pretend to the truth of the last instance, however, it is an important reason for the further narration .
As the above listed runners appeared, they were tried by me in battle, and in each of them (of course) there are pluses and minuses. Consider them briefly.
The grant has a low entry threshold, due to the configs, which at the same time are its cornerstone, forcing them to generate them programmatically, due to the large number of transmitted fields. Gulp solves this problem entirely, adding minimalism and speed of execution, thanks to streams , which raises the threshold of entry, requiring users to understand how everything works from the inside.
And so, moving away from the grant, sorting out the streams and writing a concise Gulpfile, I calmed down and continued to develop the current project. For the next application, I, of course, wrote Gulpfile again. And for the following. And for many others .
After that, the gulp itself, and its plug-ins began to be updated, and then its dependencies, which happened to have to be updated independently . Of course, you can not use services that monitor package updates , fix vulnerabilities, fix bugs, and all the rest, but this is not the best approach to development.
Thus, we come to the main drawback of most of the tax runners: they need to be updated, their dependencies need to be updated and the dependency dependencies too. For monolithic applications, this is not a problem. Problems begin when there are many parts of the application, and each of them is an independent module, but is this not the main development paradigm of node.js?
So, instead of updating: gulp, gulp-jshint and jshint, I'd rather just use jshint directly, using the command line interface that doesn’t change often, making life much easier for myself.
Of course, this approach has its drawbacks, where do without them? If you randomly shove everything in the scripts
section of the package.json
file, very soon the devil’s leg will break. Therefore, you should use short commands clearly reflecting their behavior in the title.
When I started actively using npm-scripts, I, like many developers, realized the inconvenience and verbosity of this approach, for example, if you need to organize a check with linders, the code will look like this:
{ "lint:jshint": "jshint lib test", "lint:eslint": "eslint lib test", "lint:jscs": "jscs lib test" }
Then the script that runs all the checks will look like this:
{ "lint": "npm run lint:jshint && npm run lint:eslint && npm run lint:jscs" }
Very much verbose, and here only 3 scripts are launched.
There are many libraries that simplify interaction with npm scripts. We will look at one main one, which combines the functionality of all existing solutions, and at the same time, does not depart from the main paradigm: running scripts using npm
.
The previous example turned out to be very verbose (much shorter than in the case of a grant and a galp, but not so much) and difficult to read. npm-run-all greatly simplifies everything. With it, the code that does the same will look like this:
{ "lint": "npm-run-all lint:jshint lint:eslint lint:jscs" }
( npm-run-all
can be easily replaced with a shorter name: run-s
, extreme npm-run-all
versions support this)
And do about the same thing: run scripts in turn.
npm-run-all
is not very bad in terms of convenience, but by the principle of operation it doesn’t go a npm run
from the npm run
: each command is called separately, which significantly slows down the whole process.
I used npm-run-all
for a long time, but at some point I realized that running scripts could be more optimal, faster and still have a simple implementation. The first results showed themselves very well in terms of speed and efficiency, while not losing in convenience.
The principle of operation of redrun is significantly different from analogs: instead of launching each command separately, it combines all nested commands into one big one, and already sends it to the system shell for execution. Due to this optimization, the execution speed of npm-
increases significantly, while it remains possible to run scripts in parallel and in series. An example with the lint
script, after parsing will look like this:
jshint lib test && jscs lib test && eslint lib test
In addition to the ability to run scripts sequentially, in parallel, as well as in mixed mode, redrun parses all script entries starting with npm run
, as well as npm test
(including prefix and postfix scripts), leaves the possibility of using the configuration section in package.json , and even parsit all occurrences of redrun
, which can run scripts, which makes it a unique tool for writing concise and understandable scripts, because ultimately everything will turn into one big team. It is also worth noting that most of the functionality is compatible with the above npm-run-all
, as well as npm
(the part that relates directly to running scripts).
Consider an example of using redrun
. To start the installation (nothing special):
$ npm i redrun -g
Next we create package.json
using npm init -y
:
$ mkdir example $ cd example $ npm init -y Wrote to /home/coderaiser/example/package.json: { "name": "example", "version": "1.0.0", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "keywords": [], "author": "coderaiser" "license": "MIT", "description": "" }
Install a tape
for tests, and write down the simplest test that passes.
$ npm i tape -D $ cat > test.js 'use strict'; const test = require('tape'); test('some test', (t) => { t.pass(); t.end(); }); ^C
Now, add several sections to the scripts
section of the package.json
file:
{ "test": "tape test.js", "watch:test": "npm run watcher -- npm test", "watcher": "nodemon -w test -w lib --exec" }
Then run the test using npm
:
$ time npm test reel 0m6.617s user 0m1.262s sys 0m1.778s
And now the same thing, only with the help of redrun
:
$ time redrun test real 0m2.389s user 0m0.495s sys 0m0.544s
Even on such a simple example, it can be seen that the execution speed is almost 3 times higher.
Now let's try the same with the npm watch:test
script npm watch:test
:
$ time redrun watch:test > nodemon -w test -w lib --exec tape test.js /bin/sh: 1: nodemon: not found Command failed: nodemon -w test -w lib --exec tape test.js real 0m1.211s user 0m0.208s sys 0m0.332s
Yeah, we didn't install nodemon
, and it took us only 1 second to find out. I want to draw the attention of the reader to the fact that the team has fully deployed, and nodemon
(after installation) will restart the tape
directly, and not the npm test
.
Let's try the same thing with npm
:
$ time npm run watch:test > article@1.0.0 watch:test /home/coderaiser/article > npm run watcher -- npm test > article@1.0.0 watcher /home/coderaiser/article > nodemon -w test -w lib --exec "npm" "test" sh: 1: nodemon: not found npm ERR! syscall spawn npm ERR! spawn ENOENT npm ERR! article@1.0.0 watch:test: `npm run watcher -- npm test` npm ERR! Exit status 1 real 0m11.594s user 0m2.181s sys 0m2.849s
Using npm
it took us 11 seconds to find out that nodemon
not installed.
Install nodemon
:
$ npm i nodemon -D
Let's try again:
$ redrun watch:test > nodemon -w test -w lib --exec tape test.js [nodemon] 1.10.2 [nodemon] to restart at any time, enter `rs` [nodemon] watching: test lib [nodemon] starting `tape test.js` TAP version 13 # some test ok 1 (unnamed assert) 1..1 # tests 1 # pass 1 # ok [nodemon] clean exit - waiting for changes before restart
Now everything works: an observer is started, which looks for changes in the test
and lib
folders and restarts tape test.js
- exactly what we need. At the same time, it remains possible to use the compact script syntax in package.json.
Redrun
is written on TDD , so to make changes: adding features or fixing bugs is very simple. If the reader notices an obvious and undocumented discrepancy in the work of redrun
compared to similar tools: create ishju, send a pool of requests - we will correct it.
npm
good tool that regularly performs what it is intended for. The node.js
ecosystem is evolving very rapidly, and not the last place in this process is played by npm
(and one of the first). I think a moment will come when redrun
will not be needed because npm
will do everything quickly. But so far this moment has not come, and in order to bring it closer, the npm
assistant has been created in such a difficult but important matter as running scripts.
Source: https://habr.com/ru/post/308930/
All Articles