Scroll to top

Spanish (Español) translation by Kelly Gianella (you can also view the original English article)

Hace unos años, como muchas personas, comencé a escuchar más y más sobre Node.js. Había estado creando aplicaciones del lado del servidor en ColdFusion durante más de una década, pero siempre tuve curiosidad por ver cómo funcionaban también otras plataformas. Disfruté de JavaScript en el cliente y usarlo en el servidor me pareció fascinante. (Aunque no necesariamente nuevo. Tengo la edad suficiente para recordar cuando Netscape lanzó SSJS en los años 90). Leí algunos tutoriales, me senté en unas cuantas sesiones, y en general salí... Impresionado.

Cada vez que leía algo sobre Node terminaba volviendo a la misma historia: construir un servidor web. Francamente, eso no fue emocionante. Incluso cuando hice aplicaciones web por primera vez en scripts CGI de Perl, no tuve que preocuparme por eso. Podría ver el potencial en proveedores de API pequeños y ligeros, pero ¿crearía un sitio simple en él? ¡No es posible!

Pero un día tuve suerte. Había decidido sentarme en una presentación más de Node (principalmente porque conocía bien al presentador) y durante su presentación el orador demostró Express. Se apagó una bombilla. ¡Aquí estaba el marco de nodo que estaba esperando! Sí, en teoría, todavía está creando su propio servidor web, pero ese aspecto se minimiza y, en su lugar, puede centrarse en la lógica y el contenido de su sitio. Aún mejor, vi cómo la integración de motores de plantillas permitía una experiencia de tipo casi ColdFusion (o PHP). En este artículo le mostraré cómo instalar Express y cómo empezar a crear aplicaciones web con el marco.


instalación

Lo más probable es que ya sea un desarrollador de Node. Si eres nuevo en la plataforma, entonces todavía puedes estar asombrado por el poder de npm. Sé que lo soy. Como dije, la mayor parte de mi vida la pasé haciendo ColdFusion. Hay un rico, si no grande, ecosistema de código abierto para esa plataforma. Pero descubrir e instalar es un asunto manual. Las primeras veces que usé npm estaba asombrado. Francamente, ahora me cuesta imaginar el uso de una plataforma sin una herramienta como npm. Comencemos con un archivo package.json donde agregaremos la dependencia Express.

1
{
2
	"name": "demo1",
3
	"description": "First Express app",
4
	"version": "0.0.1",
5
	"dependencies": {
6
		"express": "3.x"
7
	}
8
}

Una vez más, esto debería ser bastante estándar para los desarrolladores de Node. Baje a la línea de comandos y ejecute:

1
npm install

Lo que instalará Express y sus dependencias.

Por el contrario, también puede instalar Express como una herramienta de línea de comandos para generar rápidamente aplicaciones esqueleto. Esto se puede hacer ejecutando:

1
npm install -g express

Una vez hecho esto, puede ejecutar express en la línea de comandos para generar una aplicación.


Primeros pasos

Volvamos a la aplicación que creamos con el archivo package.json anterior y agreguemos un archivo app.js. Como mínimo, la aplicación creará una nueva instancia del objeto Express y comenzará a escuchar en un puerto determinado. Comencemos con esto:

1
var express = require('express');
2
var app = express();
3
4
app.listen(3000);

Personalmente, tiendo a tomar las cosas muy lentamente al aprender un nuevo marco, por lo que podría tener sentido ejecutar rápidamente la aplicación de nodo solo para asegurarme de que nada se jodía.

Definición de nuestras rutas

Ahora vamos a intentar agregar algunas rutas simples a la aplicación. Las aplicaciones Express pueden responder a varios verbos HTTP como métodos de API. Así que como ejemplo:

1
//Regular HTTP get
2
app.get(some url, do something);
3
4
//Some other page
5
app.get(some other url, do something else);
6
7
//I can respond to a form post
8
app.post(some url, do more stuff);

Vamos a crear un ejemplo real de esto y agregar una página de inicio a la aplicación:

1
app.get('/', function(request, response) {
2
	response.send("This would be some HTML");
3
});

Tenga en cuenta que Express añade un método send() simple al objeto de respuesta. Esto abstrae parte del código reutilizable para controlar las respuestas. Si ha hecho todo bien, ahora puede reiniciar su aplicación y abrir su navegador al puerto 3000.

La API request.send() también maneja de forma inteligente diferentes tipos de datos. Imagine que desea agregar una API simple basada en JSON a su sitio. Simplemente devolviendo un objeto en lugar de una cadena, Express controlará la conversión del resultado a JSON, así como la configuración de los encabezados de respuesta adecuados.

1
app.get('/api', function(request, response) {
2
	response.send({name:"Raymond",age:40});
3
});

