Node.js je prostředí JavaScriptu postavené na V8 (open source JavaScriptový engine od Google), které se používá k běhu serverových aplikací. Jeho výhodou je rychlost a možnost psát aplikace v JavaScriptu. Pro Node.js existuje velké množství modulů, kter lze snadno přidat do projektu. Mezi nejpopulárnější patří modul express, který umožňuje rychlý vývoj webových aplikací.
Instalace
Node.js se nachází v repozitáři Ubuntu 12.10 ve verzi 0.6.19, my si ale stáhneme zdrojové kódy té nejnovější z oficiálních stránek, tedy verzi 0.8.16: http://nodejs.org/dist/v0.8.16/node-v0.8.16.tar.gz. Nainstalujeme ho do systému pomocí standardních příkazů:
./configure
make
sudo make install
Je třeba mít nainstalovaný Python 2.6 nebo 2.7 a GNU Make 3.81 nebo novější. Společně s Node.js se instaluje i správce modulů npm. Oba programy budou v adresáři /usr/local/bin/.
Pozn.: Je možné stáhnout i zkompilovaný Node.js a neinstalovat ho do systému. Pak je vhodné udělat symbolické linky pro node a npm do adresáře /usr/local/bin/.
Vývojové prostředí
Bohužel, pro Node.js neexistuje vývojové prostředí, které by mi vyhovovalo. Plugin do Eclipse přidává jen možnost vytváření a spouštění projektů. Navíc nezobrazuje chyby v adresáři s moduly, což je příjemné. Každopádně si neumí poradit s doplňováním kódu, který je přidán pomocí require a také se mi nepodařilo zprovoznit doplňování pro JavaScriptové objekty.
O něco lepší je klon IntelliJ s názvem WebStorm. Podporuje přímo Node.js a až na varovné hlášky ohledně parametrů některých funkcí, se mi v něm vyvíjelo dobře. Doplňuje většinu kódu. Samotné prostředí je stejné, jako má IntelliJ, takže se v něm píše přijemně. Rychlost prostředí je podobná Eclipse.
Podporu JavaScriptu má také editor Sublime Text 2. Je velmi rychlý a má pokročilé funkce. Vytváření a editace kódu pro Node.js je v něm velmi příjemná. Při doplňování nabízí text, který už byl dříve napsán (nezáleží jestli před nebo za editovaným místem).
Osobně používám pro spouštění, správu projektu a zachytávání výstupů konzoli jako nejrychlejší a nejjednodušší nástroj. Její výhoda je v tom, že mi další okno nezakrývá/nezmenšuje celkový pohled na zdrojový kód.
První projekt
Jako ukázku funkčního kódu uvedu program, který použije modul express k vytvoření serveru na portu 8080 a při každém přístupu na adresu localhost:8080 vypíše na konzoli hlášku.
var express = require('express');
var app = express();
console.log('Server is running...');
app.get('/', function(req, res) {
console.log('get request');
res.send('hello');
});
app.listen(8080);
Dobrá praxe je vytvořit soubor package.json s informacemi o našem projektu. Pro nás je nejdůležitější definování závislosti modulu express. Základní obsah by mohl vypadat takto:
{
"name":"hello-world",
"version":"0.0.1",
"private":true,
"scripts":{
"start":"node app"
},
"dependencies":{
"express":"3.0.x"
}
}
Nyní můžeme spustit příkaz pro stažení závislostí (ty se objeví v adresáři node_modules u našeho projektu) a samotné spuštění aplikace:
npm install
node app.js
Všimněme si, že pokud aplikaci spustíme a uděláme v ní nějaké změny, ty se neprojeví. Jsme nuceni restartovat celou aplikaci a je to nešikovné. Naštěstí existuje utilita supervisor, která dokáže hlídat, jestli se v projektu změnil nějaký soubor a v případě že ano, provede restart aplikace sama. Její použití je intuitivní:
supervisor app.js
Databáze a REST API
Pozn.: Tato kapitola je velmi inspirována článkem Jakuba Mrozka, který je publikován na serveru zdrojak.cz. Doporučuji přečíst celou sérii jeho článků, ve které programuje e-shop za použití Node.js, Monga a Angularu. Uvádím ji proto, aby zde existovalo kompletní, jednoduché a funkční REST API využívající databázi, které se dá zkopírovat a hned na něm stavět vlastní projekt.
Pro instalaci Monga stačí využít balíček mongodb z repozitáře. Příkazem mongo se spustí terminálový klient. Ukážeme si základní práci s ním:
use pokus
var product = {name: 'iPhone', url: 'iphone'};
db.products.insert(product);
db.products.find();
Nejdříve uděláme aktivní databázi pokus. Pak definujeme objekt a vložíme ho do databáze. Poslední příkaz vypíše všechny produkty z databáze.
Pro Node.js existuje modul mongoose, který umožňuje jednodušší práci s databází (podobně jako některé ORM frameworky). Dalším užitečným modulem je express-resource, který je vhodné použít pro budování REST API, protože přidává expressu metodu resource, která očekává controller s metodami index, show, create, update a destroy, které se mapují na zadané URL.
model/Page.js
var mongoose = require('mongoose');
var PageSchema = new mongoose.Schema({
title: String,
url: String
});
// Our static method findOneByUrl is called in app.js
PageSchema.statics.findOneByUrl = function(url, cb) {
Model.findOne({url: url}, cb);
};
var Model = module.exports = mongoose.model('Page', PageSchema);
controller/Page.js
var PageModel = require('../models/Page');
// GET: /
exports.index = function(req, res) {
PageModel.find(function(err, docs) {
if (err) console.log(err);
res.json(docs);
});
};
// GET: /url
exports.show = function(req, res) {
res.send(req.page);
};
// POST: / JSON: {"title":"První", "url":"prvni"}
exports.create = function(req, res) {
var page = new PageModel();
page.title = req.body.title;
page.url = req.body.url;
page.save(function(err, doc) {
if (err) console.log(err);
res.json(doc);
});
};
// PUT: /url JSON: {"title":"První"}
exports.update = function(req, res) {
req.page.title = req.body.title;
req.page.save(function(err, doc) {
if (err) console.log(err);
res.json(docs);
});
};
// DELETE: /url
exports.destroy = function(req, res) {
req.page.remove(function(err, doc) {
if (err) console.log(err);
res.json(doc);
});
};
app.js
require('express-resource');
var express = require('express');
var mongoose = require('mongoose');
var app = express();
console.log('Server is running...');
var PageController = require('./controllers/Page');
var PageModel = require('./models/Page');
// Connect to the database
mongoose.connect('mongodb://localhost/pokus', function(err) {
if (err) console.log(err);
});
// Use body parser (required in controller)
app.use(express.bodyParser());
app.get('/', function(req, res) {
res.send('hello');
});
app.resource('pages', PageController, { base: '/api/', load: PageModel.findOneByUrl });
app.listen(8080);
package.json
{
"name":"application-name",
"version":"0.0.1",
"private":true,
"scripts":{
"start":"node app"
},
"dependencies":{
"express":"3.0.x",
"express-resource":"1.0.x",
"mongoose":"3.3.x"
}
}
Po přidání závislostí je třeba v adresáři projektu spustit následující příkaz, který stáhne potřebné závislosti do souboru node_modules.
npm install
Testování
Závěr
Na několika fórech jsem četl, že Node.js není vhodné pro větší projekty a už vůbec ne pro projekty komerční. Myslím, že tomu tak není a Node.js má své uplatnění. Je to sice mladý projekt, ale už teď pro něj existuje nepřeberné množství modulů, které lze snadno použít ve své aplikaci.
V budoucnu se chci ještě věnovat možnostem testování pro Node.js a vývojem řízeným testy (Test Driven Development), na což v tomto článku nezbylo místo.