Accès clients

Le Blog

A First Look at node.js and Express

With all the hype coming to server-side Javascript lately, especially around Node, I was feeling the need to give it a try to see how it goes. Also, getting back to work after three full weeks of unwired holidays was hard enough to worth deserving some playtime with cool and fun technologies.

Node is described as an Evented I/O Framework for Google’s V8 JavaScript Engine. Think of it as a toolkit to produce high-performance distributed, event-driven and scalable non-blocking network servers. Okay, whatever the way I want to describe the project, it’s buzzword-bingo™. Let’s say it’s mainly about catching events and react accordingly, to make load distribution and parallel processing easier and more effective.

Installing Node

Installation on my Mac went smoothly and took nearly two minutes by compiling it from the sources; here’s how I did (there might be easier or better ways, I don’t really care):

$ mkdir tmp
$ git clone http://github.com/ry/node.git
$ cd node
$ ./configure && make && sudo make install

You now have access to the node executable available on your system.

A simple example of a Node HTTP server (put the code below in a test.js file):

var http = require('http');

var server = http.createServer(function(req, res) {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.write('Hello World');
  res.end();
});

server.listen(3000, "127.0.0.1");

Then launch the created webserver using the command line:

$ node test.js

And point your browser at http://127.0.0.1:3000 to get printed Hello World. Neat, huh?

Introducing Express, a Web Framework on top of Node

Express is a Web framework built on top of Node, HTTP and Connect, allowing easy creation of full-fledged Web applications. It has routing, handles environments as well as several template engines and much more.

Installation is as easy as Node’s one, so here we go:

$ git clone http://github.com/visionmedia/express.git
$ cd express
$ git submodule update --init
$ sudo make install && sudo make install-support

That’s it. You can now write your own test application, eg. in a new hello.js file:

var app = require('express').createServer();

app.get('/', function(req, res){
    res.send('Hello World');
});

app.get('/hello/:name', function(req, res){
    res.send('Hello ' + req.param('name') + '!');
});

app.listen(3000, "127.0.0.1");

console.log('Server running at http://127.0.0.1:3000/');

Launch your webapp server by the command line:

$ node hello.js

Express and will create a Node server listening to the local port 3000, so head your favorite browser to http://127.0.0.1:3000/ then http://127.0.0.1:3000/hello/niko to get the picture of what the above code does. Those familiar with Web framework such as rails, django or symfony won’t be much disturbed.

Express also ships with an express executable which provides useful commands. To create a new hello application skeleton, just run:

 $ express hello
   create : hello
   create : hello/app.js
   create : hello/logs
   create : hello/public/javascripts
   create : hello/pids
   create : hello/public/stylesheets
   create : hello/public/stylesheets/style.less
   create : hello/public/images
   create : hello/views/partials
   create : hello/views/layout.jade
   create : hello/views/index.jade
   create : hello/test
   create : hello/test/app.test.js

Above command just created an hello project directory where you can cd into and launch the server by its default front controller app.js:

$ cd hello
$ node app.js
Express server listening on port 3000

Note that the generated project skeleton implies using Jade as a tremplate engine and the Less CSS syntax, while one might want to use something else, which is perfectly possible by configuring the project differently.

Next steps documentation will be provided by official Express documentation.

Of course, Express might not be as full-featured as older well-established Web frameworks, but for simple needs it can be pretty easy to setup and deploy, and — probably equally importantly — fun to play with and learn.

Conclusion

As you can see, installing and using Node and Express is quite straightforward, even if you have to dig into the deeper Web to find docs, when they exist. Javascript is a great, agile and well-known language, and taking part of it server-side definitely makes sense if you want my opinion.

Let’s see how this will evolve in the future, as there are not as many backend-oriented libs in JavaScript as there are in other languages like python, ruby or php yet. But more and more node modules are appearing day after day, such as Mongoose or Socket.IO, which I’ll definitely be playing with as soon as possible.

Thanks for your attention, have fun, take care and don’t break the Web.

“ Walking on water and developing software from a specification are easy if both are frozen. „
— @rb2k

Tâches de déploiement spécifiques avec Symfony

Symfony propose une tâche de déploiement distant utilisant rsync fort pratique : une fois configurés les paramètres du serveur distant dans le fichier config/properties.ini de votre projet, un simple appel en ligne de commande synchronisera les fichiers du projet présents sur votre système de fichiers local vers l’hôte distant. Et si vous utilisez une clé SSH, l’opération ne vous demandera même pas de saisir votre mot de passe !

$ ./symfony project:deploy monserveur --go

