Habits of a Happy Node Hacker
blog.heroku.com
blog.heroku.com
1. Node as a scripting language
2. Node + Express or Hapi or whatever as a web development framework
The recommendations in this article work well if you're targeting Node as a scripting language.
However, if you are developing using a web framework, then some of the recommendations are too lean (IMO).
1. npm init
When I'm developing for the web, I use a more robust application skeleton. There are a ton to choose from. However, I do use npm init when developing scripts. My guess is the author's point is something like, "good Node devs include a package.json".
2. Declare all dependencies
Absolutely. Works for both web and scripts.
3. Specify a start script
Yes, for scripts.
However for the web task runners such as Grunt / Gulp / etc. work better. For web dev starting the server is just one task of many. For example, if you need to start the server after checking the environment, watch for file changes, run jslint/jshint, and so on then a task runner makes web development easier.
4. Specify a test script
Yes!
5. Keep dependencies out of source control
Yes, but use npm-shrinkwrap because the code you deploy (your code + deps) should be the exact same code that you ran during testing.
6. Use environment variables to configure npm
Absolutely. Config files are another option, but this is a matter of personal preference. The authors point is totally valid.
7. Bring your own npm registry
This is an interesting one and one where there is no clear "best choice" yet. It'll be interesting to see how npm (public and private) evolve.
8. Keep track of outdated dependencies
Yup
9. Use npm scripts to run custom build steps
This is now being debated. There are some in the community who specifically prevent pre/post scripts from running automatically when installing via npm.
10. Try new things
Debatable (at this time). These new features can also go onto the todo list in the near future. If someone is new to node, they may be better served by focusing on what node / JS does now.
11. Browserify
Depends. If you're using Angular, then it has its own module system. I think Ember has its own module system as well.
require.js is another option. But the author's point about having client-side modules is totally valid.
Again, nice article.
[1]: https://www.npmjs.org/package/grunt-nodemon
[2]: https://www.npmjs.org/package/node-inspector
[3]: https://www.npmjs.org/package/grunt-concurrent
Edit: here is an example configuration: https://github.com/ChrisWren/grunt-nodemon#advanced-usage
It seems natural to me to handle "lock in precise deps" on the version control level. Of course there is value in tools like npm & bower intelligently resolving deps with "soft lock in" like "~1.2.3" but it makes sense to me that I'd have to commit the resulting precise versions as a new submodules state.
- I now discovered "npm submodule" command but once checked out "npm will stubbornly refuse to update" them. Why? - I tried to google for bower submodules and nobody seems to even voice the idea, although bower is more git-centric. What am I missing?
P.S. I should admit that I'm biased by not wanting to give up the convenience of Github Pages for pure html/js (without any build/minify steps) — Pages supports submodules (one level deep) so I can just push. I should graduate to Heroku which can do arbitrary build on push I guess...
Still, there will always be reasons why some people DO check in deps and advise others to do so. Why not natively support submodules as the less harmful way to do that?
Grunt also makes it super simple to do add tasks which are wrappers for things like Vagrant etc. For example, you can bootstrap a vagrant vm with a mongo service provisioned inside the VM and have that auto-deploy before you start you development workflow.
For those who are interested (in filing bugs, seeking inspiration, providing feedback), feel free to check out my NodeJS starter project here: https://github.com/sabhiram/nodejs-scaffolding
In addition this also eliminates the possibility of you being unable to deploy your application because npm decides to make a breaking change without bothering to inform anybody, or if npm goes down for any reason.
I find this over reliance on npm in the node community a bit discomfiting. npm is a package manager and an excellent one at that. But using it for everything from running tests to application deployment is not a very good idea.
I've noticed some culture differences between front-end and back-end javascripters.
Could you elaborate on those?
Grunt is a task runner. It's a general purpose utility, that happens to work well with JavaScript (client and server).
Our team first started using Grunt to concat Scala templates prior to compilation (in an old version of Play with an old JVM). Back then, we noticed that concatenating the Scala files reduced the amount of heap used during compilation. Never did figure out why.
Later, we started to use Grunt to minify and concat our Backbone code.
Currently, we use Grunt for both our server-side Node and client-side Angular.
Server-side we use Grunt to: 1.) Restart Node on file change, 2.) Run JSHint against both server-side and client-side JavaScript, 3.) Set some environment vars prior to starting Node, plus a few other small tasks.
Client-side we use Grunt to: 1.) Create a production build by minifying and concatenating JS, 2.) Minifying and concatenating CSS, Minifying HTML, plus some other minor tasks.
We also use Grunt to run the client and server test suite.
Basically, it's common practice to use Grunt (or Gulp, or another task runner) to assist with both client and server-side JS.
"build": "npm run build-js && npm run build-css"
Ok I see. That's sort of a poor man's dependency checker.Once you familiarize yourself with the Grunt way of setting up tasks, it becomes trivially simple to obtain and run plugins for your tasks.
1. Runs unit tests any time source or test files change
2. Runs JsHint on the source any time it changes
3. Generates a static documentation site based on any edits I make to my markdown files
4. Brings up, tears down vagrant VMs which host a MongoDB (or whatever) instance
This makes development workflow really awesome. Just do "grunt watch" in a terminal, and you will always be able to see your tests go from fail to pass as you develop your (linty clean) code.
I have seen many others use (and mention the use of) Grunt to reboot the server on file change, this is one of those programing austerities I have not given up (yet).
[1] - Sample Gruntfile - https://github.com/sabhiram/nodejs-scaffolding/blob/master/G...
[2] - Grunt Plugins - http://gruntjs.com/plugins
Am I the only one who doesn't? I don't want to add another step for people checking out my branch. It should just work.
Seems a very nice tip. I would love to hear more about this.