+ All Categories
Home > Technology > ¿Cómo mantener tu javascript?: Buenas prácticas

¿Cómo mantener tu javascript?: Buenas prácticas

Date post: 05-Dec-2014
Category:
Upload: jaespinmora
View: 170 times
Download: 5 times
Share this document with a friend
Description:
Buenas práctias en el desarrollo de software con javascript. Código limpio, mantenible, escalable, tests,... Charla perteneciente al evento Betabeers Murcia del día 9 de Mayo de 2014
54
COMO MANTENER TU JAVASCRIPT: Humberto García Caballero Buenas prácticas
Transcript
Page 1: ¿Cómo mantener tu javascript?: Buenas prácticas

COMO MANTENER TU JAVASCRIPT:

Humberto García Caballero

Buenas prácticas

Page 2: ¿Cómo mantener tu javascript?: Buenas prácticas

CONTENIDOS1. Motivación.

2. Guía de estilos.

3. Prácticas de programación.

4. Automatización.

5. Conclusiones.

6. Preguntas.

7. Bibliografía.

Page 3: ¿Cómo mantener tu javascript?: Buenas prácticas

– Douglas Crockford

“JavaScript: The world's most misunderstood programming language.”

MOTIVACIÓN

Page 4: ¿Cómo mantener tu javascript?: Buenas prácticas

if (wl && wl.length) { for (i = 0, l = wl.length; i < l; ++i) { p = wl[i]; type = Y.Lang.type(r[p]); if (s.hasOwnProperty(p)) { if (merge && type == 'object') { ! Y.mix(r[p], s[p]); } else if (ov || !(p in r)) { r[p] = s[p]; } } } }

if (wl && wl.length) { ! for (i = 0, l = wl.length; i < l; ++i) { p = wl[i]; type = Y.Lang.type(r[p]); ! if (s.hasOwnProperty(p)) { if (merge && type == 'object') { Y.mix(r[p], s[p]); } else if (ov || !(p in r)) { r[p] = s[p]; } } } }

Page 5: ¿Cómo mantener tu javascript?: Buenas prácticas

GUÍA DE ESTILOS¿Por qué? Mantener el mismo estilo de código en un equipo de desarrollo es fundamental por varios motivos. Cualquier miembro del equipo puede comprender fácilmente código escrito por otro miembro, permitiendo un desarrollo más eficiente y evitando tener que gastar tiempo en comprender un estilo de código diferente. Los errores son más fáciles de detectar.

Inicialmente el equipo debería mantener una reunión para decidir cuál será su estilo de código, ya que todos los miembros tendrán sus preferencias personales y todos intentarán mantenerlas. Hay que lograr un compromiso.

Page 6: ¿Cómo mantener tu javascript?: Buenas prácticas

ESTILOS: HERRAMIENTAS

• JSLint: Desarrollado por Douglas Crockford, esta herramienta nos informa sobre errores potenciales hallados en nuestro código, así como advertencias sobre el uso de ciertos patrones de estilo no recomendados.

• JSHint: Es un derivado de JSLint mantenido por Anton Kovalyov. Ayuda a mantener las convecciones de código así como evitar errores en nuestro código JS. Mozilla, Facebook, Twitter, Bootstrap, jQuery,..., todos ellos utilizan esta herramienta, por lo que es una buena opción ya que su mantenimiento está prácticamente asegurado.

Incluir una herramienta de este tipo en nuestro proceso de construcción es una práctica muy recomendable, ya que forzamos a que se cumplan las convecciones de código, así como evitar errores potenciales (p.e. uso de eval).

Page 7: ¿Cómo mantener tu javascript?: Buenas prácticas

ESTILOS: PRINCIPALES ELEMENTOS A TENER EN CUENTA• Identación: La primera decisión a tomar es el estilo de identación. Dos alternativas: tabs o

espacios. Normalmente 4 espacios.

