I’m poking around quite a lot with io.js recently for reasons that soon will be revealed. When doing so I used my favorite Node version manager - Node Version Manager to manage different versions of Node and io.js.
Switching back and forth is simple and sometimes I end up running some code on a version of Node/io.js that the code does not support. For example running EcmaScript 6
let-statements in Node.
I was hoping that I’d get a warning or preferable even an error when doing that. But no. Or…
In this post I’ll show you how to use the package.json file to make sure that you get warnings and errors when using the wrong version of the framework
In the package.json there’s an optional node that you can set called
engines. From the documentation we can read about what this is for:
You can specify the version of node that your stuff works on
Love the informal tone of that documentation. Ok, so here we can list of not only Node, but also alternative runtime like io.js but also npm. This can be given as just a version number or with a range
But you could also state that your “stuff” runs on several version of Node. In the case of using iojs this is true for all Node applications that is not using the EcmaScript 6 features not yet released in Node. Koa is a good example of this. This is an extract from their package.json
Koa supports both node and io.js at the respectively stated versions.
There’s another optional configuration setting in the package.json file called
engineStrict. Again from the documentation we read
If you are sure that your module will definitely not run properly on versions of Node/npm other than those specified in the engines object, then you can set "engineStrict": true in your package.json file.
and also about the engines-node
...unless the user has set the engine-strict config flag, this field is advisory only.
Note that the
engineStrict flag is set to false per default, leaving the
engines node “advisory only”.
Basically it means that we can be more restrictive about what our code need to run. For example, let’s say that I’m using some feature that only io.js supports, like the
let-statement for EcmaScript 6 for example. Then I can use the following configuration:
This will ensure that only io.js at version 1.6.1 is used when running my module. But how is that ensured?
Using the engines configurations
Well this is cool but what does that mean? I’m state the engine my things requires but how can I use it?
Let’s take an example and test it out. Let’s say that I have a package.json with the following configuration for engines:
But right now I’m running Node at
v0.11.14 (for example by going
nvm install v0.11.14) on my system. In my directory I go
npm install to install all the packages my application depends on. Knowing what I know now I expect an error. I have the wrong version of the framework and I’m using the
But we are sorely disappointed. No error. No warning. Everything happily installed. It even starts up, unless there’s a syntax error due to us using a later version of node.
Surely this is a bug?!
Marcus, a few days a go.
As it turns out the engines configuration are checked installation time of package. Yes, remember that
npm stands for Node Package Manager. The engines-field is also in the package.json file. I first thought and hoped that this would be checked when i run my application but it’s not. The engine field will be verified when you install the package, not when you run it.
But we did do
npm install. Why didn’t it check this field?! Because doing
npm install in our application folder only installs our applications dependencies. Should anyone of those dependencies require another framework version than the one we are on will would get the warning/error (depending on the
However there’s a trick here. Bless the makers of Node for their strive for simplicity. Here’s what you do:
- go up one directory
- now npm install your application folder, for example
npm install myApp
This will install your application as a package, trigger the checks of the
If we try that again, with the same settings as before; engines: node = 0.12.0, and engineStrict = true… Lo and behold: we get the error we’ve been longing for:
engineStrict to false, give us warnings but it installs. Just as expected:
And finally, if we change the
engines to match our running version (0.11.14) it works without errors.
I think that with the advent of io.js we all have to be more watchful of which engines we are using for our code. Especially when we are deploying to services like Heroku etc.
Knowing how, and why, the
engineStrict behaves as it does will be very valuable for me. And hopefully for you too.
Published byon Last updated