front end: herramientas y entorno ux

67
FRONT-END: HERRAMIENTAS Y ENTORNO UX Entorno de automatización para el trabajo en proyectos orientados a AngularJS Versión: 1.6 / Fecha: 21/12/2016

Upload: jose-maria-aparicio-gijon

Post on 13-Apr-2017

195 views

Category:

Education


5 download

TRANSCRIPT

Page 1: Front End: Herramientas y Entorno UX

FRONT-END:HERRAMIENTAS Y ENTORNO UX

Entorno de automatización para el trabajo en proyectos orientados a AngularJS

Versión: 1.6 / Fecha: 21/12/2016

Page 2: Front End: Herramientas y Entorno UX

CONTROL DE VERSIONES

Versión Fecha de Actualización Comentarios

0.1 09/11/2016 Creación del documento inicial

0.2 14/11/2016 Documentación de la sesión 1 del curso

0.3 15/11/2016 Documentación de la sesión 2 del curso

0.4 16/11/2016 Documentación de la sesión 3 del curso

0.5 17/11/2016 Documentación de la sesión 4 del curso

0.6 18/11/2016 Documentación de la sesión 5 del curso

0.7 21/11/2016 Documentación de la sesión 6 del curso

0.8 22/11/2016 Documentación de la sesión 7 del curso

0.9 23/11/2016 Documentación de la sesión 8 del curso

1.0 24/11/2016 Documentación de la sesión 9 del curso

1.1 25/11/2016 Completado de la documentación final del curso

1.2 15/12/2016 Añadida la sección de configuración del editor y correcciones varias

1.3 16/12/2016 Añadido el punto para la corrección de errores en procesado SASS

1.4 16/12/2016 Añadida configuración de puertos en BrowserSync

1.5 19/12/2016 Añadida sección para generar la guía de estilos

1.6 21/12/2016 Añadida referencia de consulta para la sintaxis de Markdown

Doc.: document.docx Título: Front-End - Herramientas y Entorno UXVersión: 1.6Fecha: 21/12/2016

Página 2 de 47

Page 3: Front End: Herramientas y Entorno UX

I N D I C E

1. Composición del entorno............................................................................................................................... 51.1. Ventajas del entorno de desarrollo.......................................................................................61.2. ¿Qué es NodeJS?...................................................................................................................61.3. ¿Qué es NPM?.......................................................................................................................61.4. ¿Qué es Bower?....................................................................................................................71.5. ¿Qué es Gulp?.......................................................................................................................71.6. ¿Qué es PUG?........................................................................................................................81.7. ¿Qué es SASS?......................................................................................................................81.8. Editores y requisitos mínimos...............................................................................................8

2. Creación de entorno base del proyecto......................................................................................................102.1. Instalación y configuración de Visual Studio Code..............................................................102.2. Instalación de Node, Git y configuración de proxy..............................................................122.3. Creación de configuración NodeJS.......................................................................................142.4. Creación de configuración Bower........................................................................................152.5. Instalación de paquete gulp y plugins para gulpfile básico.................................................162.6. Creación de la estructura del proyecto...............................................................................17

3. Procesado de HTML..................................................................................................................................... 183.1. Instalación de PUG..............................................................................................................183.2. Buenas prácticas en HTML..................................................................................................183.3. Creación de tarea de procesado PUG en Gulpfile.js............................................................19

4. Procesado de CSS........................................................................................................................................ 204.1. Instalación de SASS.............................................................................................................204.2. Buenas prácticas en SASS...................................................................................................204.3. Creación de tarea de procesado SASS en Gulpfile.js...........................................................20

5. Procesado de JS........................................................................................................................................... 225.1. Buenas prácticas en JS........................................................................................................225.2. Creación de tarea de procesado JS......................................................................................23

6. Procesando librerías de terceros................................................................................................................246.1. Instalación de USEREF........................................................................................................246.2. Creación de tarea de procesado USEREF............................................................................246.3. Instalación de librerías jquery y bootstrap mediante Bower................................................246.4. Uso de build useref dentro del código HTML.......................................................................25

7. Automatización de HTML, CSS y JS...........................................................................................................267.1. Instalación de Gulp Watch...................................................................................................267.2. Creación de tarea de escucha para el procesado automático de PUG, SASS y JS................267.3. Corrección de errores en procesado de SASS.....................................................................27

8. Servidor en vivo............................................................................................................................................ 28

Doc.: document.docx Título: Front-End - Herramientas y Entorno UXVersión: 1.6Fecha: 21/12/2016

Página 3 de 47

Page 4: Front End: Herramientas y Entorno UX

8.1. Instalación de BrowserSync................................................................................................288.2. Creación de tarea para servir estáticos...............................................................................288.3. Testing de eventos multidispositivo mediante browsersync...............................................308.4. Configuración de consola BrowserSync...............................................................................30

9. Preparación del entorno para distribución y metodología.......................................................................349.1. Minificado de librerías de terceros......................................................................................349.2. Creación de tareas de metodología.....................................................................................34

9.2.1. Metodología en CSS mediante CSSLint..........................................................................................................35

9.2.2. Compatibilidad de CSS3 con Autoprefixer.......................................................................................................36

9.2.3. Metodología en JS mediante JSHint................................................................................................................36

9.3. Creación de tareas adicionales...........................................................................................389.3.1. Tareas de copiado de ficheros.........................................................................................................................38

9.3.2. Tareas de limpiado de ficheros.........................................................................................................................39

9.3.3. Watchers para copiado de ficheros..................................................................................................................40

9.4. Completado de tareas de distribución.................................................................................419.4.1. Completado de la tarea SASS..........................................................................................................................41

9.4.2. Completado de la tarea COPY.........................................................................................................................42

9.4.3. Creación de tarea DIST:TEST..........................................................................................................................42

9.4.4. Creación de tarea DIST:ZIP.............................................................................................................................43

10.Creación de guía de estilos......................................................................................................................... 4410.1. Instalación del plugin y tareas gulp.............................................................................4410.2. Creación de estructura y estilos mediante KSS...........................................................46

Doc.: document.docx Título: Front-End - Herramientas y Entorno UXVersión: 1.6Fecha: 21/12/2016

Página 4 de 47

Page 5: Front End: Herramientas y Entorno UX

1. Composición del entornoEl objetivo de la creación del entorno para proyectos UX, es disponer de una serie de herramientas de

automatización, preprocesado y minificación para poder comenzar cualquier proyecto de UX de forma fácil

siguiendo una serie de metodologías ágiles, que facilitarán el desarrollo de proyectos y proveerán de una

base de conocimientos para trabajar con proyectos modernos como los basados en AngularJS.

La base sobre la que se ha partido para la creación del entorno:

NODE como base para todo el proyecto.

GULP como sistema de automatización de tareas.

BROWSERSYNC como servidor de aplicaciones 'en vivo'.

PUG como lenguaje de plantillas para generar el código HTML.

SASS como lenguaje para el preprocesado de CSS.

SASS + AUTOPREFIXER para dar soporte de vendor prefixes a los navegadores que elijamos.

SASS + CSSLINT para asegurar que se utiliza CSS con buenas prácticas.

JS + JSHINT para asegurar las buenas prácticas en código JavaScript.

USEREF para unificar y minimizar CSS/JS de terceros.

MINIFICADORES tanto para CSS como JS, para optimizar el rendimiento y peso del proyecto.

IMAGEMIN para optimizar el tamaño de las imágenes

SC5-STYLEGUIDE para generar la guía de estilos

PRESENTACIÓN

Doc.: document.docx Título: Front-End - Herramientas y Entorno UXVersión: 1.6Fecha: 21/12/2016

Página 5 de 47

Page 6: Front End: Herramientas y Entorno UX

1.1. Ventajas del entorno de desarrollo

La principal ventaja de disponer de un entorno de desarrollo basado en gulp es la total y completa

automatización de las tareas, para que una vez hayamos definido las tareas que vamos a necesitar,

sólo tengamos que preocuparnos de desarrollar nuestra aplicación. De modo que con una serie de

tareas analizaremos la calidad del código, optimizaremos la entrega y las dependencias del

proyecto de una forma muy sencilla y transparente para del desarrollador.

También facilita la tarea de desarrollo colaborativo, ya que sólo tenemos que subir nuestra carpeta

src y los ficheros de configuración a un repositorio de control de versiones. Así cualquiera que

descargue el proyecto solo tiene que ejecutar los comandos de instalación npm install && bower install y se instalarán todas las dependencias de plugins node y bower que hemos configurado

para nuestro proyecto.

1.2. ¿Qué es NodeJS?

Node.js es un entorno Javascript del lado del servidor, basado en eventos. Node ejecuta javascript

utilizando el motor V8, desarrollado por Google para uso de su navegador Chrome. Aprovechando

el motor V8 permite a Node proporciona un entorno de ejecución del lado del servidor que compila y

ejecuta javascript a velocidades increíbles. El aumento de velocidad es importante debido a que V8

compila Javascript en código de máquina nativo, en lugar de interpretarlo o ejecutarlo como

bytecode. Node es de código abierto, y se ejecuta en Mac OS X, Windows y Linux.

JavaScript es un sólo un lenguaje de programación del lado del cliente que se ejecuta en el

navegador, ¿verdad?. Ahora ya no. Node.js es una forma de ejecutar JavaScript en el servidor,