• Terminación de sentencias: JS permite terminar lineas con y sin ; debido al ASI (Automatic Semicolon Insertion). La recomendación aquí es insertarlo siempre, así evitaremos que el código interpretado tenga un comportamiento totalmente diferente al deseado. (Ver ejemplo siguiente). JSLint y JSHint lanzan warnings en estos casos.

• Tamaño de línea: Estrechamente relacionado con la identación. La mayoría de convecciones indican 80 caracteres por línea (Android 100). Establecer un ancho máximo evita tener que hacer scroll horizontal cada vez que queremos modificar el código, mejorando la producción.

• Rotura de líneas: Cuando una línea alcanza el máximo de caractéres, ésta debe ser dividida en dos. La norma aquí suele ser partirlas después de un operador y que la siguiente línea tenga dos niveles de identación. (ver ejemplo).

Page 8: ¿Cómo mantener tu javascript?: Buenas prácticas

• Líneas en blanco: La norma en este caso es introducir una línea en blanco para separar partes de código que no estén relacionadas, quedando el código como si fuesen párrafos en lugar de una secuencia de símbolos. Entre métodos, entre variables locales de un método y su primera sentencia, antes de un comentario, entre secciones lógicas de un método.

• Nombramiento: Se recomienda siempre utilizar el estilo propio que tenga el lenguaje de programación. En el caso de JS es camel case. Variables = nombres, funciones = verbos, objetos con capitalización.

• Constantes: En mayúsculas y con barra baja para los espacios.

Page 9: ¿Cómo mantener tu javascript?: Buenas prácticas

// Código original function getEvento() { return { event: "Betabeers Murcia VI", place: "You&Co" } }

Ejemplo: Terminación de sentencias.

// Tras el ASI, quedaría así function getEvento() { return; { event: "Betabeers Murcia VI", place: "You&Co" }; }

Page 10: ¿Cómo mantener tu javascript?: Buenas prácticas

Ejemplo: Rotura de líneas

// MAL: Sólo un nivel de identación. callAFunction(document, element, window, "some string value", true, 123, navigator);

// MAL: Línea partida antes de operador. callAFunction(document, element, window, "some string value", true, 123 , navigator);

// Bien: Después de operador seguido de dos niveles de identación. callAFunction(document, element, window, "some string value", true, 123, navigator);

Page 11: ¿Cómo mantener tu javascript?: Buenas prácticas

Ejemplo: Líneas en blanco.

if (wl && wl.length) { for (i = 0, l = wl.length; i < l; ++i) { p = wl[i]; type = Y.Lang.type(r[p]); if (s.hasOwnProperty(p)) { if (merge && type == 'object') { Y.mix(r[p], s[p]); } else if (ov || !(p in r)) { r[p] = s[p]; } } } }

if (wl && wl.length) { ! for (i = 0, l = wl.length; i < l; ++i) { ! p = wl[i]; type = Y.Lang.type(r[p]); ! if (s.hasOwnProperty(p)) { ! if (merge && type == 'object') { Y.mix(r[p], s[p]); } else if (ov || !(p in r)) { r[p] = s[p]; } } } }

Page 12: ¿Cómo mantener tu javascript?: Buenas prácticas

Ejemplo: Nombramiento.

// Bien var limite = 30; var asuntoMensaje = "Mantenimiento"; var encontrado = true; var MAX_PERSONAS = 100; !// Mal: Fácil confusión con funciones var getLimite = 10; var isEncontrado = true; !// Bien function getName() { return myName; } !// Mal: Fácil confusión con variable function theName() { return myName; }

Page 13: ¿Cómo mantener tu javascript?: Buenas prácticas

PRÁCTICAS DE PROGRAMACIÓN

Las prácticas de programación son otra convección de código, ayudándonos a resolver problemas cotidianos y estableciendo pautas para la reutilización y mantenibilidad del código.

A continuación veremos conceptos que para muchos posiblemente sean ya conocidos pero que son dignos de destacar.

Page 14: ¿Cómo mantener tu javascript?: Buenas prácticas

.box {

width: expression(document.body.offsetWidth + "px");

}

<button onClick="doSomething()" id="boton">Haz clic aquí</button>