Mais bien souvent, nous avons besoin de plus : préparer un certain nombre de fichiers statiques comme les assets CSS, JavaScript ou les images, ou vider le cache sur la ou les machines distantes pour prendre en compte d’éventuelles modifications de la configuration ou du templating sur la plateforme de production (qui exploite l’environnement du même nom, nous sommes bien d’accord).

Aussi, il est très simple de faire face à ces besoins spécifiques en créant vous même une tâche de déploiement projet, en surclassant la classe sfProjectDeployTask fournie en standard par Symfony. Par exemple, voici la tâche de déploiement que j’utilise pour la mise à jour du site Akei, exploitant mon plugin npAssetsOptimizerPlugin pour la gestion de la minification et l’assemblage des fichiers JavaScript, CSS et images PNG  :

<?php
class AkeiDeployTask extends sfProjectDeployTask
{
  /**
   * @see sfProjectDeployTask
   */
  protected function configure()
  {
    $this->addArguments(array(
      new sfCommandArgument('server', sfCommandArgument::REQUIRED, 'The server name'),
    ));

    $this->addOptions(array(
      new sfCommandOption('go', null, sfCommandOption::PARAMETER_NONE, 'Do the deployment'),
      new sfCommandOption('rsync-dir', null, sfCommandOption::PARAMETER_REQUIRED, 'The directory where to look for rsync*.txt files', 'config'),
      new sfCommandOption('rsync-options', null, sfCommandOption::PARAMETER_OPTIONAL, 'To options to pass to the rsync executable', '-azC --force --delete --progress'),
      new sfCommandOption('optimize', null, sfCommandOption::PARAMETER_OPTIONAL, 'The asset optimizations to make before deploying'),
    ));

    $this->namespace = 'akei';
    $this->name = 'deploy';
    $this->briefDescription = 'Deploys Akei website to a given server';
  }

  /**
   * @see sfProjectDeployTask
   */
  protected function execute($arguments = array(), $options = array())
  {
    // Assets
    if (!is_null($options['optimize']))
    {
      $this->logSection('deploy', 'assets optimization before deploying');
      $task = new npOptimizeAssetsTask($this->dispatcher, $this->formatter);
      $task->run(array('application' => 'main'), array('type' => $options['optimize']));
    }

    // Deployment
    $this->logSection('deploy', 'deploying...');
    parent::execute($arguments, $options);

    // Remote symfony cc
    if ($options['go'])
    {
      $this->logSection('deploy', 'remote cache clear');
      $this->getFilesystem()->execute('ssh user@monserveur.foo "/path/to/www/akei/symfony cache:clear"');
    }

    $this->logSection('deploy', 'done.');
  }
}

Comme vous pouvez le constater, cette tâche déclare un espace de nom akei et propose une option supplémentaire, optimize, permettant de préparer les assets avant déploiement :

$ ./symfony akei:deploy monserveur --optimize=stylesheet --go

Cette commande va tout simplement minifier et assembler les feuilles de style définies par la configuration du plugin npAssetsOptimizerPlugin, déployer les fichiers en production sur la machine monserveur et vider le cache sur la machine distante une fois l’opération effectuée.

Notez d’ailleurs l’emploi du très pratique appel à $this->getFilesystem()->execute(), qui permet d’executer des appels à la ligne de commande locale depuis la classe de tâche elle-même ; ici, une execution distante à travers SSH.

Bien entendu, cet exemple est très spécifique aux besoins du site Akei, mais vous pourriez en quelques minutes gérer plus finement une tâche de déploiement plus générique et configurable. Pensez-y pour vos projets ;)

PS : Ce billet a été écrit en 14 minutes. Merci de votre compréhension.

Formation Symfony Doctrine

Une nouvelle offre de formation Symfony 1.4 et Doctrine 1.2 sur 4 jours a été publiée sur le site aujourd’hui :

Cette formation sur quatre journées consécutives, a pour but de donner toute autonomie aux développeurs PHP5 aguéris à la pratique de la Programmation Orientée Objet pour développer des applications Web en utilisant le framework Symfony 1.4 et l’ORM Doctrine 1.2.

Comme d’habitude, n’hésitez pas à prendre contact si vos besoins sont éventuellement plus spécifiques, il est toujours possible de concevoir une formation sur mesure totalement adaptée.

“ Barack Obama : A project management account to which the most aspirational tickets — stuff you’d really like to do but will pobably never get approval for — gets assigned. „
— Tiré de New Programming Jargon (via leesbian)

Tweets

Derniers commentaires

Apprécié récemment

Voir plus