Gulp 4 + Browser-sync programando para varios navegadores

2020-12-04 - Categorías: JavaScript
Testing Browser-sync

Ando poniéndome al día de nuevo, con este howto o codekata, mientras que les comparto en este post sobre estas joyas de la informática. Se trata de Browser-sync y de Gulp, herramientas para desarrollar localmente más rápido páginas web.

Con Browser-sync nos evitamos el continuo F5 para refrescar los navegadores con cada cambio mientras que trabajamos, además de que podemos probar en múltiples dispositivos las páginas web mientras que vamos construyendo. Y además con Gulp, podemos tener programadas una serie de rutinas de trabajo, como combinar hojas de estilo, ficheros JavaScript, minificarlos, etc.. para así poder trabajar también más rápido y mejor.

No he encontrado por Internet un howto para Gulp 4, así que aquí estoy compartiéndolo mientras que he conseguido hacerlo funcionar. Con este howto, queda programado en Gulp el lanzamiento de Browser-sync, junto con unas rutinas básicas de JavaScript y CSS, para un entorno básico de página web.

Al grano, qué necesitamos

Tanto Gulp como Browser-sync, son herramientas construidas en JavaScript, con lo que necesitamos el runtime de Nodejs instalado localmente.

Por otro lado necesitamos el entorno de programación, y los navegadores que vayamos a usar.

Instalando las herramientas

Doy por hecho que si estas aquí ya tienes instalado Nodejs. Si no me remito a un posta anterior donde escribí sobre Nodejs.

Necesitamos instalar los paquetes con NPM que hacen falta para que funcione. Podemos hacer lo siguiente en el directorio del proyecto:

npm init

..y seguimos las instrucciones para crear el fichero package.json con su package-lock.json que contendrá las configuraciones de Nodejs.

Lo siguiente es instalar las dependencias. Para este post, he probado con los siguientes paquetes:

npm install --save gulp browser-sync gulp-sass gulp-clean-css gulp-concat gulp-terser gulp-strip-comments gulp-remove-empty-lines gulp-sourcemaps gulp-rename gulp-if

..esperamos y si va bien, se instalará localmente todo grabando en packages.json la configuración del proyecto.

Empezando con Gulp

Tendremos que empezar creando el fichero gulpfile.js con una cabecera con los requires que podría ser la siguiente:

'use strict';

const gulp = require('gulp');
const { parallel } = require('gulp');
const browserSync = require('browser-sync').create();
const sass = require("gulp-sass");
const cleanCss = require("gulp-clean-css");
const concat = require('gulp-concat');
const terser = require('gulp-terser');
const strip = require('gulp-strip-comments');
const removeEmptyLines = require('gulp-remove-empty-lines');
const sourcemaps = require('gulp-sourcemaps');
const rename = require('gulp-rename');
const gulpif = require('gulp-if');

Unas rutinas para CSS y JavaScript

Para combinar ficheros SASS en un único fichero minificado CSS podría ser algo parecido a lo siguiente en el mismo fichero gulpfile.js:

function css() {
    return gulp.src('./src/scss/main.scss')
        .pipe(gulpif(useSourceMaps, sourcemaps.init()))
        .pipe(sass())
        .pipe(cleanCss({ format: 'keep-breaks' }))
        .pipe(rename('main.min.css'))
        .pipe(gulpif(useSourceMaps, sourcemaps.write()))
        .pipe(gulp.dest('./css/'))
        .pipe(browserSync.stream());
}

Para hacer lo mismo con JavaScript, necesitaremos una función en Gulp parecida a lo siguiente:

function js() {
    let javascriptSources = [
        './src/js/app.js',
        './src/js/app-secondary.js',
        './src/js/app-secondary-other.js',
    ];
    return gulp.src(javascriptSources)
        .pipe(gulpif(useSourceMaps, sourcemaps.init()))
        .pipe(strip())
        .pipe(removeEmptyLines())
        .pipe(gulpif(useMaximumCompress, terser()))
        .pipe(concat('main.min.js'))
        .pipe(gulpif(useSourceMaps, sourcemaps.write()))
        .pipe(gulp.dest('./js/'))
        .pipe(browserSync.stream());
}

Hay unas rutinas condicionales en este script con gulpif, con lo que hacen falta las variables:

const useSourceMaps = true;
const useMaximumCompress = true;

Forzando el refresco del HTML también

La siguiente función simplemente envía a Browser-sync los ficheros .html que haya en la raiz del directorio:

function html() {
    return gulp.src('./*.html')
        .pipe(browserSync.stream());
}

Esto hace falta porque si no, no refrescará los navegadores con los html, aunque no procesa Gulp los .html.

Arrancando el servidor de desarrollo de Browser-sync

La siguiente función también para el gulpfile.js es la que lanza el programa y lo pone a la escucha con unos navegadores:

function server() {
    browserSync.init({
        server: {
            baseDir: '.'
        },
        browser: ["google-chrome", "google-chrome", "firefox", "opera"]
    });
    gulp.watch(['./*.html', './css/*', './js/*'], browserSync.reload);
};

