├── .editorconfig ├── .gitignore ├── LICENSE ├── README.md ├── gulpfile.js ├── index.html ├── keynotes ├── gulp.pdf └── http2.pdf ├── package.json └── src ├── css ├── app.scss ├── elements.scss ├── layout.scss └── vars.scss └── js ├── dom.js └── functions.js /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | insert_final_newline = true 6 | end_of_line = lf 7 | indent_size = 2 8 | indent_style = space 9 | trim_trailing_whitespace = true 10 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled binary addons (http://nodejs.org/api/addons.html) 2 | dist/ 3 | 4 | # Dependency directories 5 | node_modules -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 luisδμ 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Ejemplo de iniciación a Gulp para Adalab 2 | 3 | Podéis ver la presentación que utilicé en el taller [aquí](keynotes/gulp.pdf), en formato PDF. 4 | 5 | ## Ejecución 6 | 7 | Para usar este ejemplo hay que seguir los siguientes pasos: 8 | - Instalar Node y npm desde su [web oficial](https://nodejs.org/en/) (Windows, MacOS). También se puede hacer mediante consola ejecutando `apt-get install nodejs` (en Ubuntu o Debian) o usando [Homebrew](https://brew.sh/) (en MacOS). 9 | 10 | - Instalar todas las dependencias de npm listadas en *package.json* ejecutando `npm install`. 11 | 12 | - Instalar Gulp también de forma global ejecutando `npm -g install gulp` (puede requerir permisos de superusuario, en cuyo caso es necesario poner `sudo` delante). De este modo se podrá usar como comando de sistema. A partir de npm v5.2.0 también podemos optar por no hacer esto, y en su lugar [ejecutar `gulp` de forma local](https://medium.com/@maybekatz/introducing-npx-an-npm-package-runner-55f7d4bd282b) (el que aparece en *package.json*) usando `npx gulp` seguido de las opciones descritas a continuación. Vale para cualquier otro paquete que se pueda usar como comando de sistema sin tener que instarlarlo de forma global. 13 | 14 | - Para ejecutar las tareas que manipulan los scripts y las hojas de estilos una sóla vez, hay que ejecutar `gulp` sin argumentos (véase la tarea 'default'). 15 | 16 | - Para mantener un servidor HTTP local abierto que fuerce una recarga del navegador cada vez que haya cambios, hay que ejecutar `gulp observe`. Esto observará los cambios que se produzcan en los archivos de *src*, forzando una compilación a *dist*. A su vez, la observación de cambios en *dist* forzará una recarga del navegador. 17 | 18 | ## Notas 19 | 20 | - Se pueden instalar plugins adicionales mediante `npm install nombre-del-plugin` y cargarlos en *gulpfile.js*. Podéis encontrar muchos [aquí](https://gulpjs.com/plugins/). A partir de la versión 5 de npm (Node 8.x) se añadirán automáticamente al *package.json* (para versiones previas usar `npm install --save nombre-del-plugin`). Como los plugins de Gulp no dejan de ser módulos de npm, también podéis buscar [aquí](https://www.npmjs.com/). 21 | 22 | - El archivo *.gitignore* evita que tanto *node_modules* como *dist* sean versionados por Git. El motivo es que, como norma general, únicamente debemos subir a nuestro repo el código que hemos hecho nosotros, no el que ha hecho otra gente (ya está en sus respectivos repos y lo traemos mediante `npm install`) ni el que se genera automáticamente (ya lo generamos mediante `gulp`). 23 | 24 | - Algunas de vosotras teníais problemas al intentar ver el directorio *node_modules* desde Atom. No he encontrado ninguna info al respecto, pero podéis probar a actualizar vuestros editores a la última versión, por si fuese algún bug, o también probar algún editor alternativo ([VSCode](https://code.visualstudio.com/), [Sublime](http://www.sublimetext.com/)) para descartar otros problemas. 25 | 26 | - Hay algunos flujos de trabajo que van cambiando con el tiempo, ya que algunos se irán volviendo innecesarios y otros nuevos les reemplazarán. Es el caso, por ejemplo, de la concatenación de archivos, que es muy positiva en HTTP 1.1, pero innecesaria, e incluso contraproducente, en HTTP 2. Ocurre lo mismo con los *sprites* o concatenación de imágenes. Para saber más sobre el funcionamiento de HTTP y su influencia en el desarrollo web, recomiendo leer los capítulos dedicados a HTTP del libro [High Performance Browser Networking](http://chimera.labs.oreilly.com/books/1230000000545/index.html) de Ilya Grigorik, o echar un ojo a otra de mis presentaciones que resume el tema [aquí](keynotes/http2.pdf). 27 | 28 | ## Referencias 29 | 30 | - [Gulp for Beginners](https://css-tricks.com/gulp-for-beginners/) (CSS-Tricks). 31 | - [Diagramas de fujo de HTTP 1.1 y HTTP 2](https://twitter.com/kosamari/status/859958929484337152). 32 | 33 | ## Tiras cómicas :) 34 | 35 | - [Nodecalypse](https://webangelist.ladybenko.net/nodecalypse/), de Belén Albeza, al hilo de lo que ocurrió en el [npmgate](http://www.businessinsider.com/npm-left-pad-controversy-explained-2016-3). 36 | - [NPM Delivery](http://www.monkeyuser.com/2017/npm-delivery/), de MonkeyUser. 37 | - [Sandwich](https://www.xkcd.com/149/), de xkcd. 38 | -------------------------------------------------------------------------------- /gulpfile.js: -------------------------------------------------------------------------------- 1 | // Gulp local (devuelve un objeto 'gulp' con todos sus métodos) 2 | var gulp = require('gulp'); 3 | 4 | // Plugins de Gulp (devuelven funciones encadenables con .pipe()) 5 | var concat = require('gulp-concat'); 6 | var uglify = require('gulp-uglify'); 7 | var rename = require('gulp-rename'); 8 | var sass = require('gulp-sass'); 9 | var cleanCss = require('gulp-clean-css'); 10 | 11 | // Otros módulos de npm (no encadenables con .pipe(), pueden devolver funciones o cualquier otra cosa) 12 | var browserSync = require('browser-sync'); 13 | 14 | // Tarea que manipula los scripts de Javascript 15 | gulp.task('script', function () { 16 | gulp.src('src/js/*.js') // Leo todos los archivos .js del directorio fuente 17 | .pipe(concat('app.js')) // Los junto todos en uno solo 18 | .pipe(uglify()) // Minifico el archivo resultante 19 | .pipe(rename('app.min.js')) // Le cambio el nombre 20 | .pipe(gulp.dest('dist/js')); // Lo escribo en el directorio destino 21 | }); 22 | 23 | // Tarea que manipula las hojas de estilos 24 | gulp.task('style', function () { 25 | gulp.src('src/css/app.scss') // Leo el archivo principal, el que contiene los includes 26 | .pipe(sass()) // Compilo el resultado a CSS, obteniendo ya un sólo archivo 27 | .pipe(cleanCss()) // Minifico el fichero resultante 28 | .pipe(rename('app.min.css')) // Le cambio el nombre 29 | .pipe(gulp.dest('dist/css')); // Lo escribo en el directorio destino 30 | }); 31 | 32 | // Tarea que ejecuta las dos anteriores de forma secuencial, se ejecuta al invocar 'gulp' sin argumentos 33 | gulp.task('default', ['script', 'style']); 34 | 35 | // Tarea que observa cambios en 'src' 36 | // En su primera ejecución lanzará también las dos tareas previas y el autoreload 37 | gulp.task('observe', ['script', 'style', 'autoreload'], function () { 38 | gulp.watch('src/css/*.scss', ['style']); // Lanza la tarea 'style' cuando observa cambios en cualquer scss 39 | gulp.watch('src/js/*.js', ['script']); // Lanza la tarea 'script' cuando observa cambios en cualquier js 40 | }); 41 | 42 | // Tarea que observa cambios en 'dist' generados desde la tarea anterior 43 | // Recarga automáticamente el navegador 44 | gulp.task('autoreload', function () { 45 | // Abre un servidor HTTP en localhost cuya raíz será nuestro directorio de tabajo 46 | // Esto es ecesario para hacer la recarga automática mediante websockets 47 | browserSync.init(['dist/css/**.css', 'dist/js/**.js', 'index.html'], { 48 | server: './' 49 | }); 50 | }); 51 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 |
5 | 6 | 7 |