Como puedes imaginar, en este punto, la creación de una aplicación consistiría en agregar más y más rutas para manejar lo que pueda ser tu necesidad. Vamos a construir un sitio estático muy simple que utiliza lo que hemos aprendido hasta ahora.


Aplicación de blog genérico 9000

Para nuestro primer sitio, crearemos un blog. Sí, esto no es terriblemente nuevo o emocionante, pero también es algo que todo el mundo entiende conceptualmente. Puede encontrar el código fuente completo de esta aplicación en la descarga adjunta en la carpeta blog1. Omitiremos el archivo package.json ya que es exactamente el mismo, excepto por el nombre. Veamos en su lugar .js aplicaciones.

1
var express = require('express');
2
var app = express();
3
4
app.get('/', function(req, res) {
5
	res.sendfile('./views/index.html');
6
});
7
8
app.get('/about', function(req, res) {
9
	res.sendfile('./views/about.html');
10
});
11
12
app.get('/article', function(req, res) {
13
	res.sendfile('./views/article.html');
14
});
15
16
app.listen(3000);

Una de las primeras cosas que notará es que hemos cambiado de la API de envío a sendfile. Si bien podríamos incrustar cadenas HTML grandes en nuestro archivo .js aplicación, eso se complicaría bastante rápido. Tenemos tres rutas para esta aplicación. Uno para la página de inicio, otro para una página "Acerca de" y otro para un artículo. Por lo general, la página del artículo representaría una entrada de blog, pero por ahora, estamos manteniendo las cosas simples.

Agregar en el HTML

El HTML para nuestras páginas también es bastante simple. Aquí está la página de inicio:

1
<html>
2
<head>
3
	<title>Home Page</title>
4
</head>
5
6
<body>
7
<h1>Blog!</h1>
8
9
<footer>
10
<p>
11
	<a href="/">Home</a> ~ <a href="/about">About Me</a> ~ <a href="/article">Some Article</a>
12
</p>
13
</footer>
14
15
</body>
16
</html>

Observe que no hay nada especial aquí todavía. Es HTML estático simple que será devuelto por la aplicación Express tal cual. Las páginas Acerca de y Artículo son las mismas fuera de los cambios en los valores de título y h1.

Una vez más, inicie esto en la línea de comandos y abra su navegador. (Por cierto, uno de los errores comunes que cometí al aprender Node por primera vez fue olvidarme de matar mis demos anteriores. Si todavía está ejecutando la última aplicación, mantendrá el puerto 3000. Matarlo o utilizar otro puerto para esta aplicación.) Usted debe ser capaz de navegar alrededor de esta sencilla aplicación en unos pocos clics.

Ahora pasemos de estático a dinámico.

De estático a dinámico

Express admite una variedad de motores de plantillas. Los motores de plantillas son como muchas cosas en el mundo de la tecnología, un paso más bajo que la religión y la política. La línea de mandatos express puede añadir soporte para Jade, EJS, JSHTML y Hogan. Según la documentación de Express, cualquier motor de plantillas que se ajuste a una firma determinada funcionará con él. También recomiendan comprobar la biblioteca de consolidación.js para obtener una lista de los motores de plantillas compatibles.

Personalmente, soy un gran fan de Handlebars (handlebarsjs.com). Lo he usado en muchas aplicaciones del lado cliente y era un ajuste natural para mí para usar en el lado del servidor. Para usar Handlebars necesitas instalar una librería wrapper llamada hbs. Vamos a agregar esto a nuestra aplicación.

1
{
2
	"name": "blog2",
3
	"description": "Blog app",
4
	"version": "0.0.1",
5
	"dependencies": {
6
		"express": "3.x",
7
		"hbs":"*"
8
	}
9
}

Ahora vamos a actualizar nuestra aplicación.js para usar este motor:

1
var express = require('express');
2
var app = express();
3
4
var hbs = require('hbs');
5
6
app.set('view engine', 'html');
7
app.engine('html', hbs.__express);
8
9
app.get('/', function(req, res) {
10
	res.render('index');
11
});
12
13
app.get('/about', function(req, res) {
14
	res.render('about');
15
});
16
17
app.get('/article', function(req, res) {
18
	res.render('article');
19
});
20
21
app.listen(3000);

Hemos hecho algunas cosas importantes aquí. Para usar Handlebars, cargamos (a través de require) la biblioteca de envolturas hbs. Luego tenemos que decirle a Express que lo use. De forma predeterminada, Handlebars funcionará con archivos que contienen una extensión que coincide con el motor en particular. En nuestro caso, something.hbs. Pero podemos decirle a Express que trate los archivos HTML como dinámicos mediante el uso de la directiva "view engine", que se ve arriba. Esto no es necesario, pero prefiero trabajar con archivos HTML. Mi editor puede proporcionar sugerencias de código más agradables y resaltado de sintaxis. En realidad, la carga del motor se realiza a través de app.engine.