Aquí es donde podremos consultando la documentación de Browser-sync configurar a nuestro gusto Browser-sync. Aunque ya sólo con esto personalmente lo veo muy práctico.

Mira que hace una escucha de los cambios en ./*.html ./css/* y ./js/* que es cuando hace la recarga de los navegadores.

Escuchando los cambios

Queda una última tarea para lanzar las tareas automáticas cuando se escuchen cambios y enviar los resultados a Browser-sync con algo como lo siguiente:

function watchForBuildAssets() {
    gulp.watch(['./*.html', './src/scss/*', './src/js/*'], parallel('html', 'css', 'js'));
}

Esta función simplemente lanza las funciones anteriores cuando Gulp detecta cambios en los ficheros mientras programamos.

Finalmente, exportando las funciones para usarlas

exports.html = html;
exports.css = css;
exports.js = js;
exports.watchForBuildAssets = watchForBuildAssets;
exports.server = server;
exports.default = parallel(this.server, this.watchForBuildAssets);

Ya con esto podremos usar los comandos desde consola siguientes:

gulp html
gulp css
..
etcétera..
..

Y si lanzamos gulp sin parámetros, cargará finalmente todo el programa al ejecutar la tarea exportada default. La tarea default es la que lanzará en paralelo el servidor, y se pondrá a la escucha de cambios en los ficheros para procesarlos y refrescar todos los navegadores conectados al puerto localhost:3000.

Un index.html para probar

<html>

<head>
    <title>Prueba</title>
    <link rel="stylesheet" href="css/main.min.css">
</head>

<body>
    <h1>Esto es otra prueba</h1>
    <p>Aquí estamos probando de nuevo. Lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum lorem ipsum...</p>

    <div class="container">
        <div class="box"></div>
        <div class="box"></div>
        <div class="box"></div>
        <div class="box"></div>
        <div class="box"></div>
        <div class="box"></div>
    </div>

    <script src="js/main.min.js"></script>
</body>

</html>

El fichero completo Gulp

Para que todo funcione necesitamos una estructura de directorios con unos ficheros mínimos o editar el gulpfile.js para hacerlo funcionar:

css/
js/
src/js/app.js
src/js/app-secondary.js
src/js/app-secondary-other.js
src/scss/main.scss
index.html

Y aquí el gulpfile.js completo:

'use strict';

const gulp = require('gulp');
const { parallel } = require('gulp');
const browserSync = require('browser-sync').create();
const sass = require("gulp-sass");
const cleanCss = require("gulp-clean-css");
const concat = require('gulp-concat');
const terser = require('gulp-terser');
const strip = require('gulp-strip-comments');
const removeEmptyLines = require('gulp-remove-empty-lines');
const sourcemaps = require('gulp-sourcemaps');
const rename = require('gulp-rename');
const gulpif = require('gulp-if');

const useSourceMaps = true;
const useMaximumCompress = true;

function html() {
    return gulp.src('./*.html')
        .pipe(browserSync.stream());
}

function css() {
    return gulp.src('./src/scss/main.scss')
        .pipe(gulpif(useSourceMaps, sourcemaps.init()))
        .pipe(sass())
        .pipe(cleanCss({ format: 'keep-breaks' }))
        .pipe(rename('main.min.css'))
        .pipe(gulpif(useSourceMaps, sourcemaps.write()))
        .pipe(gulp.dest('./css/'))
        .pipe(browserSync.stream());
}

function js() {
    let javascriptSources = [
        './src/js/app.js',
        './src/js/app-secondary.js',
        './src/js/app-secondary-other.js',
    ];
    return gulp.src(javascriptSources)
        .pipe(gulpif(useSourceMaps, sourcemaps.init()))
        .pipe(strip())
        .pipe(removeEmptyLines())
        .pipe(gulpif(useMaximumCompress, terser()))
        .pipe(concat('main.min.js'))
        .pipe(gulpif(useSourceMaps, sourcemaps.write()))
        .pipe(gulp.dest('./js/'))
        .pipe(browserSync.stream());
}

function server() {
    browserSync.init({
        server: {
            baseDir: '.'
        },
        browser: ["google-chrome", "firefox", "opera"]
    });
    gulp.watch(['./*.html', './css/*', './js/*'], browserSync.reload);
};

function watchForBuildAssets() {
    gulp.watch(['./*.html', './src/scss/*', './src/js/*'], parallel('html', 'css', 'js'));
}

exports.html = html;
exports.css = css;
exports.js = js;
exports.watchForBuildAssets = watchForBuildAssets;
exports.server = server;
exports.default = parallel(this.server, this.watchForBuildAssets);

Terminando y referencias

Ya sólo queda remitirte a las webs oficiales de Gulp y Browser-sync:
https://gulpjs.com/
https://browsersync.io/

E invitarte a dejar un comentario, compartir, suscribirte.. 😉

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

 

© 2021 JnjSite.com - MIT license

Sitio hecho con WordPress, diseño y programación del tema por Jnj.