var element = document.getElementById("boton");

elememt.style.color = "red";

element.style.float = "left";

element.innerHTML = "<strong>CLICA AQUÍ</strong>;

var boton = document.getElementById("boton");

boton.addEventListener("click", doSomething, false);

#boton {

color: "red"; float: "left";

}

// tres alternativas vistas más adelante

Page 15: ¿Cómo mantener tu javascript?: Buenas prácticas

ACOPLAMIENTO UI & LÓGICAUn factor determinante para la mantenibilidad de un proyecto es reducir el acoplamiento tanto como sea posible.

En la imagen podemos ver las capas de una aplicación web (client-side).

Siguiendo una serie de consejos podemos mantener estas capas lo más desacopladas posible.

Page 16: ¿Cómo mantener tu javascript?: Buenas prácticas

REDUCCIÓN DE ACOPLAMIENTO

• Mantener JavaScript fuera de CSS.

• Mantener CSS fuera de JavaScript.

• Mantener JavaScript fuera de HTML.

• Mantener HTML fuera de JavaScript.

Page 17: ¿Cómo mantener tu javascript?: Buenas prácticas

MANTENER HTML FUERA DE JS

Este es el punto más importante e interesante de esta sección, ya que el resto de puntos son relativamente lógicos.

En muchísimas ocasiones, ya sea por la falta de conocimiento o por comodidad, empezamos a desarrollar aplicaciones JS y empezamos a embeber código HTML en la lógica de la aplicación. Hay unas alternativas que podemos utilizar para evitarlo:

Page 18: ¿Cómo mantener tu javascript?: Buenas prácticas

• Cargar HTML desde el servidor.

• Plantillas simples en el lado del cliente.

• Plantillas complejas en el lado del cliente.

Page 19: ¿Cómo mantener tu javascript?: Buenas prácticas