Por último, todas las rutas cambian a usar el nuevo método de representación. Express usa de forma predeterminada la carpeta views, por lo que podemos dejar eso. Dado que Express también sabe la extensión que preferimos, también podemos olvidarnos de eso. Esencialmente, res.render('something') equivale a decirle a Express que busque views/something.html, lo analice en función de las reglas de nuestro motor de plantillas y lo devuelva al navegador.

Puede encontrar este ejemplo en la carpeta blog2, en el código fuente adjunto. Como dije antes, me gusta dar pequeños pasos, así que aunque en realidad no estamos haciendo nada dinámico, recomiendo disparar esto en la línea de comandos y asegurarse de que aún pueda navegar por el sitio.

Visualización de entradas de blog en la página de inicio

Dado que ahora soportamos plantillas dinámicas, hagámoslas realmente dinámicas. Dado que estamos creando un blog, debemos agregar soporte para enumerar un conjunto de entradas de blog en la página de inicio y permitirle vincular a un motor de blog en particular. Si bien podríamos activar una conexión a MySQL o Mongo, vamos a crear un conjunto estático de datos, así como una biblioteca de contenedores simple para ello. Aquí hay un archivo blog.js que proporciona tanto para obtener un conjunto de entradas como para obtener solo una.

1
var entries = [
2
{"id":1, "title":"Hello World!", "body":"This is the body of my blog entry. Sooo exciting.", "published":"6/2/2013"},
3
{"id":2, "title":"Eggs for Breakfast", "body":"Today I had eggs for breakfast. Sooo exciting.", "published":"6/3/2013"},
4
{"id":3, "title":"Beer is Good", "body":"News Flash! Beer is awesome!", "published":"6/4/2013"},
5
{"id":4, "title":"Mean People Suck", "body":"People who are mean aren't nice or fun to hang around.", "published":"6/5/2013"},
6
{"id":5, "title":"I'm Leaving Technology X and You Care", "body":"Let me write some link bait about why I'm not using a particular technology anymore.", "published":"6/10/2013"},
7
{"id":6, "title":"Help My Kickstarter", "body":"I want a new XBox One. Please fund my Kickstarter.", "published":"6/12/2013"}];
8
9
10
exports.getBlogEntries = function() {
11
	return entries;
12
}
13
14
exports.getBlogEntry = function(id) {
15
	for(var i=0; i < entries.length; i++) {
16
		if(entries[i].id == id) return entries[i];
17
	}
18
}

Normalmente, también tendríamos métodos para agregar, editar y eliminar, pero por ahora esto es suficiente. Veamos ahora un archivo de aplicación.js actualizado que usa este motor.

1
var express = require('express');
2
var app = express();
3
4
var hbs = require('hbs');
5
6
var blogEngine = require('./blog');
7
8
app.set('view engine', 'html');
9
app.engine('html', hbs.__express);
10
app.use(express.bodyParser());
11
12
app.get('/', function(req, res) {
13
	res.render('index',{title:"My Blog", entries:blogEngine.getBlogEntries()});
14
});
15
16
app.get('/about', function(req, res) {
17
	res.render('about', {title:"About Me"});
18
});
19
20
app.get('/article/:id', function(req, res) {
21
	var entry = blogEngine.getBlogEntry(req.params.id);
22
	res.render('article',{title:entry.title, blog:entry});
23
});
24
25
app.listen(3000);

Vamos a abordar las actualizaciones una por una. (Esta versión se puede encontrar en la carpeta blog3.) En primer lugar, cargamos en nuestro motor utilizando una llamada de requerir rápido. Esto nos da la capacidad de llamarlo y obtener entradas. Puede observar una nueva línea que llama a bodyParser, pero ignorar eso por ahora.

En nuestro enrutador de página de inicio, hemos pasado un segundo argumento a la API de representación. El argumento es un objeto con dos claves, título y entradas. El valor de title es solo una cadena, pero entries llama a nuestra API blogEngine. Aquí es donde las cosas se ponen interesantes. Cualquier dato que pasemos aquí estará disponible para nuestras plantillas. Dependiendo del idioma de su plantilla, los detalles en cómo la usa pueden cambiar, pero echemos un vistazo a la página de inicio.

