node.js and the beauty of working on a platform that embraces opensource

In this article I will show one of the most beautiful things of working with node.js and how noders do open source in the right way.

I have been working full time in a project using node.js for Tellago Studios, I have read a lot of posts about node.js being cancer, why node.js sucks, why ruby is better, why javascripts callbacks for async workflows are complex and so on, and even if I agree with some things at some point there are things in node.js done right, things to applaud and things to learn from it. This article is about something to applaud.

tl;dr

When working with node.js you can swap a dependency or a sub-dependency with a link to your fork-branch in a git repository. Make sure you understand the [1] algorithm for loading modules and [2] npm install

A bug story

Lets say you are working on your project and you are using a third party opensource module named Foo, your package.json will looks like:


{
  "name": "myproject",
  "version": "0.0.1",
  "dependencies": {
    "foo" : "*"
  },
}

The star * here means any version.

If you look at the your project folder you will see a tree like this:


myproject/
  server.js
  package.json
  node_modules/
    foo/
      package.json
      node_modules/
        bar/
          package.json
          node_modules/
            another/

Now suppose that you find a bug, you fire up [3] node-inspector and you start digging in your modules, then you figure out that the problem is in the module "bar".

Now, the flow will be something like this:

  1. Clone the module Bar (which of course is opensource of course as the bast majority of node.js modules) in another folder. If you don't know where the Bar module repository is hosted, don't worry, look at its package.json the url will be there for sure.
  2. Fix the issue and try things as crazy. Write tests!
  3. Commit, revert, commit, branch blah
  4. Push to your fork of the project
  5. Do a pull request to the project owner[s]

So far these are the standards steps you will take in any platform, even in .net. Because node.js developers take so serious this opensource business it is very likely that your pull request will be at least reviewed or discussed the same day.

But what if not?

You still have a bug to solve in your project, and no one in your team or company want to wait for you or other people to:

  1. merge your fix
  2. publish to npm a fix of Bar
  3. publish a new version of Foo pointing to the fixed Bar.

Node community understand open source

As crazy as it might sound, we can easily do this in OUR package.json:


{
  "name": "myproject",
  "version": "0.0.1",
  "dependencies": {
    "bar": "git://github.com/youruser/bar.git#my-branch-to-the-ugly-bug"
    "foo" : "*"
  },
}

run npm install and you are done. Your project and most important, your local instance of the package Foo is using the your fork of Bar. Your team will be able to work with and everyone will be happy. We can even omit the pull request if we find that is something useful only in our project or something that should not be on the main repository.

We can also release our project as opensource and no one is going to be affected.

Whats the price for a feature like this in a programming language / platform?

How does it works?

There are few things that make this possible.

The first thing is the ability of npm to install things from a git repository as explained in [2] npm install the package could be:

a) a folder containing a program described by a package.json file
b) a gzipped tarball containing (a)
c) a url that resolves to (b)
d) a <name>@<version> that is published on the registry with (c)
e) a <name>@<tag> that points to (d)
f) a <name> that has a "latest" tag satisfying (e)
g) a <git remote url> that resolves to (b)

The second things is how the module system (i.e. the require function) works as explained in [1] Node.js: Modules - All together , specifically this part:

NODE_MODULES_PATHS(START)
1. let PARTS = path split(START)
2. let ROOT = index of first instance of "node_modules" in PARTS, or 0
3. let I = count of PARTS - 1
4. let DIRS = []
5. while I > ROOT,
   a. if PARTS[I] = "node_modules" CONTINUE
   c. DIR = path join(PARTS[0 .. I] + "node_modules")
   b. DIRS = DIRS + DIR
   c. let I = I - 1
6. return DIRS

It means that when trying to solve the module Bar from Foo, this thing will start with a path like this:

node_modules/foo/node_modules

and as is explained there, first it will look for Bar in the first node_modules folder.

And last but not least is the fact that the node.js community understand how opensource works. All modules in node.js are opensource, and almost all modules in node are in git and in github. It is easy to understand modules because all modules have almost the same file structure package.json, lib/bin folders, etc. This means there is a way to do it and most people is following that way.

I have the pleasure to assist to jsConf in Argentina and listen to [4] Isaac Z. Schlueter current curator of node.js and creator of npm and it is not surprising that the technical thing explained here is in the same line that the principles he encourage. Unfortunately the talk is not online (yet? saw it was being recorded) neither his slides but I found slides from another very similar talk [5] TacoConf Anarchism


blog comments powered by Disqus
  • Categories

  • Archives