Wednesday, November 26, 2014

npm link with interdependent modules

Sometimes you need to develop on multiple interdependent node modules at the same time. When developing on a dependent module, in order to test your changes, you can do one of several things:
  1. Publish your module and run npm update
  2. Copy and paste code into your node_modules folder
  3. Use npm link to use the in progress version of your module in your other applications
Out of any of the above options only 3 really scales and doesn't leave much potential for errors. Before going any further let's review what npm link does.

Let's say you have 2 modules:
  • dependent-module
  • master-module
master-module also has a dependency on dependent-module. Running npm link inside the dependent-module directory will create a symlink from that directory to the global node_modules/dependent-module directory. Then when running npm link dependent-module in the master-module directory will add dependent-module as a symlink inside the local node_modules directory. This allows you to make changes to dependent-module and instantly have them available inside master-module.

This works great until you have a module that is used in both of your modules that also has global state. A good example is mongoose, the excellent mongodb odm. Schemas and models are defined on the global mongoose object. If each of your modules has mongoose installed, they will have 2 different mongoose objects. So if your models are defined in one module, those models won't be available in your other module. Normally this behavior doesn't happen because npm is smart enough not to install module dependencies if they have already been installed, but when using npm link this won't be the case.

In order to avoid this problem, you will need to run npm link on any susceptible modules. So in our above example if both modules need mongoose, you will need to run npm link mongoose in each affected module directory.

Something to also keep in mind is that running npm update will destroy the symlinks, meaning you need to run npm link dependent-module and npm link mongoose after your run npm update.

Friday, August 29, 2014

AngularJS custom scrollbar directive

On a recent project I needed to create a widget that had a similar look and feel across multiple platforms. This widget had a limited size and needed scrolling. When developing on my Macbook the scrollbars were working fine and everything seemed ok. As soon as we started testing it in Windows, the scrollbar width caused an issue with the rendering pushing all the content down.

The solution that we decided on was to use a custom scrollbar. After scouring the web for custom scrollbars in JavaScript I found TinyScrollbar. I liked it because it didn't use jQuery as we were using AngularJS and didn't want to bog down our app with jQuery. I decided to tweak it and port it to AngularJS as a directive.

It's available on github and via bower (bower install ng-tiny-scrollbar) and a demo can be seen here.

Wednesday, July 9, 2014

npm install ENOENT errors

I've been working on a project that is built using NodeJS. Our development environment is a bit of a hybrid. Most of the developers are developing on Macs, with one exception. Our build server is on Windows and our site is running in Windows Azure. For the most part developing NodeJS on a Mac is quite straightforward. All the tooling is readily available and tends to work quite well. Not so much on Windows. So when our build server starting to run into issues installing the requestify package, we chalked it up to something not liking Windows.

We were getting ENOENT errors where npm was complaining that it couldn't find files that it was supposed to download on the file system. Since the error was happening installing a dependency of a dependency, we thought maybe it was a long paths issue. However, we couldn't even get it to install running in the root directory. We decided to use a work around to switch to a different version of that particular dependency.

Weeks later I ran into the same issue, but this time on my Mac. I found a solution by running npm cache clean before running npm install again. I tried it on the Windows build server and it started working again.

TL;DR;
If you're seeing ENOENT errors when running npm install try running npm cache clean and try again.