1
<h1>Blog!</h1>
2
3
{{#each entries}}
4
	<p>
5
		<a href="/article/{{id}}">{{title}}</a><br/>
6
		Published: {{published}}
7
	</p>
8
{{/each}}

Si usted nunca ha utilizado manillar antes, usted todavía puede tomar una buena conjetura en cuanto a lo que está pasando aquí. La directiva #each recorrerá en iteración una matriz. Dentro del bloque he usado una combinación de tokens de Handlebar que apuntan a los datos de mi blog, así como HTML para generar una lista simple de entradas de blog. Viniendo de un fondo ColdFusion, esto es muy familiar.

Creación de un diseño

Apuesto a que también te estás preguntando dónde fue el resto del HTML. Cuando se utilizan motores de plantillas en Express, se obtiene compatibilidad con el diseño automático. Eso significa que puedo crear un diseño genérico con el diseño de mi sitio y Express inyectará la salida de una página en particular dentro de ella. Por convención, esto se llama layout.something donde "algo" es la extensión particular que está utilizando. Dado que usamos HTML, esto solo será diseño.html:

1
<html>
2
3
<head>
4
	<title>{{title}}</title>
5
</head>
6
7
<body>
8
9
	{{{body}}}
10
11
	<footer>
12
		<p>
13
			<a href="/">Home</a> ~ <a href="/about">About Me</a>
14
		</p>
15
	</footer>
16
	
17
</body>
18
</html>

Bastante resbaladizo, ¿verdad? La página Acerca de no es interesante, así que la omitiremos, pero echa un vistazo a la ruta del artículo. Ahora incluye un token, :id, en la dirección URL. Express nos permite crear URL dinámicas que luego se pueden asignar a los argumentos de solicitud. Notarás que en la página de inicio, definimos enlaces que se veían así: /article/{{id}}.

En teoría, agregaríamos una ruta por cada entrada de blog que tenemos, pero es mucho mejor crear una ruta abstracta que coincida con cualquier solicitud de esa forma en particular. Para obtener acceso a este valor, también agregamos otra pieza, la línea bodyParser que definimos anteriormente. (Esta característica en particular proviene del marco de connect y en realidad proporciona bastante ayuda para admitir la cadena de consulta y los cuerpos de formulario. Casi todas las aplicaciones Express querrán incluir esto).

Visualización de artículos individuales

Debido a que obtenemos acceso al valor dinámico al final de la dirección URL, simplemente podemos pasar esto al objeto blogEngine y usar el resultado como un argumento para la vista.

Aquí está el archivo de .html artículo:

1
<h1>{{blog.title}}</h1>
2
Published: {{blog.published}}
3
4
<p/>
5
6
{{blog.body}}

Ahora tenemos una aplicación verdaderamente dinámica, pero fea. Aquí está nuestra nueva página de inicio:

express-blog3-homeexpress-blog3-homeexpress-blog3-home

Y aquí está uno de una entrada de blog en particular:

express-blog3-articleexpress-blog3-articleexpress-blog3-article

Poner un poco de lápiz labial en ese cerdo!

Vamos a agregar algunos estilos básicos a nuestra aplicación para que sea un poco más bonita. Express proporciona una manera sencilla de agregar compatibilidad con recursos estáticos como imágenes, bibliotecas de JavaScript y hojas de estilos. Simplemente definiendo una carpeta estática, cualquier solicitud de un archivo se comprobará con esa carpeta en particular antes de compararse con las rutas. Aquí hay un ejemplo de la versión final de nuestro motor de blog (que se puede encontrar en la carpeta blog4):

1
app.use(express.static('public'));

En este momento, si solicita /foo.css y el archivo foo.css existe en la carpeta pública, se devolverá. Dado que mis habilidades de diseño son tan buenas como cualquier desarrollador, tomé la salida fácil y agarré una copia de Bootstrap (https://twitter.github.io/bootstrap/). Lo dejé caer y una copia de jQuery, en mi carpeta pública.

Luego, dentro de mi diseño.html, puedo referirme a estos recursos. Aquí está un ejemplo de la vinculación en bootstrap.css:

1
<link href="/bootstrap/css/bootstrap.css" rel="stylesheet">

Express ahora buscará automáticamente este archivo dentro de la carpeta pública. Puede tener varias carpetas estáticas como esta e incluso puede configurar prefijos de URL personalizados para ellas. El resultado es - impresionante. (Ok, en comparación con la primera versión, es una gran mejora!)

La página de inicio:

express-blog4-homeexpress-blog4-homeexpress-blog4-home

Y un artículo:

express-blog4-articleexpress-blog4-articleexpress-blog4-article

¿Y ahora qué?

¿Quieres saber más? Aquí hay algunos enlaces que pueden ser útiles.

  • Obviamente, su primera parada debe ser a la página de inicio de Express.
  • Puedes unirte al grupo de Google para hablar con otros desarrolladores.
  • Si quieres estar realmente de moda, únete al canal IRC: #express.
  • Finalmente, puede ver un montón de ejemplos en GitHub.