entre otros tantos usos que le podemos dar.

1.3. ¿Qué es NPM?

NPM o Node Package Manager es el gestor de paquetes de node, con el instalamos cualquier

plugin desarrollado bajo la arquitectura Node que requiera nuestro proyecto de forma sencilla.

Además, su principal ventaja es que incorpora un gestor de dependencias, pues cada vez que

instalamos un plugin podemos indicarle que lo guarde como dependencia de nuestro proyecto.

Por defecto cuando instalamos un paquete y lo guardamos como dependencia, npm se encarga de

instalar el paquete de la misma rama, es decir si instalamos gulp 3.9.1 y lo guardamos como

dependencia, siempre que no cambie de rama en la información del paquete, instalará la última

versión de la rama, Ej.: gulp 3.9.2, gulp 3.9.3, pero no gulp 3.10.0.

Para instalar las dependencias especificadas en el proyecto (package.json):npm install

Doc.: document.docx Título: Front-End - Herramientas y Entorno UXVersión: 1.6Fecha: 21/12/2016

Página 6 de 47

Page 7: Front End: Herramientas y Entorno UX

Para instalar un paquete de forma global (accesible desde cualquier directorio)npm install -g nombrepaquete

Para instalar un paquete sólo en nuestro proyecto:npm install nombrepaquete

Para instalar un paquete en nuestro proyecto y guardarlo como dependencia:npm install nombrepaquete --save

npm install nombrepaquete --save-dev

Para instalar un paquete y guardar como dependencia la versión exacta:npm install nombrepaquete --save --save-exact

Para instalar una version concreta de un paquete:npm install nombrepaquete@version

Por último, si queremos actualizar el paquete y su dependencia en nuestro package.json, sólo

tenemos que realizar de nuevo npm install --save ó --save-dev y guardará la dependencia en la

última versión de su rama.

Repositorio de paquetes de Node/NPM: https://www.npmjs.com/

1.4. ¿Qué es Bower?

Bower es un plugin de Node para gestión de dependencias, para librerías y frameworks JS/CSS

tales como jQuery, AngularJS, Bootstrap, etc… Al igual que NPM, cuando instalamos una librería de

bower, podemos especificar que la guarde como dependencia del proyecto a la vez que se instala.

Repositorio de paquetes de Bower: https://bower.io/search/

1.5. ¿Qué es Gulp?

Gulp es una herramienta ‘task runner’, sirve para automatizar tareas. Mediante Gulp se define cómo

deben ejecutarse esas tareas.

Estas herramientas construyen estructuras y tareas comunes para todos los desarrolladores.

El uso típico incluiría:

Compilación de CSS y JavaScript preprocesado.

Concatenación.

Minificación.

Lanzar un servidor para la recarga automática en el browser.

Creación de una build para despliegue.

Doc.: document.docx Título: Front-End - Herramientas y Entorno UXVersión: 1.6Fecha: 21/12/2016

Página 7 de 47

Page 8: Front End: Herramientas y Entorno UX

1.6. ¿Qué es PUG?

Es conocido como un Template Engine, si pudieras compararlo con algo, sería como un pre-

procesador HTML muy parecido a los que usamos para facilitarnos la vida con CSS (SASS, Less,

Stylus…). Está implementado en JavaScript para trabajar de la mano con NodeJS ofreciendo a los

desarrolladores una forma dinámica, eficaz y expresiva para generar nuestro código en corto tiempo

y con menos líneas de código.

Ventajas:

No hay etiquetas de cierre

Uso de indentación (sangría) para la jerarquía

Apoyo de JavaScript y otras herramientas

Sistema de layouts, includes y extensiones de templates

Posibilidad de generación dinámica de pug mediante JS así como carga asíncrona

mediante AMD.

Posibilidad de escoger el formato del código generado (minificado o completo)

Generación de HTML perfectamente indentado y legible.

1.7. ¿Qué es SASS?

Sass es un lenguaje de preprocesado de CSS. La principal ventaja de SASS es la posibilidad de

convertir los CSS en algo dinámico. Permite trabajar mucho más rápido en la creación de código

con la posibilidad de crear funciones que realicen ciertas operaciones matemáticas y reutilizar

código gracias a los mixins, extensiones de clases y variables que nos permiten guardar valores.

Sus principales ventajas:

Permite convertir el código CSS en modular, facilitando enormemente el mantenimiento del

proyecto.

Permite crear código anidado (nested), ayudando así a diferenciar unos elementos de otros

gracias a su nivel de anidamiento (herencia).

Uso de variables y funciones avanzadas (mixins).

1.8. Editores y requisitos mínimos.

A la hora de editar cualquier archivo de configuración o fuente de nuestro proyecto podemos utilizar

cualquier editor que soporte SASS, PUG y JavaScript. En realidad podemos utilizar cualquier editor,

pero se recomienda que disponga de la correcta identificación y coloreado de elementos para

Doc.: document.docx Título: Front-End - Herramientas y Entorno UXVersión: 1.6Fecha: 21/12/2016

Página 8 de 47

Page 9: Front End: Herramientas y Entorno UX

dichos lenguajes, pues de lo contrario perdemos una de las ventajas principales del uso de dichos

lenguajes: La facilidad de lectura del código.

Principalmente se recomienda la utilización de Visual Studio Code. Optamos por el, debido

principalmente a que de serie trae el soporte de lenguajes que necesitamos, la licencia de uso es

gratuita, podemos ampliar sus funcionalides mediante la instalación de plugins a través de su propio

Marketplace de Plugins y dispone de una consola de comandos integrada en el propio editor, lo que

nos facilitará las tareas que iremos realizando mediante la ejecución de comandos en dicha consola.

Otros editores a tener en cuenta son Atom y Brackets (Gratuitos y multiplataforma) y Sublime Text

(Multiplataforma, de pago).

Doc.: document.docx Título: Front-End - Herramientas y Entorno UXVersión: 1.6Fecha: 21/12/2016

Página 9 de 47

Page 10: Front End: Herramientas y Entorno UX

2. Creación de entorno base del proyecto

2.1. Instalación y configuración de Visual Studio Code

La instalación de Visual Studio Code, es sencilla, sólo hay que ejecutar el instalador y establecer si

queremos asociar los archivos al editor. Con la configuración por defecto se instalará correctamente.

Una vez instalado, se recomienda ejecutarlo y realizar la configuración mostrada a continuación:

Archivo > Preferencias > Tema de Color > Monokai

Archivo > Preferencias > Tema de Iconos > Seti (Visual Studio Code)

En cuanto a los temas de código e iconos, es de libre elección del usuario con los que se sienta más

cómodo. Pero al menos se recomienda utilizar un esquema de colores que identifique

correctamente todos los elementos, objetos, variables, parámetros, etc… de nuestro código. El tema

de los iconos, nos ayuda visualmente a distinguir más claramente los archivos y directorios con los

que trabajamos.

Doc.: document.docx Título: Front-End - Herramientas y Entorno UXVersión: 1.6Fecha: 21/12/2016

Página 10 de 47

Page 11: Front End: Herramientas y Entorno UX

Para evitar problemas con la mezcla de espaciados y tabulaciones, configuraremos unos

parámetros en nuestras preferencias personales:

Archivo > Preferencias > Configuración de usuario

Básicamente configuraremos el editor para que utilice tabulaciones en lugar de espacios y además

nos muestre de forma visual los espacios y tabulaciones:

{

"editor.renderWhitespace": "boundary",

"editor.insertSpaces": false,

"editor.detectIndentation": false

}

Una vez activadas estas opciones, en nuestro código aparecerá una para identificar tabulaciones

y un punto cada vez que introduzcamos un espacio:

Doc.: document.docx Título: Front-End - Herramientas y Entorno UXVersión: 1.6Fecha: 21/12/2016

Página 11 de 47

Page 12: Front End: Herramientas y Entorno UX

2.2. Instalación de Node, Git y configuración de proxy

También necesitamos instalar NodeJS: https://nodejs.org/es/ y Git para Windows: https://git-for-

windows.github.io/.

Al instalar tanto NodeJS como Git, nos aseguraremos de seleccionar la instalación de ambos en el

PATH del sistema, para poder acceder a su línea de comandos desde cualquier proyecto.

Doc.: document.docx Título: Front-End - Herramientas y Entorno UXVersión: 1.6Fecha: 21/12/2016

Página 12 de 47

Page 13: Front End: Herramientas y Entorno UX

Una vez hayamos finalizado la instalación de visual studio code, nodejs y git para Windows,

procederemos a la configuración para poder trabajar con NPM (Gestor de paquetes de Node) y Git a

través del proxy de indra.

Configuración del proxy para NPM:

npm config set proxy http://USERNAME:[email protected]:8080

Si tenemos un carácter de la siguiente tabla en nuestra contraseña de usuario, debemos escaparlo

con el código hexadecimal correspondiente de la siguiente tabla (Sólo para NPM):

Hexadecimal Carácter especial

%40 @

%3A :

%21 !

%23 #

%24 $

Configuración del proxy para GIT:

git config --global http.proxy http://USERNAME:[email protected]:8080

git config --global https.proxy http://USERNAME:[email protected]:8080

Cada una de estas configuraciones no va a generar un archivo de configuración en nuestra carpeta

de usuario:

