Simple Engineering

npm

This blog post highlights key points to consider when setting up a nodejs application workflow.

In this article we will talk about:

  • Key workflow that requires automation
  • Automating workflow using npm
  • Automating workflow using gulp
  • Inter-operable workflow using npm and gulp
  • Other tools: nx
  • Auto reload(hot reload) using:nodemon, supervisor or forever

Even though this blog post was designed to offer complementary materials to those who bought my Testing nodejs Applications book, the content can help any software developer to tuneup working environment. You use this link to buy the book. Testing nodejs Applications Book Cover

Key automation opportunities

Automation opportunities are grouped around tasks that tend to be manually repeated, over the course of the development lifecycle. Some of those opportunities are, but not limited to:

  • hot reloading the server after updating some source files
  • automatically executing tests after source/test code change
  • pre-commit lint/test/cleaning hooks

To name a few. There are two major workflow automation tools that are discussed in this article, but the process will be applicable to any tool the reader wishes to pick. Those tools are, but not limited to npm, yarn, gulp — and husky for git hooks.

Hot reload can be achieved using one of the following tools: nodemon, supervisor or forever. The choice of tools does not end here, as there is always something cooking in the community. To start a server in watch mode, instead of starting the server as: node server.js, we can use instead supervisor server.js. Later in the following sections, we will see how we can move this feature from the command line to npm scripts, or even to gulp tasks runner helper.

Workflow with npm

There are various issues related to relying on npm package globally installed on one system. Some of those issues are exposed when code changes hands and runs on another platform: deployment server, CI server, or even a developer computer other than ours. The npm package version provided globally, may not be the npm package version required by the project at hand. There is no indication to tell npm to use local package A instead of globally available package B. To eliminate that ambiguity, taking preference on all modules local to the project makes sense.

How to manage globally installed devDependencies ~ StackOverflow Question. How to Solve the Global npm Module Dependency Problem

Workflow with gulp

Running this to a remote server requires installing manually a global version of gulp. Many applications, may require a different gulp version. Typical gulp installation:

$ npm install gulp -g     #provides gulp `cli` globally
$ npm install gulp --save #provides gulp locally 

Since some applications may require a different version of gulp, adding gulp in package.json as in the following example makes sure the locally sourced gulp is run.

"scripts": {
  "gulp": "./node_modules/.bin/gulp"  
}

Example: equivalent to gulp when installed globally

Use case: running mocha test with npm

This section highlights important steps to get tests up and running. Examples provided here cover single runs, as well as watch mode.

While searching for a task runner, stability ease of use, and reporting capabilities come first. Even though mocha is easy to get started, other tools such as jasmine-node/ava or jest can do a pretty good job at a testing node as well. They worth giving a try.

supertest is a testing utility wrapper of superagent. It is useful when testing endpoints of REST API in end-to-end/contract/integration test scenarios. However, when working on unit tests, for that reason there is a need to intercept HTTP requests, mocking tools such as nock HTTP mocking framework deserves a chance.

Starting with command line test runner instructions, gives a pretty good baseline and an idea of how the npm script may end-up looking like. The following example, showcases how to run tests in watch mode, while instrumenting a select set of source code files for reporting purposes:

$ ./node_modules/.bin/istanbul cover \
    --dir ./test/coverage -i 'lib/**' \
    ./node_modules/.bin/_mocha -- --reporter \
    spec  test/**/*spec.js

istanbul is a reporting tool and will be used to generate reports, as tests progress.

# in package.json at "test" - add next line
$ istanbul test mocha -- --color --reporter mocha-lcov-reporter specs
# then run the tests using 

In case that code works just fine, we can go ahead and add it in the scripts section of package.json, and that will be enough to execute the test runner command from npm

There are additional features that make this setup a little more hectic to work with. Even though mocha is the choice of this blog, jest is also a pretty good alternative to the test node too.

{
  "test": "mocha -R spec  test/**/*spec.js",
  "test:compile": "mocha -R spec --compilers js:babel/register test/**/*spec.js",
  "watch": "npm test -- --watch",
  //Adding istanbul coverage + local istanbul + local mocha 
  "test": "./node_modules/.bin/istanbul cover --dir ./test/coverage -i 'lib/**' ./node_modules/.bin/mocha -- --reporter spec  test/**/*spec.js",
  //./node_modules/.bin/istanbul cover --dir ./test/coverage -i 'lib/**' ./node_modules/.bin/mocha -- --reporter spec  test/**/*spec.js =>produces<= "No coverage information was collected, exit without writing coverage information" 
}

When using istanbul cover mocha – Error: “No coverage information was collected, exit without writing coverage information” may be displayed. To avoid this error, the use of istanbul cover _mocha can make reporting available at the end of test execution.

Once the npm scripts are in place, we can leverage the command line once again, but this time using a smaller version of the command. We have to keep in mind that, most environments have to have npm available globally.

$ npm test --coverage
$ npm run test:watch
$ npm run test:compile

Use case: running mocha test with gulp

$ npm run gulp will use scripts > gulp version. The reason for using gulp while testing, is to have a smaller package.json scripts section. The tasks have to be written in ./gulpfile.js, and requires gulp plugins to work. gulp tasks can also take on more complex custom tasks such as deployment from the local machine, codemod and other various tasks using projects that do not have a cli tool yet.

Conclusion

In this article, we revisited key points to set up a nodejs workflow. The workflow explored goes from writing code to automated tasks such as linting, testing, and release. There are additional complimentary materials in the “Testing nodejs applications” book.

References

#snippets #nodejs #workflow #npm #nx