re: Why I struggle with Node VIEW POST


Some ideas that made my life easier:

Mocking modules:

Build system: Use webpack, bash, npm scripts. Its more difficult under Windows, I know. But Grunt and Gulp have been so awful for me, that even installing bash under cygwin manually is better. Most npm scripts will work okay under windows too.

Compiler / Static checks: Swap Babel with TypeScript.

Code coverage with mocha and TypeScript:

tsc && 
  istanbul cover -x 'tests/**/*.js' --report none _mocha -- 'tests/**/*.js' && 
  remap-istanbul -i coverage/coverage.json -o coverage/html -t html

The key here is remap-istanbul, which will give you more useful results when you have a compile-to-JS step. Make sure that sourceMap is true for typescript's configuration though.


Mocking modules can be done in a number of ways, but almost all of them seem to work on the require calls. Using ES6 means that you use import statements instead - which Babel rewrites to require, but outside of your control. There is a module I found - babel-rewire-plugin - which allows you to replace variables - including imports - inside a module, but even that just feels clunky. Coming from a Java world, what I feel like I want is a Dependency Injection setup, where I inject modules into each other, rather than pulling them in using require. However, I know that this isn't the standard Node way of doing things, and I'd rather do things the "correct" way than try to reproduce the way I work in a different language just because it's what I know.

The Node Build Systems I've never had much problem with. It can be a pain getting Grunt or Gulp to do exactly what I want it to, and some of the modules have problems, but in general I can cope there.

Typescript I've not yet used. I've used Flow, and kept running into problems where even though I had typing information on all of my code I didn't have it on the libraries I depended on, which just made it clunky.


Regarding DI, node modules are already basically a service locator, so you don't really need it. Definitely not for testing anyway.

Proxyquire does need some ES6/babel/typescript love, I agree, but its just a matter of looking at the compilation output of babel and setting up the mocks accordingly. Would be nice if there was direct support for it. Sounds like a good pull request or module :)

TS largely solves the 3rd party library problem of flow. The number of available type definitions is quite impressive:

I second the recommendation for VSCode. Don't know if it solves all your debugging troubles though. A lot of the problems with mocha come from it not playing well with other tools unless you use the _mocha binary, since mocha itself likes to start _mocha as a subprocess IIRC

The DI needs are a lot more than just Service Locator though. It is all about abstracting away the wiring of your modules. It means that you can change the service that a module depends on simply by changing the wiring, and not changing the module itself. And that instantly means that the modules have to depend on the API of the service, not the implementation.

Regarding Proxyquire or similar, that would work but it means doing the imports in the middle of your tests - which is, of course, how Node does these things. That goes against the idea from ES6 that imports are done before any code, and simply set up the scene for your code to work.

code of conduct - report abuse