C:\Users\nombredeusuario\.npmrc en el caso de la configuración de NPM

C:\Users\nombredeusuario\.gitconfig en el caso de la configuración de GIT

Podemos acceder a dichos archivos más adelante para cambiar las credenciales o para verificar

que está correctamente configurado si experimentamos algún problema de conexión con los

repositorios.

El último paso para poder comenzar con nuestro proyecto, es la instalación de dos plugins de node

de forma GLOBAL para poder invocarlos desde cualquier proyecto (Gulp y Bower). Los plugins se

instalan de forma global con el parámetro –g en la instalación:

npm install -g gulp

npm install -g bower

Con la instalación de los programas aquí mencionados, la configuración de proxy realizada y la

instalación de estos dos plugins procederemos a la creación de nuestro proyecto inicial.

Doc.: document.docx Título: Front-End - Herramientas y Entorno UXVersión: 1.6Fecha: 21/12/2016

Página 13 de 47

Page 14: Front End: Herramientas y Entorno UX

2.3. Creación de configuración NodeJS

Para poder instalar los plugins necesarios para nuestro proyecto, debemos crear en primera

instancia una configuración de proyecto NodeJS. En esta configuración se almacenará la

información del proyecto, así como los plugins que instalemos y marquemos como dependencias

durante la instalación.

Para la creación de un nuevo proyecto ejecutamos el comando npm init sobre el directorio raíz de

nuestro proyecto, a través de una consola de comando, acto seguido nos aparecerán una serie de

preguntas acerca de nuestro proyecto, por norma general sólo especificaremos el nombre y la

descripción del mismo en el caso de que queramos cambiarlo.

Esta configuración se realizará la primera vez y nos genera un archivo de configuración

(package.json) ubicado en la raíz del proyecto, cuyo contenido es:

{

"name": "ejercicio",

"version": "1.0.0",

"description": "curso de ux",

"main": "index.js",

"scripts": {

"test": "gulp"

},

"author": "",

"license": "ISC",

"devDependencies": {

"del": "^2.2.2",

"gulp": "^3.9.1",

"gulp-pug": "^3.1.0"

}

}

En caso de que queramos añadir alguna información del proyecto o cambiar alguna dependencia lo

haremos editando el archivo package.json correspondiente a nuestro proyecto.

Doc.: document.docx Título: Front-End - Herramientas y Entorno UXVersión: 1.6Fecha: 21/12/2016

Página 14 de 47

Page 15: Front End: Herramientas y Entorno UX

2.4. Creación de configuración Bower

Del mismo modo que necesitamos un archivo de configuración para guardar la información y

dependencias de nuestro proyecto node, también necesitamos un archivo de configuración Bower

para guardar las dependencias de librerías que necesite nuestro proyecto. Para crear la

configuración ejecutamos el comando bower init. En este caso, obtiene la configuración del archivo

package.json de node y además nos realiza una serie de preguntas adicionales, la más importante

es decirle que NO queremos importar la librerías existentes como dependencias y que SI queremos

que nos añada a la configuración la lista de archivos comúnmente ignorados. En el caso de bower,

nos genera un archivo bower.json, con el siguiente contenido:

{

"name": "ejercicio",

"description": "curso de ux",

"main": "index.js",

"license": "ISC",

"homepage": "",

"private": true,

"ignore": [

"**/.*",

"node_modules",

"bower_components",

"test",

"tests"

]

}

Con la creación de estos dos archivos de configuración (Node y Bower) ya podremos comenzar a

formar nuestro flujo de automatización.

Doc.: document.docx Título: Front-End - Herramientas y Entorno UXVersión: 1.6Fecha: 21/12/2016

Página 15 de 47

Page 16: Front End: Herramientas y Entorno UX

2.5. Instalación de paquete gulp y plugins para gulpfile básico

En puntos anteriores vimos cómo hemos instalado plugins de node a nivel global, y uno de ellos era

gulp, éste es necesario instalarlo a nivel global como a nivel de proyecto. En las siguientes

operaciones de instalación de paquetes a nivel de proyecto, siempre marcaremos dicho paquete

como dependencia del proyecto, para ello añadimos al final del comando el parámetro --save-dev

Para crear nuestro archivo gulpfile donde iremos configurando el flujo de automatización

necesitamos instalar el paquete gulp, con el comando: npm install gulp --save-dev

Una vez instalado el paquete crearemos el archivo gulpfile.js en la raíz de nuestro proyecto y lo

inicializaremos con la inicialización de variables y tareas básicas:

var gulp = require('gulp');

gulp.task('default', function(){

console.log('tarea por defecto');

});

Desde este mismo momento ya tenemos la configuración mínima que nos permitirá lanzar el

comando gulp con un resultado, en este caso un texto en consola con el valor tarea por defecto.

Se recomienda configurar el archivo package.json para que el comando test ejecute nuestra tarea

gulp por defecto, así a la hora de testear la correcta instalación de paquetes tendremos esa tarea

como prueba de que todo se ha instalado correctamente:

"scripts": {

"test": "gulp"

},

Para el resto de plugins node que vayamos a utilizar con nuestro gulpfile, hay que declarar la

variable correspondiente al inicio de nuestro fichero gulpfile:

var gulp = require('gulp'),

pug = require('gulp-pug'),

del = require('del'),

sass = require('gulp-sass'),

[...],

useref = require('gulp-useref');

Doc.: document.docx Título: Front-End - Herramientas y Entorno UXVersión: 1.6Fecha: 21/12/2016

Página 16 de 47

Page 17: Front End: Herramientas y Entorno UX

2.6. Creación de la estructura del proyecto

Por norma general, la estructura de cada proyecto depende mucho de la naturaleza del desarrollo y

de los propios desarrolladores, aun así aconsejamos seguir una estructura de proyecto mínima

como la siguiente (La más común compartida por diversos proyectos):

src/

├─── features/ Secciones o páginas que componen nuestra aplicación

│ └─── sectionName/

│ ├─── sectionName.js Todo el JS, PUG y SASS en la misma carpeta

│ ├─── sectionName.pug siempre que sea de la misma feature.

│ └─── sectionName.scss

├─── components/ Componentes propios comunes o individuales

│ └─── componentName/

│ ├─── componentName.js Todo el JS, PUG y SASS en la misma carpeta

│ ├─── componentName.pug siempre que sea del mismo componente.

│ └─── componentName.scss

├─── services/ Toda la lógica relacionada con los servicios y conexiones

│ ├─── data.service.js

│ └─── logger.service.js

├─── app.main.js JavaScript principal de nuestra aplicación

├─── assets/

│ ├─── img/ Imágenes

│ ├─── css/ CSS Propio y de terceros (vendors)

│ ├─── js/ Javascript propio independiente de AngularJS

│ ├─── libs/ Librerías de terceros (vendors)

│ └─── fonts/ Tipografías para embeder mediante CSS

└─── index.pug Página principal de nuestra aplicación

Cuando incluyamos imágenes, tipografías, css y librerías de terceros, siempre se incluirán en

minúsculas y utilizando guiones o puntos para separar los nombres:

jquery.nombreplugin.min.js

jquery.nombreplugin.min.css

Si el plugin lo utilizamos a través de Bower, no modificaremos ningún archivo.

Doc.: document.docx Título: Front-End - Herramientas y Entorno UXVersión: 1.6Fecha: 21/12/2016

Página 17 de 47

# Estructura no modificable # Estructura generada por el usuario

Page 18: Front End: Herramientas y Entorno UX

3. Procesado de HTML

3.1. Instalación de PUG

Para la tarea de procesado PUG, necesitamos instalar el plugin gulp-pug, instalándolo como

dependencia del proyecto:

npm install gulp-pug --save-dev

3.2. Buenas prácticas en HTML

Para el desarrollo de los proyectos, se ha de utilizar HTML5, dado que queremos hacer un

desarrollo extensible, dinámico y lo más compatible posible con nuevas tecnologías. Se recomienda

seguir una serie de buenas prácticas para un desarrollo de calidad y mantenible:

Usa tabulador, y en el caso de que uses espaciado, 4 espacios.

Utilizar lo más preciso posible las etiquetas de HTML5 en lugar de utilizar los div habituales. En

HTML5 disponemos de etiquetas para enmarcar distintas zonas o elementos de nuestro

código, como <header> <footer> <nav> <aside> <section> <caption> etc., El uso de estas

etiquetas nos aseguran un marcado correcto, semántico y accesible.

Hay que asegurarse de usar correctamente y siguiendo una jerarquía lógica, las etiquetas de

Heading (H1, H2, H3, etc.). No podemos utilizar una etiqueta H1 y saltar a una etiqueta H3 si

no disponemos de una etiqueta H2 superior.

Etiquetado correcto de los elementos, por ejemplo si estamos presentando una lista de datos

simples, una serie de imágenes relevantes debemos utilizar una lista desordenada (UL > LI). Si

estamos mostrando datos complejos y asociados en serie debemos utilizar una tabla, etc.

Evitar el exceso de presentación bajo CSS. Ya que intentamos crear un marcado semántico y

accesible, deberemos en la medida de lo posible, utilizar imágenes (bitmap o vectoriales),

iconos tipográficos, etc., dentro del propio HTML, evitando la inclusión de dichos elementos en

