Introduccion a Full-Stack JavaScript
Indice
¿Que es?
Lenguajes en un Stack web tipico
Lenguajes en Full-Stack JavaScript
Ventajas
Se reduce el numero de lenguajes.
Menos lenguajes que aprender para novicios y menos lenguajes que gestionar en general.
Reutilización de recursos, tanto programadores como código.
Cuidado con esto, no hay que limitar al servidor a funciones de un navegador.
Programación no bloqueante o asíncrona en el servidor, de forma nativa, sin librerías externas solo con el event loop de JavaScript.
La CPU se mantiene ocupada y se ahorra memoria.
Comunidad.
JS es uno de los lenguajes de programación mas usados del mundo, es muy fácil encontrar librerías y herramientas (...y StackOverflow).
Servidor
Ejemplo de uso
Estándar de facto para el desarrollo de aplicaciones web en Node
Express es a Node lo que Ruby on Rails es a Ruby
Hola Mundo
var express = require('express'); var app = express(); app.get('/hello.txt', function(req, res){ res.send('Hello World'); });
var server = app.listen(3000, function() { console.log('Listening on port %d', server.address().port); });
Middleware
Middleware
app.use(function(req, res, next){ console.log('First middleware'); });
app.use(function(req, res, next){ console.log('Second middleware'); });
app.get('/', function(req, res){
console.log('End middleware');
res.send('Page render here'); });
Usos del middleware:
- Loggers
- Servir archivos estáticos
- Gestión de errores
Koa es un framework web, desarrollado por el equipo detrás de Express.
La idea es mejorar el uso de middleware y la gestión de errores usando generadores (definidos en EcmaScript 6).
Los generadores permiten especificar un punto en una función donde se interrumpe la ejecución y se devuelve un valor.
foofunction foo(x){ while(true){
x = x * 2;
yield x;
}
});
var bar = foo(2);
bar.next(); // -> 4
bar.next(); // -> 8
bar.next(); // -> 16
En Koa la palabra clave yield pasa el flujo de control al siguiente middleware. Cuando la ejecución acabe el flujo de control ira retornando hacia arriba.
Esto permite una mejor gestión de errores usando try/catch en vez de pasar los errores como parámetro en el callback.
app.use(function *(next){
var start = new Date;
yield next;
var ms = new Date - start;
this.set('X-Response-Time', ms + 'ms');
});
app.use(function *(next){
var start = new Date;
yield next;
var ms = new Date - start;
this.set('X-Response-Time', ms + 'ms');
});
Un motor para comunicación en tiempo real.
Cuando hacemos aplicaciones web no tenemos demasiadas opciones para comunicación en tiempo real ya que el cliente no puede recibir información sin petición previa.
Socket.IO proporciona una librería para el servidor y el cliente que permite comunicación bidireccional en tiempo real en aplicaciones web.
WebSockets
Socket.IO proporciona una API un nivel por encima de esta tecnología. Si es posible usara WebSockets, pero sino buscara otro método, de forma transparente para el desarrollador.
Servidor
io.on('connection', function(socket){
socket.on('chat message', function(msg){
io.emit('chat message', msg);
});
});
Cliente
var socket = io();
$('form').submit(function(){
socket.emit('chat message', $('#m').val());
$('#m').val('');
return false;
});
socket.on('chat message', function(msg){
$('#messages').append($('<li>').text(msg));
});
MongoDB es la base de datos NoSQL mas usada en la actualidad. Es flexible, escalable y fácil de usar.
Mongo esta una BD orientada a documentos.
Guarda documentos en formato BSON (Binary JSON). Ademas, el shell de mongo es en esencia un interprete de JavaScript.
Debido a esto, se usa MongoDB en Full-Stack JavaScript, para conseguir una BD en "JavaScript".
var MongoClient = require('mongodb').MongoClient;
MongoClient.connect("mongodb://localhost:27017/exampleDb", function(err, db) {
if(err) { return console.dir(err); }
var collection = db.collection('test');
var doc1 = {'hello':'doc1'};
var doc2 = {'hello':'doc2'};
var lotsOfDocs = [{'hello':'doc3'}, {'hello':'doc4'}];
collection.insert(doc1);
collection.insert(doc2, {w:1}, function(err, result) {});
collection.insert(lotsOfDocs, {w:1}, function(err, result) {});
});
Mongoose
var mongoose = require('mongoose'); mongoose.connect('mongodb://localhost/test'); var Cat = mongoose.model('Cat', { name: String }); var kitty = new Cat({ name: 'Zildjian' }); kitty.save(function (err) { if (err) // ... console.log('meow'); });
Cliente
JQuery esta bien para pequeños scripts en una web.
A medida que las RIA (Rich Internet Application) crecen se vuelven mas complejas y terriblemente difíciles de gestionar.
Hace falta estructura.
Framework de código abierto para el desarrollo de aplicaciónes web de una sola página (Single Page Applications).
Está basado en un modelo vista controlador (MVC).
Ejemplo de uso
Frameworks
Full-Stack
De todas las mencionadas, Meteor es la única herramienta que realmente sigue el paradigma FullStack JavaScript.
Es un framework para construir aplicaciones web en tiempo real que actúa tanto en el cliente como en el servidor.
Aunque esta basada en Node no tiene nada que ver con ello. Por ello, no se pueden usar librerías de node en meteor.
Estructura de proyectos
Un proyecto de meteor tiene como mínimo dos carpetas: client y server.
El código en client solo se ejecuta en el cliente, mientras que server solo se ejecuta en el servidor. El resto se ejecuta en ambos.
En meteor NO hay que importar ficheros de JavaScript con require ni incluir scripts en los documentos HTML. El motor se encarga de buscar todos los ficheros JS que hayamos creado y ejecutarlos.
El framework usa una base de datos MongoDB, que se mantendra actualizada en tiempo real de forma transparente.
Para manejar los datos se crean colecciones, conjuntos de datos persistentes que actúan de forma diferente en el servidor y en el cliente.
Una colección en el servidor es una representación de un conjunto de datos que existe en la base de datos.
El servidor publica diferentes colecciones (por ejemplo, todas las imágenes subidas por una determinada persona), que serán accesibles por los clientes.
Una colección en el cliente es una especie de cache de los datos que corresponden en el servidor.
Cuando hay cambios en las colecciones en el navegador (hechos mediante operaciones idénticas a las que se pueden realizar en un shell de mongo) los cambios se actualizan en el servidor y en otros navegadores abiertos instantáneamente y automáticamente.
No hay que preocuparse de la comunicación cliente / servidor, es automática.
Yeoman
Ayuda a la generación de la estructura básica de diversos tipos de proyectos.
Para ello, usa unos plugins llamados generators que al ser ejecutados con el comando yo generan el proyecto.
- generator angular
- generator chromeapp
- generator angular-fullstack
yo angular-fullstack
Build Systems
Package Managers
- NPM: el gestor de paquetes de NodeJS.
- Bower: gestor de paquetes para el front-end de las aplicaciones.
Creacion de un foro usando un MEAN stack
Instalar herramientas
Node
sudo add-apt-repository ppa:chris-lea/node.js
sudo apt-get update
sudo apt-get install nodejs
Node package manager
sudo apt-get install npm
Yeoman
sudo npm install -g yo
Generador angular-fullstack
sudo npm install -g generator-angular-fullstack #generador
Ubuntu puede encontrarse con un problema de la version de yeoman, para solucionarlo:
sudo npm rm -g yo
npm cache clean
sudo npm install -g yo
sudo rm /usr/local/bin/yo
sudo ln -s /usr/lib/node_modules/yo/cli.js /usr/local/bin/yo
Otro posible problema es que bower o npm sean incapaces de bajar librerias de github. Para solucionarlo:
git config --global url."https://".insteadOf git://
Generar el proyecto
yo angular-fullstack
¿Que nos ha creado?
Comandos
Servidor
Node: Require
Node: Modulos
module.exports.holamundo = function(){
console.log('hola mundo');
}
//Require en otro fichero
var miModulo = require(nombreFichero);
miModulo.holamundo(); //hola mundo
API
Modelo
Mongoose
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var ThreadSchema = new Schema({
title: String,
author: { type: Schema.types.ObjectId, ref: 'User' },
posts: [{ type: Schema.types.ObjectId, ref: 'Post' }]
});
module.exports = mongoose.model('Thread', ThreadSchema);
Tambien se pueden definir validaciones, atributos virtuals y funciones a llamar antes o despues de realizar una operacion.Controladores
Controladores
Thread.find().populate('author').exec(function (err, threads) {if(err) { return handleError(res, err); }return res.json(200, threads);});
Controladores
Request
Response
Router
app.use('/api/threads', threadRouter);
Router
Servidor
Client
- index.html: El html principal donde se referencian todos los scripts externos y se va insertando el html correspondiente a cada estado.
- assets: carpeta donde se almacena todos los archivos estáticos: imágenes, archivos para traducir, etc.
- bower_components: carpeta donde se "instalan" todos los elementos definidos en el archivo bower.json.
- components: almacena alguno de los elementos generados automáticamente por el generador de angular-fullstack: auth, mongoose-error, nabvar y socket.
- app: donde se va a ir programando toda la lógica del cliente.
Client/app
- app.js: el "corazón" del cliente en AngularJS, es donde se definen todas las dependencias de AngularJS y su configuración inicial.
- ngCookies: módulo para crear y leer cookies.
- ui.bootstrap: módulo para añadir las funcionalidades de UI-Boostrap .
- ui.router: módulo para manejar la aplicación de AngularJS mediante estados en lugar de rutas.
- ngResource: módulo que permite hacer llamadas REST a la API.
- ngSanitize: módulo para hacer transformar strings en código HTML.
//Permite a angular cambiar las urls de las páginas sin tener que refrescar la página
$locationProvider.html5Mode(true);
//Sistema para comprobar si el usuario está logeado
$httpProvider.interceptors.push('authInterceptor');
Gestión de estados o URLs con UI-Router
Directivas
- ngRepeat: repetir un elemento HTML y todos sus hijos una vez por cada elemento que hay en el array.
- ngShow: si la expresión booleana dada es verdadera, visualiza el elemento HTML. (Usando CSS)
- ngHide: si la expresión booleana dada es verdadera, oculta el elemento HTML. (Usando CSS)
- ngIf: si la expresión booleana dada es verdadera, visualiza el elemento HTML. (Cuando es falso directamente lo elimina del DOM).
- ngClick: vincula un click en el elemento HTML con una función del controlador
- ngChange: cada vez que el valor de un input cambia, llama a una función.
- ngModel: vincula un dato del scope con el elemento HTML.
- ngController: añade un controlador a todos los hijos del elemento HTML.
Controller
Service
Factory
Componentes externos
-
Angular-SnapJS
- Angular-DragDrop
- Angular-Translate: tutorial muy completo.
- FlowJS: para subir archivos.
Introduccion a Full-Stack Javascript
By Aimar Rodriguez
Introduccion a Full-Stack Javascript
- 2,458