|
const { src, dest, watch, series, parallel } = require('gulp'); |
|
const sass = require('gulp-sass')(require('sass')); |
|
const autoprefixer = require('autoprefixer'); |
|
const postcss = require('gulp-postcss'); |
|
const sourcemaps = require('gulp-sourcemaps'); |
|
const cssnano = require('cssnano'); |
|
const concat = require('gulp-concat'); |
|
const terser = require('gulp-terser-js'); |
|
const rename = require('gulp-rename'); |
|
const cache = require('gulp-cache'); |
|
const imagemin = require('gulp-imagemin'); |
|
const notify = require('gulp-notify'); |
|
const sharp = require('sharp'); |
|
const path = require('path'); |
|
|
|
// Definición de rutas |
|
const paths = { |
|
scss: 'src/scss/**/*.scss', |
|
js: 'src/js/**/*.js', |
|
imagenes: 'src/img/**/*.{jpg,jpeg,png,webp}' |
|
}; |
|
|
|
// Compilar Sass |
|
function css() { |
|
return src(paths.scss) |
|
.pipe(sourcemaps.init()) |
|
.pipe(sass().on('error', sass.logError)) |
|
.pipe(postcss([autoprefixer(), cssnano()])) |
|
.pipe(sourcemaps.write('.')) |
|
.pipe(dest('build/css')); |
|
} |
|
|
|
// Procesar JavaScript |
|
function javascript() { |
|
return src(paths.js) |
|
.pipe(sourcemaps.init()) |
|
.pipe(concat('bundle.js')) |
|
.pipe(terser()) |
|
.pipe(rename({ basename: 'bundle.min' })) |
|
.pipe(dest('build/js')) |
|
.pipe(rename({ extname: '.map' })) |
|
.pipe(dest('build/js')); |
|
} |
|
|
|
// Optimizar imágenes originales |
|
function imagenes() { |
|
return src('src/img/**/*.{jpg,jpeg,png,webp}') |
|
.pipe(cache(imagemin({ optimizationLevel: 3 }))) |
|
.pipe(dest('build/img')) |
|
.pipe(notify({ message: 'Imagen optimizada: <%= file.relative %>' })); |
|
} |
|
|
|
// Función auxiliar: convertir a WebP |
|
async function convertirWebp(ruta) { |
|
const outputPath = ruta.replace('src/img', 'build/img').replace(/\.(jpe?g|png)$/i, '.webp'); |
|
await sharp(ruta).webp({ quality: 50 }).toFile(outputPath); |
|
} |
|
|
|
// Función auxiliar: convertir a AVIF |
|
async function convertirAvif(ruta) { |
|
const outputPath = ruta.replace('src/img', 'build/img').replace(/\.(jpe?g|png)$/i, '.avif'); |
|
await sharp(ruta).avif({ quality: 50, effort: 4 }).toFile(outputPath); |
|
} |
|
|
|
// Tarea: procesar imágenes y generar formatos modernos |
|
async function procesarImagenes(done) { |
|
await imagenes(); |
|
done(); |
|
} |
|
|
|
// Watch: vigila cambios y ejecuta tareas |
|
function watchArchivos() { |
|
watch(paths.scss, css); |
|
watch(paths.js, javascript); |
|
watch(paths.imagenes, procesarImagenes); |
|
|
|
// Vigila cambios en JPG/PNG para generar WebP y AVIF |
|
watch('src/img/**/*.{jpg,jpeg,png}', async (event) => { |
|
const ruta = event.path || event; |
|
await convertirWebp(ruta); |
|
await convertirAvif(ruta); |
|
console.log(`✅ Formatos generados para: ${path.basename(ruta)}`); |
|
}); |
|
} |
|
|
|
// Exportar tareas |
|
exports.css = css; |
|
exports.javascript = javascript; |
|
exports.imagenes = imagenes; |
|
exports.procesarImagenes = procesarImagenes; |
|
exports.watchArchivos = watchArchivos; |
|
|
|
// Tarea por defecto |
|
exports.default = parallel(css, javascript, procesarImagenes, watchArchivos); |