CSS. Ya que por accesibilidad en el punto de control de contraste, estos elementos no son

tratados por los navegadores.

Definir correctamente la identificación de los elementos. Es muy importante identificar

correctamente los enlaces e imágenes utilizando las etiquetas ALT y TITLE, para una correcta

accesibilidad e identificación de las mismas.

No abusar del sobre etiquetado. Para la presentación de elementos, en muchas ocasiones

utilizamos muchos elementos HTML dentro de otros para hacer una presentación que se ajuste

Doc.: document.docx Título: Front-End - Herramientas y Entorno UXVersión: 1.6Fecha: 21/12/2016

Página 18 de 47

Page 19: Front End: Herramientas y Entorno UX

a nuestras necesidades. Actualmente y gracias a las técnicas CSS podemos eliminar gran

parte de esos elementos HTML innecesarios utilizando pseudoelementos CSS, selectores

avanzados, etc. Siempre que podamos evitaremos el uso excesivo de elementos si no

entramos en conflicto con una buena semántica y accesibilidad.

En general si dudas a la hora de hacer un marcado HTML concreto, quizá es porque ese

marcado no corresponde con lo que debes utilizar, analízalo e investiga si lo que vas a hacer

es la forma correcta de hacerlo.

3.3. Creación de tarea de procesado PUG en Gulpfile.js

Creamos en nuestro gulpfile una tarea llamada pug para compilar todo el html del proyecto:

gulp.task('pug', function(){

return gulp.src('src/**/!(_)*.pug')

.pipe(pug({pretty: true}))

.pipe(gulp.dest('app'));

});

Por defecto, utilizaremos la api estándar de gulp y la única opción que cambiaremos en la función

.src(), donde indicaremos con una negación y el carácter a omitir entre paréntesis !(_) en la

expresión a buscar en el source. Esta expresión indica que todo lo que empiece por _ en el nombre

del archivo, ej: _parcial.pug no sea procesado por la tarea, ya que los usaremos para hacer

includes y extensiones de layout internamente al procesar los archivos principales.

Como parámetro opcional podemos definir que nos genere el html completo y correctamente

indentado, indicando el parámetro pretty:true en las opciones de pug. Si quitamos esta opción nos

generará el html minificado en una sola línea.

Doc.: document.docx Título: Front-End - Herramientas y Entorno UXVersión: 1.6Fecha: 21/12/2016

Página 19 de 47

Page 20: Front End: Herramientas y Entorno UX

4. Procesado de CSS

4.1. Instalación de SASS

Para la tarea de procesado SASS, necesitamos instalar el plugin gulp-sass, instalándolo como

dependencia del proyecto:

npm install gulp-sass --save-dev

4.2. Buenas prácticas en SASS

Debido a que vamos a utilizar CSSLint siempre que compilemos nuestro SASS no vamos a entrar

en las buenas prácticas de CSS porque el propio CSSLint nos avisará de los errores que podamos

cometer programando el CSS, por tanto vamos a centrarnos en las buenas prácticas a tener en

cuenta a la hora de trabajar con SASS.

Usa tabulador, y en el caso de que uses espaciado, 4 espacios.

Utiliza la estructura predefinida de parciales, estos son los archivos que van a formar nuestro

CSS. En nuestro proyecto se distinguen COMMONS o Globales y PARTIALS o Parciales. En la

carpeta commons se separa por tipos de elementos (Formularios, Tablas, Botones, Layout,

etc.), es una estructuración que hay que respetar. En la carpeta partials, se incluyen aquellos

estilos que requieren ser escritos a parte para una vista concreta, por ello crearemos un archivo

partial por cada vista en la que tengamos que añadir estilos independientes.

Cuidado con el anidamiento excesivo. Como vamos a partir de un proyecto de cero, no hay

ningún motivo para aplicar un anidamiento excesivo, salvo para el caso de sobre escritura de

estilos de terceros (bootstrap, librerías externas, etc.). Por norma general es mejor utilizar una

clase global para una vista concreta y utilizar un máximo de 3 niveles de anidamiento, en la

medida de lo posible, para optimizar el procesado y carga del CSS resultante.

Usa los comentarios correctamente. Los comentarios estándar de CSS /* como este */ se

compilan junto al CSS, por lo que para evitar que sea compilado, se recomienda utilizar los

comentarios de tipo Sass, precedidos de dos barras // Como este.

4.3. Creación de tarea de procesado SASS en Gulpfile.js

Creamos en nuestro gulpfile una tarea llamada sass para compilar todo el css del proyecto:

gulp.task('sass', function(){

return gulp.src('src/**/!(_)*.scss')

.pipe(sass().on('error', sass.logError))

Doc.: document.docx Título: Front-End - Herramientas y Entorno UXVersión: 1.6Fecha: 21/12/2016

Página 20 de 47

Page 21: Front End: Herramientas y Entorno UX

.pipe(gulp.dest('app'));

});

Al igual que con la tarea de pug, usaremos la api estándar de gulp y añadiremos el comodín de

negación !(_) en la declaración de .src() para que no nos compile ninguno de los archivos que

vamos a utilizar como parciales.

En cuanto a configuración, el plugin gulp-sass permite añadir escuchadores de eventos para realizar

distintas acciones, por defecto recomiendan añadir el escuchador cuando hay un error y ejecutar un

logError, en nuestro caso: on(‘error’, sass.logError) para que nos muestre en consola los errores

que encuentre al procesar SASS y no detenga el flujo de la tarea.

Entre los parámetros que podemos configurar, está el formato de salida del CSS generado, de

momento no vamos a configurarlo, pero más adelante elegiremos formato comprimido o expandido

dependiendo de la tarea que ejecutemos.

Doc.: document.docx Título: Front-End - Herramientas y Entorno UXVersión: 1.6Fecha: 21/12/2016

Página 21 de 47

Page 22: Front End: Herramientas y Entorno UX

5. Procesado de JS

5.1. Buenas prácticas en JS

Hemos marcado unas pautas de desarrollo con respecto al JavaScript que vamos a utilizar, que

dado que trabajaremos con AngularJS será bastante. No se trata de limitar ni imponer una forma de

trabajar sino de definir una metodología, que cumpla unos requisitos mínimos siguiendo estándares

de desarrollo de buenas prácticas, haciendo que el código implementado se pueda mantener y

sostener por cualquier persona involucrada en el proyecto:

Usa tabulador, y en el caso de que uses espaciado, 4 espacios.

Comillas simples para strings, excepto cuando hay que escapar comillas simples dentro de la

cadena.

Después de cada sentencia usar un espaciado para facilitar la lectura.

Ejemplo: if (condición) {…}

No dejar variables zombis, variables definidas y no usadas.

Usar comparador de valor y tipo siempre que sea posible [===].

Dejar espacio entre operadores facilitando la lectura del código. Ejemplo: var x = 1;

En la declaración de parámetros/argumentos de funciones dejar un espacio tras la coma de

separación para facilitar la lectura.

