« Previous 1 2
Programming with Node.js and JavaScript
Turbulent World
Structure
Basically, neither Node nor Express demands a specific structure for web applications. This feature could also be understood as a weakness, because as a beginner, you may initially find yourself somewhat disoriented. However, when you install Express with the -g
(for global) switch, it also gives you a command-line tool of the same name. It creates the public
directory for static files, routes
for routes, and views
for templates. The main function of the application resides in the app.js
file (Figure 2).
In the figure, you can see another aspect of NPM package management – that is, the package.json
file. If you develop a Node application manually, you do not have to use it, but it is recommended for structuring your projects. It contains the metadata of a project and the packets needed to run it. Yet another section contains the packages needed to "develop" the project – more on that later. If package.json
is complete, you just need to call npm
in the same directory for NPM to install all the packages listed there, including their dependencies.
The npm
command also offers two practical switches that save the developer from entering each required package manually in package.json
. Using
npm install package --save
enters the package to be installed in package.json
in the dependencies
section, whereas
npm install package --save-dev
puts the package in devDependencies
. Listing 4 shows an example of an NPM package file of this type.
Listing 4
package.json
01 { 02 "name": "random", 03 "version": "0.0.1", 04 "private": true, 05 "scripts": { 06 "start": "node app.js" 07 }, 08 "dependencies": { 09 "express": "*", 10 "swig": "*", 11 "consolidate": "*" 12 }, 13 "devDependencies": { 14 "grunt": "~0.4.1", 15 "grunt-contrib-copy": "*", 16 "grunt-contrib-clean": "*", 17 "grunt-contrib-uglify": "*", 18 "grunt-htmlrefs": "*" 19 } 20 }
Development dependencies include just the Grunt package [8], along with a few of its subprojects, about which I also need to say a few words. To structure the development process, JavaScript or Node developers show an increasing tendency to use build tools, as known from compiled languages, such as Make/CMake from C/C++, or Ant/Maven from Java. In principle, the compile step is dropped in JavaScript; Node handles this for server code, whereas the user's web browser does the same for client code. However, there are quite a number of steps in web development at which projects can be optimized thanks to "compilers," or preprocessors; that's where tools like Grunt enter the game.
For example, many meta-dialects exist for CSS stylesheets, such as SASS and LESS, that introduce includes and variables like the HTML templates mentioned previously or abstractions for the differences between different browsers. This approach greatly simplifies the task of maintaining style sheets in larger projects. At some point before delivery to the browser, these dialects must be translated back into classic CSS, either at run time or offline using a build tool like Grunt, which in turn calls the appropriate preprocessors.
The same goes for JavaScript code that needs to meet different requirements for development and production: In development, the focus is on structuring, readability, and maintainability, but when the project moves into the production phase, it shifts primarily to performance. It goes without saying that the code should be error-free to the greatest extent possible in both cases.
For web projects, performance not only means efficient algorithms but also using small files and as few as you can effect. You typically need to find a compromise that is defined by the specified key data (maximum number of concurrent HTTP connections per browser/server combination) or that can be determined experimentally. Grunt also supports this process by allowing the developer to integrate various tools for compressing (e.g., UglifyJS), merging, or otherwise transforming JavaScript files.
Future
Grunt offers many opportunities, but it also seems a bit strange to reverse-engineer a program like GNU Make in JavaScript only to then have to formulate its tasks in a fairly awkward way in JSON. Every community, however, is probably doomed to reinvent its own very special wheel. This, therefore, conveniently brings up the biggest weakness in the Node world, which is also its greatest strength: its enormous enthusiasm, which unfortunately dies out as quickly as it flares.
Grunt is one example. Although it was recently hailed as the greatest invention of all time, it is already regarded as clumsy. The new emperor in Node-build country goes by the name of Gulp, if you believe the propagandists [9]. However, nobody knows what developments next week will bring. This situation in itself is not bad, but if you are new to Node, the huge selection of packages and frequently changing favorites can lead to despair.
In this article, I only touched on the topic of programming complex applications with Node. Next time, I will look at circumnavigating the pitfalls of asynchronous processing and helping components communicate with one another via events.
Infos
- Helma: http://helma.org
- Node.js: http://nodejs.org
- "Apache HTTP Server 2.4" by Rich Bowen, Linux Pro Magazine , Issue 149, April 2013, pp. 42-46: http://www.linuxpromagazine.com/Issues/2013/149/Apache-HTTP-Server-2.4
- "SmartOS" by Oliver Frommel, ADMIN , Issue 19, pp. 70-75.
- Azure tools: http://www.windowsazure.com/en-us/downloads/cli-tools-install
- Express: http://expressjs.com
- Swig: http://paularmstrong.github.io/swig/docs
- Grunt: http://gruntjs.com
- … it's all about Gulp and Browserify now: http://www.100percentjs.com/just-like-grunt-gulp-browserify-now
« Previous 1 2
Buy this article as PDF
(incl. VAT)