Renato Ivancic - Software Engineer

Background image

NodeJS hints

Web Development

NodeJS

NodeJS

Node.js is a JavaScript runtime an interpreter built on Chrome’s V8 JavaScript engine.

Node version manager

If your project is dependend on some specific Node verison you can use the benefits of the nvm.

What it does is… manage your Node version. Every once in a while, Node comes out with a new version of the language and interpreter that changes some things. A version manager lets you switch which version your computer is running. This is important because sometimes a Node program won’t actually run in a newer version so you have to keep an older one around, but on the other hand, some other Node program won’t run in the older version and needs the new one.

For example running gulp task can throw out ugly error message if incorrect node.js is used.

guest@laptop:~/Projects/platform/test-project$ gulp buildDev
/home/guest/Projects/platform/test-project/node_modules/node-sass/lib/binding.js:15
      throw new Error(errors.missingBinary());
      ^

Error: Missing binding /home/guest/Projects/platform/test-project/node_modules/node-sass/vendor/linux-x64-51/binding.node
Node Sass could not find a binding for your current environment: Linux 64-bit with Node.js 7.x

Found bindings for the following environments:
  - Linux 64-bit with Node.js 4.x

This usually happens because your environment has changed since running `npm install`.
Run `npm rebuild node-sass` to download the binding for your current environment.
    at module.exports (/home/guest/Projects/platform/test-project/node_modules/node-sass/lib/binding.js:15:13)
    at Object.<anonymous> (/home/guest/Projects/platform/test-project/node_modules/node-sass/lib/index.js:14:35)
    at Module._compile (module.js:571:32)
    at Object.Module._extensions..js (module.js:580:10)
    at Module.load (module.js:488:32)
    at tryModuleLoad (module.js:447:12)
    at Function.Module._load (module.js:439:3)
    at Module.require (module.js:498:17)
    at require (internal/module.js:20:19)
    at Object.<anonymous> (/home/guest/Projects/platform/test-project/node_modules/gulp-sass/index.js:187:21)

So we see current environment is using Node.js 7.x but the expected binding is Node.js 4.x

The problem is that for multiple local projects maybe you’ll need different Node.js versions. The solution is quite simple. Install nvm, install required versions and set the default one or switch between them with following commands.

https://github.com/creationix/nvm

Usage

Install with

curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.11/install.sh | bash

Verify instalation

nvm --version

Install latest version

nvm install node # "node" is an alias for the latest version

To install a specific version of node

nvm install 6.14.4 # or 10.10.0, 8.9.1, etc

And then in any new shell just use the installed version

nvm use node

If you want to see what versions are installed

nvm ls

If you want to list all remote available versions

nvm ls-remote

To set a default Node version to be used in any new shell, use the alias ‘default’. To use the latest version

nvm alias default node

To use version v4.9.1

nvm alias default v4.9.1

NPM

NPM

npm is the package manager for JavaScript and the world’s largest software registry. Discover packages of reusable code — and assemble them in powerful new ways.

Listing dependencies

npm list

Pinning the versions

The package.json file is the heart of the npm package management. Among other things there you can manage dependency versions.

"devDependencies": {
  "node-sass": "^4.9.3",
  "js-beautify": "1.7.5"
}

Note that you have two section of dependencies defined as JSON properties. Dependencies are modules which are required at a runtime. devDependencies are modules which are only required during development or compilation time. For example, you see above node-sass and js-beautify are used only in compilation time. Node-sass compiles sass to css and js-beautify is formatting the js and css files which are then used in runtime, but at the runtime itself these dependencies are obsolete so they will not be a part of the application.

Relaxed versioning

Dependency definition follows Semantic versioning or semver, with an extension, I’ll call it relaxed versioning. When not used with extreme caution, it will cause Dependency Hell.

If you have a problem that the build of npm application suddenly breaks, because dependencies are incompatible, but you swear you did not changed anything. The issue is also known as “It works on my machine”. I can tell that in the package.json file you’ll see strange ASCII characters in front of version numbers. They indicate restrictions on which software version numbers can be used as a dependency in your project. With those signs you don’t specify the very specific version. You can give npm the freedome to decide to use never versions.

Carret (^)

  • Backward compatible new functionalities
  • Large internal refactor
  • Bug fixes
  • Deprecation of old functionality (which is still operational)

With the caret you can get releases like 3.., where the * characters will match the highest version number available. So changes in the major digit, like 4.0.0, will not be used in this case.

Tilde (~)

  • Bug fixes

With tilde, you can get releases like 3.9.*. Only the latest bug fixes are allowed with the tilde.

Conclusion

I have seen too often that builds failed on local machines as well on build servers, as a result of using relaxed version definition with tilde or carret in npm-backed projects. I can’t understand why would somebody want to use this feature in enterprise solutions. Do you really want that dependencies are upgraded and as a consequence break a build. Its ok to use the relaxed versions for prototyping or using it locally. But before proceeding with deployment to production you should do npm list on tested environment and put the dependencies versions in stone.

The most common side effects of relaxed versioning include:

  • Nausea
  • Sore throat
  • Red sight
  • Anger outbursts

These are not all the possible side effects of relaxed versioning. For more information, please read the Versioning guide; ask your architect or stackowerflow.

js-beautify

https://www.npmjs.com/package/js-beautify

https://github.com/beautify-web/js-beautify

[email protected] has dependency on it.

In version 1.8.4 the base64 data strings are broken, because it adds additional space. Issue

v1.7.5

background: url(data:image/gif;base64,R0lGODlhCwALAJEAAAAAAP///xUVFf///yH5BAEAAAMALAAAAAALAAsAAAIPnI+py+0/hJzz0IruwjsVADs=);

v.1.8.4

background: url(data:image/gif; base64, R0lGODlhCwALAJEAAAAAAP ///xUVFf///yH5BAEAAAMALAAAAAALAAsAAAIPnI+py+0/hJzz0IruwjsVADs=);

Bower

Bower

Bower played an important role in improving the way front-end developers manage their dependencies—the advantages it provided set the stage for later features in npm and Yarn. In short get rid of it. https://snyk.io/blog/bower-is-dead

TODO rewiew

Why this needs to be added

.bowerrc

{
  "registry": "https://registry.bower.io"
}

package.json

{
  "devDependencies": {
    "bower": "1.8.4",
    ...
  }
}

Sources:

Ponyfoo

Carret vs Tilde - StackAbuse

#node