Mantener las llaves de apertura en la misma línea de la condición. Ej.: if (cond) {

Mantener la sentencia ‘else’ en la misma línea del cierre del if.

Para condiciones simples no usar líneas nuevas, en tal caso abrir y cerrar llaves.

No dejar múltiples saltos de línea en blanco para la separación de código.

No asignes múltiples variables en la misma línea.

En la asignación de múltiples variables, no definas el estamento completo para cada una de

ellas, separa por coma y salto de línea.

Utilizar nombres descriptivos para las variables.

Escribe todos los puntos y comas (;) siempre que se deban llevar.

En ejecución, todas las declaraciones var y function son movidas para el comienzo de cada

función (su alcance) - esto es conocido como Elevación. Dicho esto, es buena práctica declarar

todas las variables juntas en la primera línea, con el fin de evitar falsas expectativas con las

variables que han sido declaradas luego de la asignación de su valor.

Doc.: document.docx Título: Front-End - Herramientas y Entorno UXVersión: 1.6Fecha: 21/12/2016

Página 22 de 47

Page 23: Front End: Herramientas y Entorno UX

Comenta el código para que se pueda mantener y sostener fácilmente.

Reduce el número de variables globales.

5.2. Creación de tarea de procesado JS

Como para JS no vamos a utilizar ningún lenguaje intérprete de JS, si no que vamos a utilizar

javascript estándar, no necesitamos ningún plugin para procesarlo. Únicamente necesitamos

disponer de una tarea que copie los archivos JS a nuestro directorio app:

gulp.task('js', function(){

return gulp.src('src/**/*.js')

.pipe(gulp.dest('app'));

});

Utilizamos las api de GULP SRC y DEST únicamente, indicando que recoja cualquier archivo JS

(aunque esté en subdirectorios) y copie la misma estructura a nuestra carpeta app.

Doc.: document.docx Título: Front-End - Herramientas y Entorno UXVersión: 1.6Fecha: 21/12/2016

Página 23 de 47

Page 24: Front End: Herramientas y Entorno UX

6. Procesando librerías de terceros

6.1. Instalación de USEREF

Debido a que el entorno se ha orientado para el trabajo con AngularJS y su metodología permite

crear múltiples archivos sin seguir una esctructura definida de los archivos, no vamos a utilizar los

plugins habituales de concatenación para unir nuestros JS. En su lugar utilizaremos el plugin gulp-

useref como alternativa a los mismos, ya que nos permite una flexibilidad a la hora de elegir cómo

generar el JS sin tener que modificar el archivo gulpfile, que otros plugins no permiten.

Para la instalación del paquete necesario para nuestra tarea ejecutamos el comando:

npm install gulp-useref --save-dev

6.2. Creación de tarea de procesado USEREF

El plugin USEREF depende explícitamente de ficheros HTML, por tanto debemos ejecutar ésta

tarea una vez hayamos compilado las plantillas PUG. Además, como useref está orientado a

minimizar los ficheros que generemos lo asociaremos a la tarea de distribución.

Para ello crearemos una tarea ‘dist’ que ejecute la tarea pug, sass, una vez que procese nuestras

fuentes, lanzamos la función que ejecuta useref sobre nuestro HTML generado.

gulp.task('dist', ['sass', 'pug'], function(){

return gulp.src('app/**/*.html')

.pipe(useref({searchPath: 'src'}))

.pipe(gulp.dest('app'));

});

El parámetro searchPath que le facilitamos a useref, indica dónde tiene que buscar si no encuentra

los archivos que está buscando. En nuestro caso cuando encuentre un JS o CSS que no esté en la

carpeta app lo buscará también dentro de la carpeta src.

Más adelante veremos por qué motivo hemos optado por este comportamiento y además

extenderemos ésta tarea, pues USEREF únicamente se encarga de concatenar archivos, no los

minimiza ni procesa de ninguna otra forma.

6.3. Instalación de librerías jquery y bootstrap mediante Bower

En apartados anteriores, hemos visto que Bower es un gestor de librerías externas, que nos permite

instalar las últimas versiones de las librerías y frameworks más extendidos, así no tenemos más que

lanzar un comando para instalar cualquiera de estas librerías. En nuestro caso y para seguir con el

Doc.: document.docx Título: Front-End - Herramientas y Entorno UXVersión: 1.6Fecha: 21/12/2016

Página 24 de 47

Page 25: Front End: Herramientas y Entorno UX

ejemplo de la tarea de procesado USEREF, instalaremos jquery y bootstrap mediante los siguientes

comandos:

bower install jquery --save

bower install bootstrap --save

Con el parámetro --save especificamos que la librería que se instale se guarde como dependencia

en el proyecto.

6.4. Uso de build useref dentro del código HTML

El uso de USEREF es muy sencillo, únicamente tenemos que incluir los archivos que queremos

concatenar dentro de unos comentarios específicos, dependiendo de si es JS o CSS se forman de

la siguiente manera:

// build:css assets/css/vendor.css

link(rel='stylesheet', href='../bower_components/bootstrap/dist/css/bootstrap.min.css')

link(rel='stylesheet', href='../bower_components/bootstrap/dist/css/bootstrap-

theme.min.css')

// endbuild

// build:js assets/libs/vendor.js

script(src='../bower_components/jquery/dist/jquery.slim.min.js')

script(src='../bower_components/bootstrap/dist/js/bootstrap.min.js')

// endbuild

Al compilar nuestro pug nos genera una estructura como la siguiente:

<!-- build:TIPO archivo-de-salida -->

<!-- endbuild -->

Donde TIPO especificamos si va a concatenar un JS o CSS y en archivo de salida especificamos la

ruta y el nombre de archivo que nos va a generar.

Este comentario lo analiza USEREF cuando lo encuentra dentro del HTML y todo lo que haya

dentro del inicio y el fin del comentario lo concatenará en un archivo con la ruta y nombre que le

indiquemos. Así tenemos total control sobre cómo se generan estos archivos dentro del propio

código sin tener que modificar el archivo gulpfile.

Doc.: document.docx Título: Front-End - Herramientas y Entorno UXVersión: 1.6Fecha: 21/12/2016

Página 25 de 47

Page 26: Front End: Herramientas y Entorno UX

7. Automatización de HTML, CSS y JS

7.1. Instalación de Gulp Watch

Dado que la propia API Watch de GULP tiene algunos problemas a la hora de trabajar con archivos

que son añadidos en caliente en el proyecto, hemos optado por utilizar un plugin de terceros en

lugar de la propia api de gulp.

Para ello tenemos que instalar el paquete gulp-watch:

npm install gulp-watch --save-dev

7.2. Creación de tarea de escucha para el procesado automático de PUG, SASS y JS.

Tanto la api Watch de GULP como el plugin gulp-watch utilizan una invocación muy similar, ya que

le especificamos en qué ficheros va a escuchar y qué tarea va a ejecutar:

API GULP:

gulp.watch('*.scss', ['tarea-sass']);

Gulp Watch:

gulpwatch('*.scss', function(){

gulp.start('tarea-sass');

});

En nuestro caso, vamos a modificar la tarea default para que invoque a la tarea build y cuando haya

terminado, se quede escuchando los cambios sobre los archivos SASS, PUG y JS:

gulp.task('build', ['clean', 'sass', 'pug', 'js']);

gulp.task('default', ['build'], function(){

gulpwatch('src/**/*.scss', function(){

gulp.start('sass');

});

gulpwatch('src/**/*.pug', function(){

gulp.start('pug');

});

gulpwatch('src/**/*.js', function(){

gulp.start('js');

});

Doc.: document.docx Título: Front-End - Herramientas y Entorno UXVersión: 1.6Fecha: 21/12/2016

Página 26 de 47

Page 27: Front End: Herramientas y Entorno UX

});

Para ello, con los tres escuchadores que hemos creado, cada vez que haya un cambio en nuestros

archivos fuente, se invocará a la tarea correspondiente dependiendo del tipo de archivo que se ha

modificado.

7.3. Corrección de errores en procesado de SASS

Cuando utilizamos el plugin gulp-sass y un editor de texto que no dispone de la opción de guardado

atómico (Atomic Save), nos encontramos con el problema de que en el momento que se ejecuta la

tarea SASS, el editor todavía no ha terminado de guardar los archivos que tiene que procesar y en

algunas ocasiones nos aparece un error de compilación porque no ha podido encontrar el sass

parcial que tiene que procesar.

Para solucionar este error, utilizaremos un plugin para añadir un delay a la tarea de procesado, en

este caso el plugin se llama gulp-wait y con el podremos añadir un tiempo de espera antes de que

procese la tarea SASS, así nos aseguramos que el editor ya ha guardado correctamente los

archivos antes de que sean procesados.

Para la instalación del plugin:

npm install gulp-wait --save-dev

Una vez instalado el plugin, modificamos la tarea SASS y añadimos el delayer de 100ms justo antes

de ejecutar la tarea sass():

gulp.task('sass', function(){

return gulp.src('src/**/!(_)*.scss')

.pipe(wait(100))

.pipe(sass({outputStyle: 'expanded'}).on('error', sass.logError))

.pipe(gulp.dest('app'));

});

Con esto nos aseguramos que no aparezca el error cuando no encuentra los archivos parciales que

tiene que procesar.

Doc.: document.docx Título: Front-End - Herramientas y Entorno UXVersión: 1.6Fecha: 21/12/2016

Página 27 de 47

Page 28: Front End: Herramientas y Entorno UX

8. Servidor en vivo

8.1. Instalación de BrowserSync.

Una de las tareas más pesadas cuando estamos desarrollando es actualizar el navegador cada vez

que hacemos un cambio en el código.

BrowserSync, además de actualizar el navegador automáticamente, también sincroniza el scroll y

los clicks en todos los navegadores conectados, permitiendo sincronizar los movimientos a través

de la web en todos los dispositivos. Algo muy útil en el desarrollo y testeo.

También dispone de una interfaz gráfica que permite configurar la herramienta, consultar el historial,

sincronizar todos los dispositivos en la misma página de la aplicación, herramientas para hacer

debug, y más opciones.

BrowserSync no es un plugin de gulp específico, ya que soporta su utilización tanto en gulp como

grunt.

Para instalar el plugin BrowserSync:

npm install browser-sync --save-dev

Además, al declarar su variable, debemos hacerlo de la siguiente forma:

var browsersync = require('browser-sync').create()

8.2. Creación de tarea para servir estáticos.

La tarea para servir nuestros estáticos generados, es muy simple, sólo tenemos que especificar el

directorio app de nuestro proyecto y además añadir la ruta a la carpeta bower_components, ya que

éstos se encuentran fuera de la carpeta app y no tendríamos acceso directo desde el servidor, por

ello lo añadimos como ruta (alias).

gulp.task('serve', function(){

browsersync.init({

server: {

baseDir: 'app',

routes: {

'/bower_components': 'bower_components'

}

}

});

Doc.: document.docx Título: Front-End - Herramientas y Entorno UXVersión: 1.6Fecha: 21/12/2016

Página 28 de 47

Page 29: Front End: Herramientas y Entorno UX

});

Añadimos la tarea serve a nuestro flujo de dependencias en la tarea build, para que cada vez que

ejecutemos gulp nos compile todos los fuentes y a su vez nos sirva el resultado en el navegador:

gulp.task('build', ['clean', 'sass', 'pug', 'js', 'serve']);

Una vez que el servidor comience a escuchar, nos informa de las URL’s de acceso en la consola

que ha lanzado la tarea, así podemos ver los puertos e IP’s de acceso local, remoto y a la UI de

configuración:

[BS] Access URLs:

-------------------------------------

Local: http://localhost:3000

External: http://10.111.98.32:3000

-------------------------------------

UI: http://localhost:3001

UI External: http://10.111.98.32:3001

-------------------------------------

[BS] Serving files from: app

Si por algún motivo, necesitamos cambiar los puertos de acceso al servidor y a la consola de

configuración, debemos especificar los puertos deseados en la propia tarea serve:

gulp.task('serve', function(){

browsersync.init({

port: 2016,

server: {

baseDir: 'app',

routes: {

'/bower_components': 'bower_components'

}

},

ui: {

port: 2017

}

});

});

En este ejemplo especificamos el Puerto 2016 para el servidor y el puerto 2017 para la consola de

browsersync.

Doc.: document.docx Título: Front-End - Herramientas y Entorno UXVersión: 1.6Fecha: 21/12/2016

Página 29 de 47

Page 30: Front End: Herramientas y Entorno UX

8.3. Testing de eventos multidispositivo mediante browsersync.

Por defecto BrowserSync arranca en modo multi dispositivo, por lo que si abrimos la url de nuestro

servidor en distintos dispositivos, todos los eventos que ejecutemos sobre cualquiera de los clientes

que acceden al servidor se trasladará al resto. Es decir, si abrimos desde un navegador de escritorio

y hacemos scroll sobre la página, en el resto de navegadores (móviles, tablets, pc, etc…) se clonará

éste comportamiento, y toda la navegación que vayamos realizando se traslada al resto de

dispositivos.

8.4. Configuración de consola BrowserSync.

En la consola de browsersync, podremos configurar distintas opciones y ver información sobre el

servidor que hemos lanzado. En la pestaña overview vemos la información de acceso al servidor, la

ruta que está sirviendo y las conexiones que hay establecidas en ese momento. Desde aquí

podemos mandar una orden de sincronizar el navegador de todas las conexiones.

Doc.: document.docx Título: Front-End - Herramientas y Entorno UXVersión: 1.6Fecha: 21/12/2016

Página 30 de 47

Page 31: Front End: Herramientas y Entorno UX

En la pestaña Sync Options podemos elegir qué eventos se van a sincronizar entre los distintos

dispositivos conectados a nuestro servidor:

La pestaña History nos mostrará las distintas rutas a las que han accedido los dispositivos.

Doc.: document.docx Título: Front-End - Herramientas y Entorno UXVersión: 1.6Fecha: 21/12/2016

Página 31 de 47

Page 32: Front End: Herramientas y Entorno UX

La pestaña Plugins nos permite configurar los plugins que hayamos cargado junto a browsersync.

La pestaña Remote Debug nos permite controlar distintas formas de hacer debug remoto sobre

nuestro servidor.

Doc.: document.docx Título: Front-End - Herramientas y Entorno UXVersión: 1.6Fecha: 21/12/2016

Página 32 de 47

Page 33: Front End: Herramientas y Entorno UX

Por último la pestaña Network Throttle nos permite simular varios tipos de conexión a nuestro

servidor, para poder comprobar cómo se comportaría nuestra aplicación bajo cada uno de estos

casos.

Doc.: document.docx Título: Front-End - Herramientas y Entorno UXVersión: 1.6Fecha: 21/12/2016

Página 33 de 47

Page 34: Front End: Herramientas y Entorno UX

9. Preparación del entorno para distribución y metodología

9.1. Minificado de librerías de terceros

En puntos anteriores, hemos visto como concatenar las librerías de terceros utilizando USEREF.

Ahora vamos a completar la tarea USEREF para que minimice el CSS y JS de terceros, utilizando

los plugins gulp-uglify y gulp-clean-css.

Instalamos los plugins que vamos a utilizar

npm install gulp-if --save-dev

npm install gulp-uglify --save-dev

npm install gulp-clean-css --save-dev

Como vamos a utilizar el resultado del pipe useref(), necesitamos discriminar de alguna forma los

ficheros resultantes, para aplicar sobre ellos los plugins correspondientes para el tipo de archivo

seleccionado. Por este motivo utilizamos el plugin gulp-if.

Ahora completamos la tarea dist y modificamos el pipe USEREF:

gulp.task('dist', ['clean', 'sass', 'pug'], function(){

return gulp.src('app/**/*.html')

.pipe(useref({searchPath: 'src'}))

.pipe(gulpif('*.js', uglify()))

.pipe(gulpif('*.css', minify()))

.pipe(gulp.dest('app'));

});

Si analizamos la tarea, podemos ver que utilizamos gulp-if para discriminar el tipo de archivo que

obtenemos del pipe USEREF, si obtenemos archivos JS los pasamos a la tarea uglify() y cuando

obtenemos archivos CSS los pasamos a la tarea minify(), ya que de otra forma no funcionaría y

provocaría un error en la tarea, puesto que uglify sólo puede aplicarse sobre archivos js y minify sólo

puede aplicarse sobre archivos css.

9.2. Creación de tareas de metodología

Debido a que queremos que el código que generemos sea óptimo y fiel a los estándares,

utilizaremos una serie de plugins que analizarán nuestro código y nos informarán de errores que

cometamos en caliente. Así podremos subsanarlos al mismo tiempo que estamos desarrollando.

Doc.: document.docx Título: Front-End - Herramientas y Entorno UXVersión: 1.6Fecha: 21/12/2016

Página 34 de 47

Page 35: Front End: Herramientas y Entorno UX

9.2.1. Metodología en CSS mediante CSSLint

Para asegurar un código CSS correcto, utilizamos la herramienta CSSLint que dispone de

una serie de reglas predefinidas para asegurar un desarrollo óptimo. Podemos consultar

éstas reglas en https://github.com/CSSLint/csslint/wiki/rules. Para su utilización necesitamos

instalar el plugin gulp-csslint:

npm install gulp-csslint --save-dev

Una vez instalado, añadimos el pipe con la tarea csslint después de generar el sass,

además debido a las características de nuestro desarrollo, inhabilitaremos un par de reglas

que no deseamos comprobar en nuestro desarrollo:

gulp.task('sass', function(){

return gulp.src('src/**/!(_)*.scss')

.pipe(sass().on('error', sass.logError))

.pipe(csslint({

'order-alphabetical': false,

'box-model': false

}))

.pipe(csslint.formatter())

.pipe(browsersync.reload({stream:true}))

.pipe(gulp.dest('app'));

});

La más importante es que no compruebe el modelo de caja, ya que por defecto nuestro

proyecto incluye bootstrap y su reset.css, que especifica un modelo de caja a todos los

elementos HTML, por ello no los controlaremos en nuestro CSS, pues resultaría demasiado

redundante y con una carga más pesada.

Por otra parte, recomendamos encarecidamente el uso del plugin CSSComb para nuestro

editor, con una simple combinación de teclas formateará nuestro CSS de la forma más

óptima. Por ello inhabilitamos la regla de orden alfabético de declaraciones.

La instalación de CSSComb depende de cada editor, sólo hay que buscarlo en los

repositorios de plugins para cada uno de ellos e instalarlo. Si encuentra el archivo de

configuración en la raíz del proyecto utilizará las reglas predefinidas en el mismo para

formatear el código, esto lo hacemos pulsando la combinación de teclas:

Control + Shift + C .

Doc.: document.docx Título: Front-End - Herramientas y Entorno UXVersión: 1.6Fecha: 21/12/2016

Página 35 de 47

Page 36: Front End: Herramientas y Entorno UX

9.2.2. Compatibilidad de CSS3 con Autoprefixer

Debido a que nuestra aplicación se desarrollará utilizando HTML5 y CSS3, no vamos a

preocuparnos de dar soporte a navegadores antiguos para las propiedades CSS3 utilizando

los vendor prefixes. En nuestro caso escribiremos el código CSS3 estándar y utilizaremos la

herramienta autoprefixer, para poder cambiar el soporte a navegadores antiguos

modificando la tarea de gulp, evitándonos tener que modificar nuestro código SASS.

Para ello instalamos el plugin gulp-autoprefixer:

npm install gulp-autoprefixer --save-dev

Básicamente utilizaremos el pipe autoprefixer justo después de que generemos el CSS, por

lo que lo añadiremos más adelante a la tarea SASS.

gulp.task('sass', function(){

return gulp.src('src/**/!(_)*.scss')

.pipe(sass().on('error', sass.logError))

.pipe(autoprefixer({

Browsers: ['> 5%', 'firefox < 20']

}))

.pipe(csslint.formatter())

.pipe(browsersync.reload({stream:true}))

.pipe(gulp.dest('app'));

});

9.2.3. Metodología en JS mediante JSHint

Al igual que en CSS, también aplicaremos una serie de reglas sobre nuestro código

JavaScript para asegurar que utilizamos buenas prácticas en su desarrollo. Para ésta tarea

utilizaremos los plugins jshint y gulp-jshint (éste último es dependiente del primero):

npm install jshint --save-dev

npm install gulp-jshint --save-dev

Una vez instalados, modificaremos nuestra tarea JS, que como únicamente la ejecutaremos

en modo desarrollo no necesitamos distinguir la tarea que estamos ejecutando. En el punto

USEREF explicábamos por qué habíamos elegido éste comportamiento, ya que en

desarrollo nos interesa tener todos los JS separados para poder hacer debug más

fácilmente. En cambio, cuando entreguemos la distribución nos interesa concatenary

minificar todo el JS en un único archivo:

gulp.task('js', function(){

Doc.: document.docx Título: Front-End - Herramientas y Entorno UXVersión: 1.6Fecha: 21/12/2016

Página 36 de 47

Page 37: Front End: Herramientas y Entorno UX

return gulp.src(['src/**/*.js', '!src/assets/libs/*.js'])

.pipe(jshint())

.pipe(jshint.reporter('default'))

.pipe(browsersync.reload({stream:true}))

.pipe(gulp.dest('app'));

});

Además modificaremos la entrada de archivos, para que ignore cualquier archive JS que se

encuentre dentro del directorio de librerías, ya que no nos interesa que procese éstos

archivos, que son de terceros y no hemos desarrollado nosotros. Esta misma cadena de

entrada la aplicaremos en la tarea Watcher de JS, para que no ejecute nuestra tarea js en

estos archivos.

gulpwatch(['src/**/*.js', '!src/assets/libs/*.js'], function(){

gulp.start('js');

});

Doc.: document.docx Título: Front-End - Herramientas y Entorno UXVersión: 1.6Fecha: 21/12/2016

Página 37 de 47

Page 38: Front End: Herramientas y Entorno UX

9.3. Creación de tareas adicionales

9.3.1. Tareas de copiado de ficheros

Debido a que todos los archivos los tenemos en nuestra carpeta src, puesto que cada vez

que ejecutamos una tarea la carpeta app se limpia completamente y por lo tanto no

podríamos alojar archivos de imágenes, tipografías, etc… en esta carpeta. Necesitamos

crear una tarea de copiado para cada tipo de fichero que necesitamos copiar a nuestra

carpeta APP cuando se ejecutan las tareas iniciales o como veremos más adelante, cuando

se cambien ficheros y que ejecute el watcher.

Básicamente, vamos a comprobar cuando se añaden Imágenes, Librerías de terceros (CSS

y JS), Tipografías e Imágenes SVG (Estas últimas las copiamos aparte, porque para las

imágenes, además de copiar vamos a optimizarlas para ahorrar el máximo espacio posible).

Para ésta tarea, necesitamos instalar el plugin gulp-imagemin:

npm install gulp-imagemin --save-dev

Después conformaremos las tareas de la misma forma, indicando en algunas de ellas varias

extensiones para recoger los ficheros correspondientes:

gulp.task('copy:css', function(){

return gulp.src('src/assets/css/*.css')

.pipe(gulp.dest('app/assets/css/'));

});

gulp.task('copy:images', function(){

return gulp.src('src/assets/img/*.+(jpg|png|gif|jpeg)')

.pipe(imagemin({progressive: true}))

.pipe(gulp.dest('app/assets/img/'));

});

gulp.task('copy:fonts', function(){

return gulp.src('src/assets/fonts/*.+(eot|svg|ttf|woff|woff2|otf)')

.pipe(gulp.dest('app/assets/fonts'));

});

gulp.task('copy:libs', function(){

return gulp.src('src/assets/libs/*.js')

.pipe(gulp.dest('app/assets/libs/'));

});

Doc.: document.docx Título: Front-End - Herramientas y Entorno UXVersión: 1.6Fecha: 21/12/2016

Página 38 de 47

Page 39: Front End: Herramientas y Entorno UX

gulp.task('copy:svg', function(){

return gulp.src('src/assets/img/*.svg')

.pipe(gulp.dest('app/assets/img/'));

});

Analizando las tareas, vemos que todas comparten una cierta estructura, en algunas de

ellas seleccionamos muy detalladamente las extensiones que queremos procesar, ya que

en alguna de estas carpetas podemos tener ejemplos o muestras de uso y no queremos

procesarlas. Al ser más explicitos en los ficheros de entrada, tenemos que ser igual de

explícitos en el destino, pues no nos va a generar la propia estructura si sólo indicásemos la

salida app.

En el caso de la tarea de copiado de imágenes, añadimos el pipe imagemin() con la opción

de guardado progresivo, para que ahorre tamaño en las imágenes sin que pierdan

demasiada calidad.

9.3.2. Tareas de limpiado de ficheros

Hemos creado una serie de tareas de copiado, como estas tareas no ejecutan ningún pipe

especial y sólo las vamos a utilizar para copiar en nuestra carpeta de desarrollo

necesitamos crear unas tareas de limpieza para que elimine los archivos que hayamos

eliminado de nuestra carpeta src.

Para la eliminación de archivos utilizaremos el plugin DEL de node, no es un plugin propio

de gulp, por lo que nuestras tareas no se formarán con la estructura propia de la api de gulp,

en su lugar sólo retornamos el comando del.sync('archivo/s');

Para la instalación del plugin:

npm install del --save-dev

Todas las tareas se conforman de la misma manera, sólo se aplican sobre cada tipo de

fichero concreto, a excepción de la tarea clean general que borra toda la carpeta app cada

vez que construimos en modo desarrollo o distribución:

gulp.task('clean', function(){

return del.sync(['app/*']);

});

gulp.task('clean:css', function(){

return del.sync(['app/assets/css/*.*', '!app/assets/css/main.css']);

});

gulp.task('clean:fonts', function(){

return del.sync('app/assets/fonts/*.*');

Doc.: document.docx Título: Front-End - Herramientas y Entorno UXVersión: 1.6Fecha: 21/12/2016

Página 39 de 47

Page 40: Front End: Herramientas y Entorno UX

});

gulp.task('clean:images', function(){

return del.sync('app/assets/img/*.+(jpg|png|gif|jpeg)');

});

gulp.task('clean:libs', function(){

return del.sync('app/assets/libs/*.*');

});

gulp.task('clean:svg', function(){

return del.sync('app/assets/img/*.svg');

});

La única excepción se produce en la tarea de limpieza de CSS, pues no queremos que

elimine nuestro archivo procesado mediante SASS. En este caso le indicamos una negación

a nuestro archivo generado por SASS.

9.3.3. Watchers para copiado de ficheros

Como queremos procesar los cambios que hagamos en los ficheros indicados

anteriormente, no solo que los copie al inicio de nuestra tarea, necesitamos definir una serie

de watchers, que ejecutarán cada tarea de limpiado y copiado concreta.

Cada una de las tareas, ejecutará primero la limpieza de los archivos antiguos y copiará los

nuevos siempre que se produzcan cambios, así nos aseguramos de no dejar archivos

residuales en sus correspondientes directorios:

gulpwatch(['src/**/*.js', '!src/assets/libs/*.js'], function(){

gulp.start('js');

});

gulpwatch('src/assets/img/*.+(jpg|png|gif|jpeg)', function(){

gulp.start('clean:images');

gulp.start('copy:images');

});

gulpwatch('src/assets/fonts/*.+(eot|svg|ttf|woff|woff2|otf)', function(){

gulp.start('clean:fonts');

gulp.start('copy:fonts');

});

gulpwatch('src/assets/libs/*.js', function(){

gulp.start('clean:libs');

gulp.start('copy:libs');

Doc.: document.docx Título: Front-End - Herramientas y Entorno UXVersión: 1.6Fecha: 21/12/2016

Página 40 de 47

Page 41: Front End: Herramientas y Entorno UX

});

gulpwatch('src/assets/css/*.css', function(){

gulp.start('clean:css');

gulp.start('copy:css');

});

gulpwatch('src/assets/img/*.svg', function(){

gulp.start('clean:svg');

gulp.start('copy:svg');

});

Como podemos observar, estamos utilizando la misma entrada de extensiones de archivo

que en las tareas de copiado y limpiado, para asegurarnos de limpiar únicamente las

extensiones que nos afectan y no eliminar archivos generados por otras tareas.

También hemos modificado la entrada de archivos de la tarea Watcher de JS, puesto que

ahora tenemos que tener en cuenta que podemos tener archivos JS dentro de la carpeta

LIBS y éstos JS no nos interesa ni procesarlos (Ya modificamos la tarea JS para evitar

procesar estos archivos), ni tan siquiera que ejecute la tarea, así nos evitamos ejecutar una

tarea que no va a hacer nada sobre éstos archivos innecesariamente. Para ello utilizamos la

condición de que no escuche cualquier archivo js dentro de la carpeta libs.

9.4. Completado de tareas de distribución

Ya tenemos creada la tarea dist, que creamos y dejamos aparcada en un punto anterior. Ahora

necesitamos completar las tareas que son llamadas desde dist para que generen contenido

minificado y optimizado para distribuir.

9.4.1. Completado de la tarea SASS

Ya que por defecto la tarea SASS nos devuelve el código CSS en formato expandido,

necesitamos modificar ésta tarea para que nos devuelva el código minificado si estamos

invocándola desde la tarea dist.

Para ello nos ayudamos del objeto gulp devuelto en cada ejecución de tarea y más

concretamente del array seq (this.seq) que nos devuelve un array con la secuencia de

tareas ejecutadas en la tarea actual. Como nuestra intención es comprobar cuándo estamos

en la tarea dist, buscaremos que ‘dist’ sea parte del resultado de this.seq, comprobando

que es parte del índice del array.

gulp.task('sass', function(){

if(this.seq.indexOf('dist') >= 0) {

return gulp.src('src/**/!(_)*.scss')

Doc.: document.docx Título: Front-End - Herramientas y Entorno UXVersión: 1.6Fecha: 21/12/2016

Página 41 de 47

Page 42: Front End: Herramientas y Entorno UX

.pipe(sass({outputStyle:'compressed'}).on('error', sass.logError))

.pipe(autoprefixer({browsers: ['> 5%', 'firefox < 20']}))

.pipe(gulp.dest('app'));

} else {

return gulp.src('src/**/!(_)*.scss')

.pipe(sass().on('error', sass.logError))

.pipe(csslint({'order-alphabetical': false, 'box-model': false}))

.pipe(csslint.formatter())

.pipe(browsersync.reload({stream:true}))

.pipe(gulp.dest('app'));

}

});

De esta forma comprobamos cuando estamos dentro de dist y ejecutamos sass en modo

comprimido y le añadimos los vendor prefixes correspondientes. De lo contrario ejecutamos

sass en modo expandido y además ejecutamos CSSLint para el análisis de errores.

9.4.2. Completado de la tarea COPY

Debido a que queremos que la tarea copy ejecute distintas subtareas dependiendo de si

estamos en modo desarrollo o modo distribución, utilizaremos la comprobación de

secuencia dist, para crear una pequeña función que sólo ejecute las subtareas de copiado

específicas de desarrollo cuando no estemos en modo dist, para ello modificaremos nuestra

tarea copy:

gulp.task('copy', function(){

gulp.start('copy:fonts');

gulp.start('copy:images');

gulp.start('copy:svg');

if(this.seq.indexOf('dist') < 0) {

gulp.start('copy:css');

gulp.start('copy:libs');

}

});

9.4.3. Creación de tarea DIST:TEST

Para poder ejecutar una aplicación angularjs, tenemos que utilizar un servidor, puesto que si

abrimos los ficheros html directamente en el navegador no funcionará, sería muy

Doc.: document.docx Título: Front-End - Herramientas y Entorno UXVersión: 1.6Fecha: 21/12/2016

Página 42 de 47

Page 43: Front End: Herramientas y Entorno UX

conveniente disponer de una forma rápida de testear que el minimizado de CSS/JS no

afecta a nuestra aplicación y que todo funciona correctamente, creando la siguiente tarea:

gulp.task('dist:test', ['dist'], function(){

gulp.start('serve');

});

Simplemente añadimos una tarea dist:test que depende de dist y cuando dist finalice

ejecutará la tarea serve que arranca BrowserSync en el directorio app, que es el directorio

donde dist nos genera el distribuible por defecto.

9.4.4. Creación de tarea DIST:ZIP

Para finalizar y para facilitarnos la entrega a la hora de generar una distribución, vamos a

crear una tarea que genere la distribución y la comprima en un archivo ZIP con la fecha en

que se ha generado para entregarlo más fácilmente. Para poder crear el archivo ZIP,

necesitamos instalar el plugin gulp-zip:

npm install gulp-zip --save-dev

Después, creamos una tarea donde obtenemos la fecha actual del sistema y la añadimos al

nombre del archivo ZIP que vamos a generar:

gulp.task('dist:zip', ['dist'], function(){

var fechaCreacion = new Date().toLocaleDateString();

return gulp.src('app/**/*.*')

.pipe(zip('app-dist_'+fechaCreacion+'.zip'))

.pipe(gulp.dest('./'));

});

Doc.: document.docx Título: Front-End - Herramientas y Entorno UXVersión: 1.6Fecha: 21/12/2016

Página 43 de 47

Page 44: Front End: Herramientas y Entorno UX

10. Creación de guía de estilos

10.1.Instalación del plugin y tareas gulp

Gracias a la tecnología provista mediante KSS, podemos incluir comentarios con un format

específico en nuestros ficheros CSS para ir construyendo una guía de estilos con los estilos propios

de nuestro SASS.

Guía de uso KSS: https://github.com/kneath/kss/blob/master/SPEC.md

De esta forma, ayudamos a construir una documentación visual de cómo hay que escribir el código

HTML para generar los distintos elementos que hemos estilizado mediante nuestro CSS.

Para esta tarea utilizamos el plugin sc5-styleguide compatible tanto con GulpJS como con

GruntJS. Este plugin funciona con AngularJS, por lo que para poder consultar la guía de estilos una

vez generada, tenemos que utilizar un servidor web, de lo contrario no podemos consultarla.

Para construir la guía de estilos necesitamos incluir un archivo Markdown con el texto de

introducción o instrucciones a mostrar en la página principal de la guía de estilos e ir especificando

las distintas secciones que compondrán dicha guía de estilos mediante nuestros archivos SASS. La

propia tarea de styleguide se encargará de analizar nuestros archivos fuentes y construir la

estructura de navegación y los estilos a mostrar dependiendo de nuestros archivos SASS.

Sintaxis de Markdown: http://markdown.es/sintaxis-markdown/

Para la instalación del plugin:

npm install sc5-styleguide --save-dev

Una vez instalado el plugin, crearemos dos subtareas necesarias para la construcción de la guía de

estilos y una tarea principal que invocará a estas dos subtareas y además, se encargará de lanzar

un servidor específico para la guía de estilos:

gulp.task('styleguide:generate', function(){

return gulp.src('src/assets/css/**/*.scss')

.pipe(styleguide.generate({

title: 'Guía de estilos de ejemplo',

extraHead: '<link rel="stylesheet" href="assets/css/vendor.css" />',

overviewPath: 'src/assets/css/styleguide.md'

}))

.pipe(gulp.dest('app/styleguide'));

});

Doc.: document.docx Título: Front-End - Herramientas y Entorno UXVersión: 1.6Fecha: 21/12/2016

Página 44 de 47

Page 45: Front End: Herramientas y Entorno UX

gulp.task('styleguide:applystyles', function(){

return gulp.src([

'src/assets/css/main.scss',

'bower_components/bootstrap/dist/css/bootstrap.min.css'

])

.pipe(sass({errLogToConsole: true}))

.pipe(styleguide.applyStyles())

.pipe(gulp.dest('app/styleguide'));

});

gulp.task('styleguide', ['dist', 'styleguide:generate', 'styleguide:applystyles'],

function(){

browsersync.init({

server: {

baseDir: "app/styleguide",

routes: {

"/css": "app/assets/css"

}

}

});

});

En la tarea styleguide:generate, especificamos el título de la guía de estilos, el archivo markdown

con la introducción y además, nuestro archivo vendor.css para que cargue los estilos de terceros

que utilizamos en nuestro código, por ejemplo bootstrap.

Aparte de esto, también tenemos que cargar los estilos de bootstrap en la tarea

styleguide:generate, para que al combinar ambas tareas se muestren correctamente los estilos

bootstrap que modifiquemos, por lo demás utilizará nuestro fuente SASS para generar los estilos y

elementos.

Por último, creamos la tarea principal styleguide, que se encarga de ejecutar la distribución y las

subtareas styleguide para una vez terminado servir el resultado utilizando browsersync. Así

podemos consultar mas fácilmente la guía de estilos.

Doc.: document.docx Título: Front-End - Herramientas y Entorno UXVersión: 1.6Fecha: 21/12/2016

Página 45 de 47

Page 46: Front End: Herramientas y Entorno UX

10.2.Creación de estructura y estilos mediante KSS

Los puntos que conforman la estructura de la guía de estilos se definen dentro de nuestros ficheros

SASS. Por norma general seguiremos la estructura recomendada en las buenas prácticas CSS que

hemos visto en puntos anteriores. De tal forma que tendremos una sección Global o Commons y

una sección de parciales o Views/Features.

En el primer archivo que carguemos de tipo común o parcial mediante @import en nuestro SASS

indicaremos el nombre del menú donde iremos incluyendo los distintos subniveles. En este ejemplo

lo hacemos con los comunes:

_commons.scss

// Commons

//

// Estilos comunes para todo el proyecto

//

// Styleguide 1.0

Aquí estamos definiendo el primer punto de la guía de estilos 'Commons' y aplicando la numeración

1.0 como raíz. Si añadimos cualquier subnivel dentro de Commons lo haremos indicando la

numeración 1.x:

_buttons.scss

// Botones

//

// Muestrario de estilos de botones de bootstrap

//

// .btn-custom - Botón personalizado

// .btn-primary - Bootstrap Primary

// .btn-success - Bootstrap Success

// .btn-info - Bootstrap Info

// .btn-warning - Bootstrap Warning

// .btn-danger - Bootstrap Danger

// .btn-link - Bootstrap Link

// .btn-default - Comportamiento estándar de botón de Bootstrap

//

// markup:

// <button class="btn {$modifiers}">

// Texto del botón

// </button>

//

// Styleguide 1.1

Con la estructura de comentarios anterior, estamos indicando todas las distintas clases disponibles

para nuestro elemento, en este caso los botones. Además le estamos indicando el código necesario

Doc.: document.docx Título: Front-End - Herramientas y Entorno UXVersión: 1.6Fecha: 21/12/2016

Página 46 de 47

Page 47: Front End: Herramientas y Entorno UX

para generar correctamente los botones, así KSS se encargará de generar un botón con el código

que le especifiquemos por cada una de las clases disponibles que también hemos especificado:

Doc.: document.docx Título: Front-End - Herramientas y Entorno UXVersión: 1.6Fecha: 21/12/2016

Página 47 de 47