function loadDialog(name, oncomplete) { ! var xhr = new XMLHttpRequest(); xhr.open("get", "/js/dialog/" + name, true); ! xhr.onreadystatechange = function() { ! if (xhr.readyState == 4 && xhr.status == 200) { var div = document.getElementById("dlg-holder"); div.innerHTML = xhr.responseText; ! oncomplete(); } else { // handle error } }; ! xhr.send(null); }

Alternativa 1

Page 20: ¿Cómo mantener tu javascript?: Buenas prácticas

<li><a href="%s">%s</a></li> !function sprintf(text) { var i=1, args=arguments; ! return text.replace(/%s/g, function() { return (i < args.length) ? args[i++] : ""; }); } !// uso var result = sprintf(templateText, "/item/4", "Fourth item");

Alternativa 2

Page 21: ¿Cómo mantener tu javascript?: Buenas prácticas

<script type="text/x-handlebars-template" id="list-item"> <li><a href="{{url}}">{{text}}</a></li> </script> !var script = document.getElementById("list-item"), templateText = script.text, template = Handlebars.compile(script.text); !var result = template({ text: "Fourth item", url: "/item/4" });

Alternativa 3

Page 22: ¿Cómo mantener tu javascript?: Buenas prácticas

GLOBALIZACIÓNEl entorno de JavaScript tiene su ejecución asociada a un objeto global (en los navegadores web window).

Por lo tanto, cualquier variable definida fuera de una función se considera una variable global.

Page 23: ¿Cómo mantener tu javascript?: Buenas prácticas

var numero = 6; !function mostrarNumero() { alert(numero); } !alert(window.numero); //=> 6 alert(typeof window.getNumero); //=>"function"

fichero1.js ...

ficheroN.js

Page 24: ¿Cómo mantener tu javascript?: Buenas prácticas

• Entre los problemas de la globalización podemos nombrar los siguientes:

• Colisión de nombres.

• Fragilidad del código.

• Dificultad en el testeo.

• Globales accidentales.

Page 25: ¿Cómo mantener tu javascript?: Buenas prácticas

AUTOMATIZACIÓN• Primeras páginas web sólo contenían algunos ficheros JS, los scripts eran

desarrollados por una persona.

• Hoy en día las aplicaciones web contienen gran cantidad de scripts, con miles de líneas de código programadas, en ocasiones, por más de una docena de programadores.

• Con este contexto, las metodologías utilizadas hace años dejan de servir.

• Incluir JS en los procesos de automatización es un paso muy importante para conseguir proyectos que puedan ser mantenidos.

Page 26: ¿Cómo mantener tu javascript?: Buenas prácticas

VENTAJAS• El código de desarrollo no

tiene que estar "reflejado" en el entorno de producción.

• Pueden ser ejecutados análisis automáticos para detectar fallos o errores.

• Procesamiento de los ficheros JS.

• Fase de testeo es automatizada.

• Desplegado en los servidores de producción es sencillo.

• Tareas comúnes pueden ser ejecutadas numerosas veces de manera sencilla.

• Desarrolladores podrían necesitar ejecutar un "build" mientras hacen cambios en entornos de desarrollo. (Preferencia por refrescar en el navegador).

• El código de producción no es exactamente como el desarrollado. Seguimiento de bugs.

• Desarrolladores menos técnicos podrían tener problemas usando los sistemas de construcción.

DESVENTAJAS

Page 27: ¿Cómo mantener tu javascript?: Buenas prácticas

AUTOMATIZACIÓN: ESTRUCTURA DE DIRECTORIO Y FICHERO

El primer paso es establecer una estructura de directorios y ficheros. La estructura dependerá directamente del tipo de proyecto que estemos desarrollando. Esta etapa es importante ya que el proceso de construcción dependerá directamente de la organización de ficheros y directorios, por lo que tener una estructura lógica es fundamental.

Page 28: ¿Cómo mantener tu javascript?: Buenas prácticas

INDEPENDIENTE AL TIPO DE PROYECTO...

• Un objeto por archivo: Al igual que otros lenguajes de programación. Reduce el riesgo de trabajar varias personas en el mismo fichero.

• Agrupar archivos relacionados en directorios: Si existen objetos relacionados es aconsejable mantenerlos en un mismo directorio (p.e. Utilidades)

• Mantener librerías separadas del código: Cualquier código no desarrollado por nosotros debería mantenerse apartado del nuestro. De hecho, lo ideal es hacer uso de un CDN.

• Determinar la ruta de construcción: Debe ser un directorio completamente separado del directorio fuente, ya que este no debería ser tenido en cuenta en ningún chequeo u otro proceso automatizado.

• Mantener código de testeo cerca: Esto ayuda a los desarrolladores a echar en falta cualquier código de testeo que todavía no haya sido implementado.

• En cualquier caso: son recomendaciones, la estructura debe ser decidida por el equipo de desarrollo ya que en muchos casos dependeremos del framework utilizado en el lado del servidor.

Page 29: ¿Cómo mantener tu javascript?: Buenas prácticas

LAYOUT BÁSICOUn layout básico suele ser el siguiente:

• build: Para los ficheros construidos finales.

• src: Para todos los ficheros desarrollados, conteniendo subdirectorios.

• test o tests: Para todos los tests de nuestra aplicación.

Page 30: ¿Cómo mantener tu javascript?: Buenas prácticas

CSSLint

jQuery

YUI3

Page 31: ¿Cómo mantener tu javascript?: Buenas prácticas

ANTLa elección de un sistema de construcción depende de las herramientas con las cuales los desarrolladores sean más familiares. Ya que las aplicaciones web suelen ir acompañadas de un back-end (posiblemente) desarrollado en Java, esta herramienta resulta muy apropiada para la tarea en cuestión. Aunque hay muchas alternativas a día de hoy, nosotros nos vamos a centrar en esta herramienta por su larga trayectoria y su sencillo uso.

Nos centraremos en la construcción de JavaScript, pero las técnicas vistas podrían ser aplicadas a otros lenguajes.

Page 32: ¿Cómo mantener tu javascript?: Buenas prácticas

En primer lugar, lo básico:

• task: Es un paso del proceso (p.e. copiar archivos, ejecutar un comando, etc).

• target: Un grupo de tareas con un orden secuencial.

• project: Contenedor de todo lo anterior.

Page 33: ¿Cómo mantener tu javascript?: Buenas prácticas

<project name="betabeers" default="hello"> <target name="hello"> <echo>Hello world!</echo> </target> <target name="goodbye" depends="hello"> <echo>Goodbye world!</echo> </target> </project>

Ejemplo de build.xml

Page 34: ¿Cómo mantener tu javascript?: Buenas prácticas

En nuestro fichero de construcción podemos necesitar cierta información como, por ejemplo, el directorio src de nuestro código, el directorio que contiene las librerías o el directorio resultante del fichero JavaScript final.

Toda esta información puede definirse mediante propiedades y ser cargadas posteriormente desde nuestro fichero de construcción.

Page 35: ¿Cómo mantener tu javascript?: Buenas prácticas

PROPIEDADES !

version = 0.1.0 src.dir = ./src lib.dir = ./lib build.dir = ./build

CARGAR PROPIEDADES !

<project name="betabeers" default="version"> <loadproperties srcfile="build.properties" /> <target name="version"> <echo>La version es ${version}</echo> </target> </project>

Page 36: ¿Cómo mantener tu javascript?: Buenas prácticas

VALIDACIÓN• JavaScript no es un lenguaje compilado, por lo que

los desarrolladores no tienen la información que proporciona ese paso.

• Añadiremos JSHint (visto anteriormente) a nuestro proceso de construcción.

Page 37: ¿Cómo mantener tu javascript?: Buenas prácticas

• Encontrar archivos a validar : <fileset> & <filelist>.

• Ejecutar JSHint a través de Rhino.

• Detener la construcción en caso de error.

Page 38: ¿Cómo mantener tu javascript?: Buenas prácticas

<target name="validate"> <apply executable="java" failonerror="true" parallel="true"> <fileset dir="${src.dir}" includes="**/*.js" /> <arg line="-jar"/> <arg path="${rhino}"/> <arg path="${jshint}" /> <arg line="${jshint.options}" /> <srcfile/> </apply> </target>

src.dir = ./src lib.dir = ./lib rhino = ${lib.dir}/js.jar jshint = ${lib.dir}/jshint.js jshint.options = curly=true,forin=true,latedef=true,noempty=true,undef=true\ ,rhino=false

Page 39: ¿Cómo mantener tu javascript?: Buenas prácticas

CONCATENACIÓN Y "BAKING"

• Si hemos seguido la recomendación de un objeto por archivo, tendremos docenas de ficheros.

• La concatenación reduce peticiones al servidor, reduciendo así el overhead producido por las cabeceras HTTP.

• Cada proyecto tendrá su propia directiva a la hora de concatenar los ficheros, veremos que con Ant es una tarea bastante sencilla de realizar.

Page 40: ¿Cómo mantener tu javascript?: Buenas prácticas

CONCATENACIÓN: PASOS• Encontrar ficheros a concatenar, teniendo en

mente cuál debería ser su orden.

• Determinar el fin de línea.

• ¿Necesitamos cabeceras o pie de página?

Page 41: ¿Cómo mantener tu javascript?: Buenas prácticas

<target name="concatenate"> <concat destfile="${build.dir}/build.js" fixlastline="yes" eol="lf"> <header>/* Build Time: ${build.time} */</header> <filelist dir="${src.dir}" files="first.js,second.js" /> <fileset dir="${src.dir}" includes="**/*.js" excludes="first.js,second.js"/> </concat> </target>

<tstamp> <format property="build.time" pattern="dd/MM/yyyy hh:mm:ss" locale="es,ES"/> </tstamp>

Page 42: ¿Cómo mantener tu javascript?: Buenas prácticas

BAKING: DESCRIPCIÓN Y PASOS

• Esta etapa de la construcción puede ser util para añdir información de licencias o reemplazar cierto texto en nuestros ficheros JS.

• El ejemplo visto anteriormente es un tipo de baking.

• Lo veremos más claro con el siguiente ejemplo.

Page 43: ¿Cómo mantener tu javascript?: Buenas prácticas

// Javascript var MyProject = { version: "@VERSION@" }; !// Ant <target name="bake"> <replaceregexp match="@VERSION@" replace="${version}" flags="g" byline="true"> <fileset dir="${build.dir}" includes="**/*"/> </replaceregexp> </target>

Page 44: ¿Cómo mantener tu javascript?: Buenas prácticas

MINIMIZACIÓN & COMPRESIÓN

La minimización y compresión son los últimos pasos mas relevantes de la construcción. La minimización consiste en eliminar espacios en blanco, comentarios y realizar algunas mejoras en los ficheros para hacerlos tan pequeños como sea posible.

Por otro lado podemos comprimir los ficheros (gzip, etc).

Page 45: ¿Cómo mantener tu javascript?: Buenas prácticas

276 KB

Page 46: ¿Cómo mantener tu javascript?: Buenas prácticas

93,54 KB

Page 47: ¿Cómo mantener tu javascript?: Buenas prácticas

MINIMIZACIÓNHay dos tipos: con parseo de código o mediante expresiones regulares. Los primeros son más seguros y suelen producir menor número de fallos de sintaxis.

• YUI Compressor: Julien Lecomte.

• Closure compiler : Google engineers.

• UglifyJS : Mihai Bazon.

Page 48: ¿Cómo mantener tu javascript?: Buenas prácticas

COMPRESIÓNUna vez los ficheros han sido minimizados es hora de comprimirlos para transmitir el menor número de bytes como sea posible.

• Compresión en tiempo de ejecución.

• Compresión en tiempo de construcción.

Page 49: ¿Cómo mantener tu javascript?: Buenas prácticas

UNIENDO PIEZASEl proceso de construcción debería tener, al menos, tres targets diferentes:

• Develop: Target ejecutado en la etapa de desarrollo.

• Integration: Target ejecutado por el CI.

• Production: Target ejecutado al realizar un release.

Page 50: ¿Cómo mantener tu javascript?: Buenas prácticas

UNIENDO PIEZAS: PASOS1. Limpiar directorio build. (Elimiar). 2. Crear directorio build. 3. Develop:

1. Validación. 2. Concatenación.

4. Integration:

1. Minificación. 2. Testeo. 3. Documentación.

5. Release:

1. Baking.

Page 51: ¿Cómo mantener tu javascript?: Buenas prácticas

<project name="JS" default="build.dev"> <loadproperties srcfile="JS.properties" /> !<target name="init">

<mkdir dir="${build.dir}"/> </target> !<target name="clean">

<delete dir="${build.dir}"/> </target> !<target name="build.dev" depends="clean,init,validate,concatenate"> </target> !<target name="build.int depends="build.dev,minify,test,document"> </target> !<target name="build.release" depends="build.int,bake"> </target>

</project>

Page 52: ¿Cómo mantener tu javascript?: Buenas prácticas

CONCLUSIONESEl mantenimiento de un proyecto software es determinante, tanto para los propios desarrolladores, como para la entidad para la que trabajen, ahorrando tiempo, esfuerzo y dinero.

Hay numerosas alternativas y elegir las apropiadas es igual de determinante.

Siguiendo una serie de consejos sencillos, podemos aumentar nuestra productividad y ser más eficientes, mejorando así nuestra faceta profesional.

Page 53: ¿Cómo mantener tu javascript?: Buenas prácticas

¿PREGUNTAS?

Page 54: ¿Cómo mantener tu javascript?: Buenas prácticas

BIBLIOGRAFÍA• C. Zakas, Nicholas. (2012). Maintainable JavaScript. O'Reilly Media, Inc.

• Crockford, Douglas. (2001). JavaScript: The world's most misunderstood programming language. Recuperado de www.javascript.crockford.com/javascript.html

• jQuery Foundation. (2014). jQuery. Recuperado de http://jquery.com/


Recommended