Managing Node.js projects for pythonists


Different languages, different toolsets. Classic. Nonetheless, if you look carefully, many tools available for language X are also available for language Y. This article will draft the similarities between the (core) Node.js toolset and their equivalent in Python.

Installation

Node.js should be installed using NVM. It is the preferred way because it allows all the packages and binaries to be available to the current user instead of being installed system-wide.

quick tip: The installation process of NVM does not automatically install Node.js. Follow this gist or the README in the NVM repository to complete the installation process.

Binaries

pip

pip handles packages management for your projects. The equivalent in Node.js is the npm command.

python

As for the python command in Python-land, the node command is a REPL that allows you to load execute Javascript code.

Features comparable with Python

virtualenv

Virtualenv in Python allows to have scoped dependencies, libraries and binaries for a specific project. There is no direct equivaent in Node.js, for the following reasons:

  • a Node.js project (initialized with npm init) always has its own dependencies in the node_modules folder.
  • The global dependencies (installed with npm install -g myPackage) are always scoped to the current version of Node.js you are using. That's a feature provided by NVM.

pip freeze

The pip freeze command outputs a new requirements.txt file with the exact versions of the currently used packages. In Node-land, the equivalent command is npm shrinkwrap, which outputs a shrinkwrap.json file which does exactly the same.

note: In Node, a best practice is to follow strictly the conventions of Semantic Versioning (aka. SemVer, which, when correctly followed, makes the usage of npm shrinkwrap pretty much useless.

pip install -e

This command lets you use a local version of a dependency that you might need to work on (-e stands for editable). This is very useful when your project has been decomposed in many subprojects and you want to integrate a new version in order to publish it.

The equivalent in Node-land is npm link though it must be used a little bit differently.

npm link declares that the current project you're in can be linked to another.

npm link myPackage will use the package myPackage in the current project and will use the version on which you have previously run npm link. Here's a more concrete example:

$ cd myLinkedProject
$ npm link
$ cd ../myProject
$ npm link myLinkedProject

Declaring dependencies

In Python, dependency management is separated in two files: requirements.txt (a part of pip) and setup.py. They have two very different meanings that go beyond the scope of this article, but if you're interested, you can read this article.

In node, the dependency management resides in package.json, which is created when you run npm init.

package.json describes everything related to your project: name, author and of course dependencies.

Installing a package is easy: just run npm install myPackage.

There are a number of very common switches to npm install:

  • -g installs the package globally, it will be available to all the other projects. It can be useful when you want to install general-purpose tools, like JSHint.
  • --save adds a line to package.json declaring that the dependency is required to run your project.
  • --save-dev adds a line to package.json declaring that the dependency is required as a part of your workflow or build process in your project.

Maintenance scripts

Though this is not strictly Python but Django, the file manage.py is used to create project-related scripts (setup, migration, maintenance, and so on...).

In Node.js, there are many alternatives (like, really a lot), but the simplest is the scripts property in package.json. Here you can declare as many scripts as you wish and use them in your projects with a simple npm scripts myScript where myScript is a key in the scripts hash of your package.json.

note: As the script is defined as a value in package.json, it's pretty inconvenient to write long scripts. These entries will generally use higher-level tools to do the right job. For instance, if you want to run your test suite and you're using Karma, the relevant part of your package.json could look as follows:

{
  "scripts": {
    "test": "node_modules/.bin/karma specs/**/*Spec.js"
  }
}

Conclusion

This is definitively not an exhaustive list, there are certainly many other similarities. But at Novapost, where we use bigger and bigger portions of the Javascript world and are already heavily using Python, we liked to see that best practices and good tools are shared among those two solid platforms.

By the way, we're hiring. If you're a (guess what ;) Python or (frontend) JS developer, feel free to contact us. There are plenty of great things to do here.

1 / 1