Gulp Cheatsheet¶
¶
¶
> > > > > > > "Clase de inscripción" Gulp es un kit de herramientas para automatizar tareas dolorosas o que consumen mucho tiempo en su flujo de trabajo de desarrollo, por lo que puede dejar de jugar y construir algo. Utiliza los flujos Node.js, haciendo construye más rápido evitando la necesidad de escribir archivos temporales al disco. ▪/p] ■/div titulada
¶
########################################################################################################################################################################################################################################################## Copiar todos los comandos¶
########################################################################################################################################################################################################################################################## Generar PDF seleccionado/button¶
■/div titulada ■/div titulada
Cuadro de contenidos¶
- Instalación
- Empezar
- Core Concepts
- Tareas básicas
- File Operations
- CSS Processing
- JavaScript Processing
- Optimización de imagen
- HTML Processing
- Development Server
- Watch Tasks
- Build Pipeline
- Plugin Ecosystem
- Patrones avanzados
- Perfeccionamiento Optimización
- Manejo del espejo
- Testing
- Deployment
- Las mejores prácticas
Instalación¶
Instalación global¶
Instalación local¶
# Initialize npm project
npm init -y
# Install Gulp locally
npm install --save-dev gulp
# Install common plugins
npm install --save-dev gulp-sass gulp-uglify gulp-concat gulp-clean-css
Configuración de proyectos¶
# Create project structure
mkdir my-gulp-project
cd my-gulp-project
# Initialize package.json
npm init -y
# Install Gulp and plugins
npm install --save-dev gulp gulp-sass gulp-autoprefixer gulp-clean-css gulp-uglify gulp-concat gulp-imagemin gulp-htmlmin
# Create gulpfile
touch gulpfile.js
# Create source directories
mkdir -p src/{scss,js,images,html}
mkdir dist
Paquete.json Scripts¶
{
"name": "my-gulp-project",
"version": "1.0.0",
"scripts": {
"build": "gulp build",
"dev": "gulp dev",
"watch": "gulp watch",
"clean": "gulp clean",
"serve": "gulp serve"
},
"devDependencies": {
"gulp": "^4.0.2",
"gulp-sass": "^5.1.0",
"gulp-autoprefixer": "^8.0.0",
"gulp-clean-css": "^4.3.0",
"gulp-uglify": "^3.0.2",
"gulp-concat": "^2.6.1",
"gulp-imagemin": "^8.0.0",
"gulp-htmlmin": "^5.0.1"
}
}
Comienzo¶
Basic Gulpfile¶
// gulpfile.js
const gulp = require('gulp');
const sass = require('gulp-sass')(require('sass'));
const cleanCSS = require('gulp-clean-css');
const uglify = require('gulp-uglify');
const concat = require('gulp-concat');
// Define paths
const paths = {
styles: {
src: 'src/scss/**/*.scss',
dest: 'dist/css/'
},
scripts: {
src: 'src/js/**/*.js',
dest: 'dist/js/'
}
};
// Compile Sass
function styles() {
return gulp.src(paths.styles.src)
.pipe(sass().on('error', sass.logError))
.pipe(cleanCSS())
.pipe(gulp.dest(paths.styles.dest));
}
// Process JavaScript
function scripts() {
return gulp.src(paths.scripts.src)
.pipe(concat('main.js'))
.pipe(uglify())
.pipe(gulp.dest(paths.scripts.dest));
}
// Watch files
function watch() {
gulp.watch(paths.styles.src, styles);
gulp.watch(paths.scripts.src, scripts);
}
// Export tasks
exports.styles = styles;
exports.scripts = scripts;
exports.watch = watch;
exports.build = gulp.parallel(styles, scripts);
exports.default = gulp.series(exports.build, watch);
Running Tasks¶
# Run individual tasks
gulp styles
gulp scripts
# Run build task
gulp build
# Run default task (build + watch)
gulp
# Run with specific gulpfile
gulp --gulpfile custom.gulpfile.js
# List available tasks
gulp --tasks
Estructura del proyecto¶
my-gulp-project/
├── src/
│ ├── scss/
│ │ ├── main.scss
│ │ ├── _variables.scss
│ │ └── components/
│ ├── js/
│ │ ├── main.js
│ │ └── modules/
│ ├── images/
│ └── html/
├── dist/
│ ├── css/
│ ├── js/
│ ├── images/
│ └── index.html
├── gulpfile.js
└── package.json
Conceptos básicos¶
Corrientes y tubos¶
// Basic stream example
gulp.src('src/**/*.js') // Read files
.pipe(uglify()) // Transform
.pipe(gulp.dest('dist/')); // Write files
// Multiple transformations
gulp.src('src/scss/**/*.scss')
.pipe(sass()) // Compile Sass
.pipe(autoprefixer()) // Add vendor prefixes
.pipe(cleanCSS()) // Minify CSS
.pipe(gulp.dest('dist/css/'));
Glob Patterns¶
// Glob pattern examples
gulp.src('src/*.js') // All .js files in src/
gulp.src('src/**/*.js') // All .js files in src/ and subdirectories
gulp.src('src/js/*.{js,ts}') // All .js and .ts files in src/js/
gulp.src(['src/**/*.js', '!src/vendor/**']) // Exclude vendor directory
// Multiple sources
gulp.src([
'src/js/vendor/*.js',
'src/js/main.js',
'src/js/modules/*.js'
])
Funciones de tareas¶
// Named function
function buildCSS() {
return gulp.src('src/scss/**/*.scss')
.pipe(sass())
.pipe(gulp.dest('dist/css/'));
}
// Arrow function
const buildJS = () => {
return gulp.src('src/js/**/*.js')
.pipe(uglify())
.pipe(gulp.dest('dist/js/'));
};
// Async function
async function copyFiles() {
return gulp.src('src/assets/**/*')
.pipe(gulp.dest('dist/assets/'));
}
// Export tasks
exports.css = buildCSS;
exports.js = buildJS;
exports.copy = copyFiles;
Serie y paralelo¶
const { series, parallel } = require('gulp');
// Run tasks in series (one after another)
const build = series(clean, parallel(styles, scripts), copyAssets);
// Run tasks in parallel (simultaneously)
const dev = parallel(styles, scripts, serve, watch);
// Mixed series and parallel
const deploy = series(
clean,
parallel(styles, scripts, images),
copyFiles,
uploadToServer
);
exports.build = build;
exports.dev = dev;
exports.deploy = deploy;
Tareas básicas¶
Copia del archivo¶
// Simple file copy
function copyHTML() {
return gulp.src('src/**/*.html')
.pipe(gulp.dest('dist/'));
}
// Copy with base option
function copyAssets() {
return gulp.src('src/assets/**/*', { base: 'src' })
.pipe(gulp.dest('dist/'));
}
// Copy specific files
function copyFonts() {
return gulp.src([
'src/fonts/**/*.{woff,woff2,ttf,eot}',
'node_modules/font-awesome/fonts/**/*'
])
.pipe(gulp.dest('dist/fonts/'));
}
Limpieza de archivos¶
const del = require('del');
// Clean build directory
function clean() {
return del(['dist/**', '!dist']);
}
// Clean specific files
function cleanCSS() {
return del(['dist/css/**/*.css']);
}
// Clean with patterns
function cleanOld() {
return del([
'dist/**',
'!dist/vendor',
'!dist/vendor/**'
]);
}
exports.clean = clean;
Renaming del archivo¶
const rename = require('gulp-rename');
// Add suffix
function minifyCSS() {
return gulp.src('src/css/**/*.css')
.pipe(cleanCSS())
.pipe(rename({ suffix: '.min' }))
.pipe(gulp.dest('dist/css/'));
}
// Change extension
function compileTypeScript() {
return gulp.src('src/**/*.ts')
.pipe(typescript())
.pipe(rename({ extname: '.js' }))
.pipe(gulp.dest('dist/js/'));
}
// Custom rename function
function customRename() {
return gulp.src('src/**/*.scss')
.pipe(sass())
.pipe(rename((path) => {
path.dirname += '/compiled';
path.basename += '-processed';
}))
.pipe(gulp.dest('dist/css/'));
}
Operaciones de archivo¶
File Concatenation¶
const concat = require('gulp-concat');
// Concatenate JavaScript files
function concatJS() {
return gulp.src([
'src/js/vendor/*.js',
'src/js/modules/*.js',
'src/js/main.js'
])
.pipe(concat('bundle.js'))
.pipe(gulp.dest('dist/js/'));
}
// Concatenate CSS files
function concatCSS() {
return gulp.src('src/css/**/*.css')
.pipe(concat('styles.css'))
.pipe(gulp.dest('dist/css/'));
}
// Conditional concatenation
function buildVendorJS() {
return gulp.src([
'node_modules/jquery/dist/jquery.min.js',
'node_modules/bootstrap/dist/js/bootstrap.min.js',
'src/js/vendor/*.js'
])
.pipe(concat('vendor.js'))
.pipe(gulp.dest('dist/js/'));
}
Filtro de archivos¶
const gulpif = require('gulp-if');
const filter = require('gulp-filter');
// Conditional processing
function processFiles() {
const isProduction = process.env.NODE_ENV === 'production';
return gulp.src('src/js/**/*.js')
.pipe(gulpif(isProduction, uglify()))
.pipe(gulp.dest('dist/js/'));
}
// Filter specific files
function processAssets() {
const jsFilter = filter('**/*.js', { restore: true });
const cssFilter = filter('**/*.css', { restore: true });
return gulp.src('src/**/*')
.pipe(jsFilter)
.pipe(uglify())
.pipe(jsFilter.restore)
.pipe(cssFilter)
.pipe(cleanCSS())
.pipe(cssFilter.restore)
.pipe(gulp.dest('dist/'));
}
Transformación de archivos¶
const replace = require('gulp-replace');
const template = require('gulp-template');
// String replacement
function updateVersion() {
return gulp.src('src/**/*.js')
.pipe(replace('{{VERSION}}', process.env.npm_package_version))
.pipe(gulp.dest('dist/js/'));
}
// Template processing
function processTemplates() {
return gulp.src('src/templates/**/*.html')
.pipe(template({
title: 'My Website',
version: '1.0.0',
timestamp: new Date().toISOString()
}))
.pipe(gulp.dest('dist/'));
}
// Multiple replacements
function processConfig() {
return gulp.src('src/config.js')
.pipe(replace('{{API_URL}}', process.env.API_URL || 'http://localhost:3000'))
.pipe(replace('{{DEBUG}}', process.env.NODE_ENV === 'development'))
.pipe(gulp.dest('dist/js/'));
}
CSS Procesamiento¶
Sass Compilation¶
const sass = require('gulp-sass')(require('sass'));
const autoprefixer = require('gulp-autoprefixer');
const cleanCSS = require('gulp-clean-css');
const sourcemaps = require('gulp-sourcemaps');
// Basic Sass compilation
function compileSass() {
return gulp.src('src/scss/**/*.scss')
.pipe(sass().on('error', sass.logError))
.pipe(gulp.dest('dist/css/'));
}
// Advanced Sass processing
function processCSS() {
return gulp.src('src/scss/main.scss')
.pipe(sourcemaps.init())
.pipe(sass({
outputStyle: 'expanded',
includePaths: ['node_modules']
}).on('error', sass.logError))
.pipe(autoprefixer({
cascade: false
}))
.pipe(sourcemaps.write('.'))
.pipe(gulp.dest('dist/css/'))
.pipe(cleanCSS())
.pipe(rename({ suffix: '.min' }))
.pipe(sourcemaps.write('.'))
.pipe(gulp.dest('dist/css/'));
}
// Production CSS build
function buildProductionCSS() {
return gulp.src('src/scss/**/*.scss')
.pipe(sass({
outputStyle: 'compressed',
includePaths: ['node_modules/bootstrap/scss']
}))
.pipe(autoprefixer({
browsers: ['last 2 versions', '> 1%'],
cascade: false
}))
.pipe(cleanCSS({
level: 2
}))
.pipe(gulp.dest('dist/css/'));
}
PostCSS Procesamiento¶
const postcss = require('gulp-postcss');
const autoprefixer = require('autoprefixer');
const cssnano = require('cssnano');
const tailwindcss = require('tailwindcss');
// PostCSS with plugins
function processPostCSS() {
const plugins = [
tailwindcss(),
autoprefixer(),
cssnano()
];
return gulp.src('src/css/**/*.css')
.pipe(postcss(plugins))
.pipe(gulp.dest('dist/css/'));
}
// Tailwind CSS processing
function buildTailwind() {
return gulp.src('src/css/tailwind.css')
.pipe(postcss([
tailwindcss('./tailwind.config.js'),
autoprefixer(),
...(process.env.NODE_ENV === 'production' ? [cssnano()] : [])
]))
.pipe(gulp.dest('dist/css/'));
}
CSS Optimización¶
const purgecss = require('gulp-purgecss');
const critical = require('critical');
// Remove unused CSS
function purgeCSS() {
return gulp.src('dist/css/**/*.css')
.pipe(purgecss({
content: ['dist/**/*.html', 'dist/**/*.js'],
safelist: ['active', 'show', /^carousel-/]
}))
.pipe(gulp.dest('dist/css/'));
}
// Extract critical CSS
function extractCritical() {
return critical.generate({
base: 'dist/',
src: 'index.html',
dest: 'css/critical.css',
inline: true,
width: 1300,
height: 900
});
}
// CSS linting
const stylelint = require('gulp-stylelint');
function lintCSS() {
return gulp.src('src/scss/**/*.scss')
.pipe(stylelint({
reporters: [
{ formatter: 'string', console: true }
]
}));
}
Procesamiento de JavaScript¶
JavaScript básico Procesamiento¶
const uglify = require('gulp-uglify');
const babel = require('gulp-babel');
const concat = require('gulp-concat');
// Basic JavaScript minification
function minifyJS() {
return gulp.src('src/js/**/*.js')
.pipe(uglify())
.pipe(gulp.dest('dist/js/'));
}
// Babel transpilation
function transpileJS() {
return gulp.src('src/js/**/*.js')
.pipe(babel({
presets: ['@babel/env']
}))
.pipe(gulp.dest('dist/js/'));
}
// Complete JavaScript pipeline
function processJS() {
return gulp.src('src/js/**/*.js')
.pipe(sourcemaps.init())
.pipe(babel({
presets: ['@babel/env']
}))
.pipe(concat('bundle.js'))
.pipe(sourcemaps.write('.'))
.pipe(gulp.dest('dist/js/'))
.pipe(uglify())
.pipe(rename({ suffix: '.min' }))
.pipe(sourcemaps.write('.'))
.pipe(gulp.dest('dist/js/'));
}
Procesamiento TipoScript¶
const typescript = require('gulp-typescript');
// TypeScript compilation
function compileTypeScript() {
const tsProject = typescript.createProject('tsconfig.json');
return tsProject.src()
.pipe(tsProject())
.js
.pipe(gulp.dest('dist/js/'));
}
// TypeScript with source maps
function buildTypeScript() {
const tsProject = typescript.createProject('tsconfig.json');
return gulp.src('src/ts/**/*.ts')
.pipe(sourcemaps.init())
.pipe(tsProject())
.pipe(sourcemaps.write('.'))
.pipe(gulp.dest('dist/js/'));
}
JavaScript Bundling¶
const browserify = require('browserify');
const source = require('vinyl-source-stream');
const buffer = require('vinyl-buffer');
// Browserify bundling
function bundleJS() {
return browserify({
entries: 'src/js/main.js',
debug: true
})
.bundle()
.pipe(source('bundle.js'))
.pipe(buffer())
.pipe(sourcemaps.init({ loadMaps: true }))
.pipe(uglify())
.pipe(sourcemaps.write('./'))
.pipe(gulp.dest('dist/js/'));
}
// Webpack integration
const webpack = require('webpack-stream');
function webpackBundle() {
return gulp.src('src/js/main.js')
.pipe(webpack({
mode: 'production',
output: {
filename: 'bundle.js'
},
module: {
rules: [
{
test: /\.js$/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env']
}
}
}
]
}
}))
.pipe(gulp.dest('dist/js/'));
}
JavaScript Linting¶
const eslint = require('gulp-eslint');
const jshint = require('gulp-jshint');
// ESLint
function lintJS() {
return gulp.src('src/js/**/*.js')
.pipe(eslint())
.pipe(eslint.format())
.pipe(eslint.failAfterError());
}
// JSHint
function hintJS() {
return gulp.src('src/js/**/*.js')
.pipe(jshint())
.pipe(jshint.reporter('default'))
.pipe(jshint.reporter('fail'));
}
// Combined linting
function checkJS() {
return gulp.src('src/js/**/*.js')
.pipe(eslint())
.pipe(eslint.format())
.pipe(jshint())
.pipe(jshint.reporter('default'));
}
Optimización de imagen¶
Procesamiento de imagen básica¶
const imagemin = require('gulp-imagemin');
const webp = require('gulp-webp');
const responsive = require('gulp-responsive');
// Basic image optimization
function optimizeImages() {
return gulp.src('src/images/**/*')
.pipe(imagemin([
imagemin.gifsicle({ interlaced: true }),
imagemin.mozjpeg({ quality: 75, progressive: true }),
imagemin.optipng({ optimizationLevel: 5 }),
imagemin.svgo({
plugins: [
{ removeViewBox: true },
{ cleanupIDs: false }
]
})
]))
.pipe(gulp.dest('dist/images/'));
}
// WebP conversion
function generateWebP() {
return gulp.src('src/images/**/*.{jpg,jpeg,png}')
.pipe(webp())
.pipe(gulp.dest('dist/images/webp/'));
}
// Responsive images
function createResponsiveImages() {
return gulp.src('src/images/**/*.{jpg,jpeg,png}')
.pipe(responsive({
'**/*': [
{
width: 320,
rename: { suffix: '-small' }
},
{
width: 640,
rename: { suffix: '-medium' }
},
{
width: 1024,
rename: { suffix: '-large' }
},
{
width: 1920,
rename: { suffix: '-xlarge' }
}
]
}))
.pipe(gulp.dest('dist/images/responsive/'));
}
Procesamiento avanzado de imagen¶
const sharp = require('gulp-sharp-responsive');
const sprite = require('gulp.spritesmith');
// Sharp image processing
function processWithSharp() {
return gulp.src('src/images/**/*.{jpg,jpeg,png}')
.pipe(sharp({
formats: [
{ format: 'jpeg', options: { quality: 80 } },
{ format: 'webp', options: { quality: 80 } }
]
}))
.pipe(gulp.dest('dist/images/'));
}
// CSS Sprites
function createSprites() {
const spriteData = gulp.src('src/images/icons/*.png')
.pipe(sprite({
imgName: 'sprite.png',
cssName: 'sprite.css',
imgPath: '../images/sprite.png'
}));
spriteData.img.pipe(gulp.dest('dist/images/'));
spriteData.css.pipe(gulp.dest('dist/css/'));
return spriteData;
}
// SVG sprites
const svgSprite = require('gulp-svg-sprite');
function createSVGSprites() {
return gulp.src('src/images/icons/*.svg')
.pipe(svgSprite({
mode: {
symbol: {
dest: '.',
sprite: 'sprite.svg'
}
}
}))
.pipe(gulp.dest('dist/images/'));
}
Procesamiento HTML¶
Minificación HTML¶
const htmlmin = require('gulp-htmlmin');
const fileinclude = require('gulp-file-include');
const replace = require('gulp-replace');
// Basic HTML minification
function minifyHTML() {
return gulp.src('src/**/*.html')
.pipe(htmlmin({
collapseWhitespace: true,
removeComments: true,
removeRedundantAttributes: true,
removeScriptTypeAttributes: true,
removeStyleLinkTypeAttributes: true,
useShortDoctype: true
}))
.pipe(gulp.dest('dist/'));
}
// HTML includes
function processHTML() {
return gulp.src('src/pages/*.html')
.pipe(fileinclude({
prefix: '@@',
basepath: '@file'
}))
.pipe(gulp.dest('dist/'));
}
// HTML templating
function buildHTML() {
return gulp.src('src/templates/*.html')
.pipe(replace('{{TITLE}}', 'My Website'))
.pipe(replace('{{VERSION}}', process.env.npm_package_version))
.pipe(htmlmin({
collapseWhitespace: true,
removeComments: true
}))
.pipe(gulp.dest('dist/'));
}
Validación y procesamiento HTML¶
const htmlhint = require('gulp-htmlhint');
const w3cjs = require('gulp-w3cjs');
const inject = require('gulp-inject');
// HTML validation
function validateHTML() {
return gulp.src('dist/**/*.html')
.pipe(htmlhint())
.pipe(htmlhint.reporter())
.pipe(w3cjs())
.pipe(w3cjs.reporter());
}
// Asset injection
function injectAssets() {
const target = gulp.src('src/index.html');
const sources = gulp.src(['dist/js/**/*.js', 'dist/css/**/*.css'], { read: false });
return target
.pipe(inject(sources, {
relative: true,
transform: function (filepath) {
if (filepath.slice(-3) === '.js') {
return '<script src="' + filepath + '"></script>';
}
return '<link rel="stylesheet" href="' + filepath + '">';
}
}))
.pipe(gulp.dest('dist/'));
}
Development Server¶
Configuración básica del servidor¶
const browserSync = require('browser-sync').create();
const connect = require('gulp-connect');
// Browser Sync server
function serve() {
browserSync.init({
server: {
baseDir: 'dist'
},
port: 3000,
open: true
});
}
// Connect server
function connectServer() {
connect.server({
root: 'dist',
livereload: true,
port: 8080
});
}
// Reload browser
function reload(done) {
browserSync.reload();
done();
}
Configuración avanzada del servidor¶
// Advanced Browser Sync setup
function advancedServe() {
browserSync.init({
server: {
baseDir: 'dist',
middleware: [
// Custom middleware
function(req, res, next) {
console.log('Request:', req.url);
next();
}
]
},
port: 3000,
ui: {
port: 3001
},
files: [
'dist/**/*.html',
'dist/**/*.css',
'dist/**/*.js'
],
reloadDelay: 1000,
notify: false,
ghostMode: {
clicks: true,
forms: true,
scroll: true
}
});
}
// Proxy server
function proxyServe() {
browserSync.init({
proxy: 'localhost:8080',
port: 3000,
files: ['dist/**/*'],
reloadDelay: 1000
});
}
Recarga en vivo¶
// Live reload with gulp-connect
function liveReload() {
return gulp.src('dist/**/*.html')
.pipe(connect.reload());
}
// Watch with live reload
function watchWithReload() {
gulp.watch('src/scss/**/*.scss', gulp.series(styles, reload));
gulp.watch('src/js/**/*.js', gulp.series(scripts, reload));
gulp.watch('src/**/*.html', gulp.series(copyHTML, reload));
}
// Complete development server
function dev() {
serve();
watchWithReload();
}
exports.serve = serve;
exports.dev = dev;
Tareas de reloj¶
Configuración de relojes básicos¶
// Basic watch
function watch() {
gulp.watch('src/scss/**/*.scss', styles);
gulp.watch('src/js/**/*.js', scripts);
gulp.watch('src/**/*.html', copyHTML);
gulp.watch('src/images/**/*', images);
}
// Watch with options
function watchAdvanced() {
gulp.watch('src/scss/**/*.scss', {
events: 'all',
delay: 500
}, styles);
gulp.watch('src/js/**/*.js', {
ignoreInitial: false
}, scripts);
}
Patrones de reloj avanzado¶
const chokidar = require('chokidar');
// Custom watcher
function customWatch() {
// Watch SCSS files
const scssWatcher = chokidar.watch('src/scss/**/*.scss');
scssWatcher.on('change', () => {
console.log('SCSS file changed');
styles();
});
// Watch JS files
const jsWatcher = chokidar.watch('src/js/**/*.js');
jsWatcher.on('add', () => {
console.log('JS file added');
scripts();
});
jsWatcher.on('unlink', () => {
console.log('JS file removed');
scripts();
});
}
// Conditional watching
function conditionalWatch() {
if (process.env.NODE_ENV === 'development') {
gulp.watch('src/scss/**/*.scss', gulp.series(styles, reload));
gulp.watch('src/js/**/*.js', gulp.series(lintJS, scripts, reload));
} else {
gulp.watch('src/scss/**/*.scss', styles);
gulp.watch('src/js/**/*.js', scripts);
}
}
Ver con el manejo de errores¶
const plumber = require('gulp-plumber');
const notify = require('gulp-notify');
// Error handling in watch
function watchWithErrors() {
gulp.watch('src/scss/**/*.scss', () => {
return gulp.src('src/scss/**/*.scss')
.pipe(plumber({
errorHandler: notify.onError({
title: 'Sass Error',
message: '<%= error.message %>'
})
}))
.pipe(sass())
.pipe(gulp.dest('dist/css/'))
.pipe(browserSync.stream());
});
}
// Graceful error handling
function gracefulWatch() {
gulp.watch('src/js/**/*.js', () => {
return gulp.src('src/js/**/*.js')
.pipe(plumber())
.pipe(babel())
.on('error', function(err) {
console.error('Error:', err.message);
this.emit('end');
})
.pipe(uglify())
.pipe(gulp.dest('dist/js/'));
});
}
Construir la tubería¶
Development Build¶
// Development build pipeline
const developmentBuild = gulp.series(
clean,
gulp.parallel(
copyHTML,
gulp.series(lintCSS, styles),
gulp.series(lintJS, scripts),
copyAssets,
optimizeImages
)
);
// Development with watch
const dev = gulp.series(
developmentBuild,
gulp.parallel(serve, watch)
);
exports.dev = dev;
Producción¶
// Production build pipeline
const productionBuild = gulp.series(
clean,
gulp.parallel(
minifyHTML,
buildProductionCSS,
buildProductionJS,
optimizeImages,
copyAssets
),
injectAssets,
generateSitemap
);
// Production JavaScript build
function buildProductionJS() {
return gulp.src('src/js/**/*.js')
.pipe(babel({
presets: ['@babel/env']
}))
.pipe(concat('bundle.js'))
.pipe(uglify())
.pipe(rev())
.pipe(gulp.dest('dist/js/'))
.pipe(rev.manifest())
.pipe(gulp.dest('dist/'));
}
exports.build = productionBuild;
Multi-Environment Builds¶
const gulpif = require('gulp-if');
// Environment-aware build
function buildForEnvironment() {
const isProduction = process.env.NODE_ENV === 'production';
const isDevelopment = process.env.NODE_ENV === 'development';
return gulp.src('src/js/**/*.js')
.pipe(gulpif(isDevelopment, sourcemaps.init()))
.pipe(babel())
.pipe(gulpif(isProduction, uglify()))
.pipe(gulpif(isDevelopment, sourcemaps.write('.')))
.pipe(gulp.dest('dist/js/'));
}
// Multiple environment configs
const environments = {
development: {
sourcemaps: true,
minify: false,
baseUrl: 'http://localhost:3000'
},
staging: {
sourcemaps: true,
minify: true,
baseUrl: 'https://staging.example.com'
},
production: {
sourcemaps: false,
minify: true,
baseUrl: 'https://example.com'
}
};
function buildWithConfig() {
const env = process.env.NODE_ENV || 'development';
const config = environments[env];
return gulp.src('src/**/*.js')
.pipe(gulpif(config.sourcemaps, sourcemaps.init()))
.pipe(replace('{{BASE_URL}}', config.baseUrl))
.pipe(gulpif(config.minify, uglify()))
.pipe(gulpif(config.sourcemaps, sourcemaps.write('.')))
.pipe(gulp.dest('dist/js/'));
}
Plugin Ecosystem¶
Plugins esenciales¶
# Core plugins
npm install --save-dev gulp-sass gulp-autoprefixer gulp-clean-css
npm install --save-dev gulp-uglify gulp-concat gulp-babel
npm install --save-dev gulp-imagemin gulp-htmlmin
# Utility plugins
npm install --save-dev gulp-sourcemaps gulp-rename gulp-if
npm install --save-dev gulp-plumber gulp-notify gulp-filter
# Development plugins
npm install --save-dev browser-sync gulp-connect
npm install --save-dev gulp-eslint gulp-stylelint
# Advanced plugins
npm install --save-dev gulp-rev gulp-inject gulp-replace
npm install --save-dev gulp-zip gulp-ftp gulp-s3-upload
Plugins de procesamiento de archivos¶
// File manipulation
const rev = require('gulp-rev');
const revReplace = require('gulp-rev-replace');
const size = require('gulp-size');
// Asset revisioning
function revisionAssets() {
return gulp.src(['dist/**/*.css', 'dist/**/*.js'])
.pipe(rev())
.pipe(gulp.dest('dist/'))
.pipe(rev.manifest())
.pipe(gulp.dest('dist/'));
}
// Replace revisioned assets
function replaceRevisionedAssets() {
const manifest = gulp.src('dist/rev-manifest.json');
return gulp.src('dist/**/*.html')
.pipe(revReplace({ manifest: manifest }))
.pipe(gulp.dest('dist/'));
}
// File size reporting
function reportSizes() {
return gulp.src('dist/**/*')
.pipe(size({
showFiles: true,
gzip: true
}));
}
Testing Plugins¶
const mocha = require('gulp-mocha');
const karma = require('karma').Server;
const jest = require('gulp-jest');
// Mocha tests
function runMochaTests() {
return gulp.src('test/**/*.js', { read: false })
.pipe(mocha({
reporter: 'spec'
}));
}
// Karma tests
function runKarmaTests(done) {
new karma({
configFile: __dirname + '/karma.conf.js',
singleRun: true
}, done).start();
}
// Jest tests
function runJestTests() {
return gulp.src('.')
.pipe(jest({
preprocessorIgnorePatterns: [
'<rootDir>/dist/', '<rootDir>/node_modules/'
],
automock: false
}));
}
Plugins de despliegue¶
const ftp = require('vinyl-ftp');
const s3 = require('gulp-s3-upload')();
const ghPages = require('gulp-gh-pages');
// FTP deployment
function deployFTP() {
const conn = ftp.create({
host: 'ftp.example.com',
user: process.env.FTP_USER,
password: process.env.FTP_PASSWORD,
parallel: 10
});
return gulp.src('dist/**/*', { base: 'dist', buffer: false })
.pipe(conn.newer('/public_html'))
.pipe(conn.dest('/public_html'));
}
// S3 deployment
function deployS3() {
return gulp.src('dist/**/*')
.pipe(s3({
Bucket: 'my-bucket',
ACL: 'public-read'
}));
}
// GitHub Pages deployment
function deployGitHub() {
return gulp.src('dist/**/*')
.pipe(ghPages());
}
Patrones avanzados¶
Plugins personalizados¶
const through = require('through2');
const PluginError = require('plugin-error');
// Simple custom plugin
function customPlugin(options) {
options = options || {};
return through.obj(function(file, encoding, callback) {
if (file.isNull()) {
return callback(null, file);
}
if (file.isStream()) {
return callback(new PluginError('custom-plugin', 'Streaming not supported'));
}
try {
// Process file content
const content = file.contents.toString();
const processed = content.replace(/foo/g, 'bar');
file.contents = Buffer.from(processed);
this.push(file);
callback();
} catch (err) {
callback(new PluginError('custom-plugin', err));
}
});
}
// Usage
function useCustomPlugin() {
return gulp.src('src/**/*.js')
.pipe(customPlugin({ option: 'value' }))
.pipe(gulp.dest('dist/'));
}
Stream Processing¶
const map = require('map-stream');
const transform = require('stream-transform');
// Map stream processing
function processWithMap() {
return gulp.src('src/**/*.js')
.pipe(map((file, callback) => {
// Process each file
const content = file.contents.toString();
const processed = content.toUpperCase();
file.contents = Buffer.from(processed);
callback(null, file);
}))
.pipe(gulp.dest('dist/'));
}
// Transform stream
function processWithTransform() {
return gulp.src('src/**/*.json')
.pipe(transform((file, encoding, callback) => {
try {
const data = JSON.parse(file.contents.toString());
data.processed = true;
data.timestamp = new Date().toISOString();
file.contents = Buffer.from(JSON.stringify(data, null, 2));
callback(null, file);
} catch (err) {
callback(err);
}
}))
.pipe(gulp.dest('dist/'));
}
```_
### Procesamiento condicional
```javascript
const yargs = require('yargs');
const gulpif = require('gulp-if');
// Command line arguments
const argv = yargs.argv;
function conditionalBuild() {
return gulp.src('src/**/*.js')
.pipe(gulpif(argv.lint, eslint()))
.pipe(gulpif(argv.babel, babel()))
.pipe(gulpif(argv.minify, uglify()))
.pipe(gulp.dest('dist/'));
}
// Environment-based conditions
function environmentalBuild() {
const isProduction = process.env.NODE_ENV === 'production';
const isDevelopment = !isProduction;
return gulp.src('src/**/*.js')
.pipe(gulpif(isDevelopment, sourcemaps.init()))
.pipe(babel())
.pipe(gulpif(isProduction, uglify()))
.pipe(gulpif(isDevelopment, sourcemaps.write('.')))
.pipe(gulp.dest('dist/'));
}
// File-based conditions
function fileBasedProcessing() {
return gulp.src('src/**/*')
.pipe(gulpif('*.js', uglify()))
.pipe(gulpif('*.css', cleanCSS()))
.pipe(gulpif('*.html', htmlmin()))
.pipe(gulp.dest('dist/'));
}
Optimización del rendimiento¶
Parallel Processing¶
// Parallel task execution
const parallelBuild = gulp.parallel(
styles,
scripts,
images,
copyAssets
);
// Mixed series and parallel
const optimizedBuild = gulp.series(
clean,
gulp.parallel(
gulp.series(lintCSS, styles),
gulp.series(lintJS, scripts),
images
),
injectAssets
);
exports.build = optimizedBuild;
Incremental Builds¶
const changed = require('gulp-changed');
const newer = require('gulp-newer');
// Process only changed files
function incrementalStyles() {
return gulp.src('src/scss/**/*.scss')
.pipe(changed('dist/css/', { extension: '.css' }))
.pipe(sass())
.pipe(gulp.dest('dist/css/'));
}
// Process only newer files
function incrementalImages() {
return gulp.src('src/images/**/*')
.pipe(newer('dist/images/'))
.pipe(imagemin())
.pipe(gulp.dest('dist/images/'));
}
// Cache-based processing
const cache = require('gulp-cache');
function cachedImages() {
return gulp.src('src/images/**/*')
.pipe(cache(imagemin()))
.pipe(gulp.dest('dist/images/'));
}
Optimización de memoria¶
const remember = require('gulp-remember');
const cached = require('gulp-cached');
// Cached processing with remember
function optimizedScripts() {
return gulp.src('src/js/**/*.js')
.pipe(cached('scripts'))
.pipe(eslint())
.pipe(remember('scripts'))
.pipe(concat('bundle.js'))
.pipe(gulp.dest('dist/js/'));
}
// Clear cache when needed
function clearCache() {
return cache.clearAll();
}
// Memory-efficient streaming
function streamEfficient() {
return gulp.src('src/**/*.js', { buffer: false })
.pipe(someTransform())
.pipe(gulp.dest('dist/'));
}
Manejo de errores¶
Manejo básico de errores¶
const plumber = require('gulp-plumber');
const notify = require('gulp-notify');
// Plumber for error handling
function errorHandledStyles() {
return gulp.src('src/scss/**/*.scss')
.pipe(plumber({
errorHandler: function(err) {
console.error('Error:', err.message);
this.emit('end');
}
}))
.pipe(sass())
.pipe(gulp.dest('dist/css/'));
}
// Notify on errors
function notifyOnError() {
return gulp.src('src/scss/**/*.scss')
.pipe(plumber({
errorHandler: notify.onError({
title: 'Sass Error',
message: '<%= error.message %>'
})
}))
.pipe(sass())
.pipe(gulp.dest('dist/css/'));
}
```_
### Manejo avanzado de errores
```javascript
// Custom error handler
function createErrorHandler(taskName) {
return function(err) {
console.error(`Error in ${taskName}:`, err.message);
if (err.stack) {
console.error(err.stack);
}
this.emit('end');
};
}
// Error handling with logging
const log = require('fancy-log');
const colors = require('ansi-colors');
function advancedErrorHandling() {
return gulp.src('src/js/**/*.js')
.pipe(plumber({
errorHandler: function(err) {
log.error(colors.red('JavaScript Error:'));
log.error(colors.red(err.message));
if (err.fileName) {
log.error(colors.yellow('File:'), err.fileName);
}
if (err.lineNumber) {
log.error(colors.yellow('Line:'), err.lineNumber);
}
this.emit('end');
}
}))
.pipe(babel())
.pipe(gulp.dest('dist/js/'));
}
// Graceful degradation
function gracefulBuild() {
return gulp.src('src/**/*.js')
.pipe(plumber())
.pipe(babel())
.on('error', function(err) {
log.error('Babel compilation failed, using original files');
return gulp.src('src/**/*.js')
.pipe(gulp.dest('dist/js/'));
})
.pipe(uglify())
.pipe(gulp.dest('dist/js/'));
}
Pruebas¶
Pruebas de unidad¶
const mocha = require('gulp-mocha');
const istanbul = require('gulp-istanbul');
// Run Mocha tests
function runTests() {
return gulp.src('test/**/*.js', { read: false })
.pipe(mocha({
reporter: 'spec',
timeout: 5000
}));
}
// Code coverage
function coverage() {
return gulp.src('src/**/*.js')
.pipe(istanbul())
.pipe(istanbul.hookRequire());
}
function testWithCoverage() {
return gulp.src('test/**/*.js', { read: false })
.pipe(mocha())
.pipe(istanbul.writeReports())
.pipe(istanbul.enforceThresholds({ thresholds: { global: 90 } }));
}
const testSuite = gulp.series(coverage, testWithCoverage);
exports.test = testSuite;
Pruebas de integración¶
const puppeteer = require('puppeteer');
const assert = require('assert');
// Browser testing
async function browserTest() {
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto('http://localhost:3000');
const title = await page.title();
assert.strictEqual(title, 'My Website');
await browser.close();
}
// Visual regression testing
const backstop = require('backstopjs');
function visualTest() {
return backstop('test', {
config: 'backstop.json'
});
}
// Performance testing
const lighthouse = require('lighthouse');
async function performanceTest() {
const results = await lighthouse('http://localhost:3000', {
output: 'json',
onlyCategories: ['performance']
});
const score = results.lhr.categories.performance.score * 100;
console.log('Performance Score:', score);
if (score < 90) {
throw new Error('Performance score too low');
}
}
Despliegue¶
Build and Deploy Pipeline¶
const zip = require('gulp-zip');
const ftp = require('vinyl-ftp');
// Create deployment package
function createPackage() {
return gulp.src('dist/**/*')
.pipe(zip('deploy.zip'))
.pipe(gulp.dest('packages/'));
}
// Deploy via FTP
function deployToServer() {
const conn = ftp.create({
host: process.env.FTP_HOST,
user: process.env.FTP_USER,
password: process.env.FTP_PASSWORD,
parallel: 10,
log: console.log
});
return gulp.src('dist/**/*', { base: 'dist', buffer: false })
.pipe(conn.newer('/public_html'))
.pipe(conn.dest('/public_html'));
}
// Complete deployment pipeline
const deploy = gulp.series(
productionBuild,
runTests,
createPackage,
deployToServer
);
exports.deploy = deploy;
CI/CD Integration¶
// Environment-aware deployment
function deployToEnvironment() {
const env = process.env.NODE_ENV || 'development';
const configs = {
development: {
host: 'dev.example.com',
path: '/dev'
},
staging: {
host: 'staging.example.com',
path: '/staging'
},
production: {
host: 'example.com',
path: '/public_html'
}
};
const config = configs[env];
return gulp.src('dist/**/*')
.pipe(deployTo(config));
}
// Docker deployment
function buildDockerImage() {
return gulp.src(['dist/**/*', 'Dockerfile'])
.pipe(docker.build({
tag: 'my-app:latest'
}));
}
// Kubernetes deployment
function deployToK8s() {
return gulp.src('k8s/*.yaml')
.pipe(kubectl.apply());
}
Buenas prácticas¶
Project Organization¶
// Organized gulpfile structure
const { src, dest, watch, series, parallel } = require('gulp');
// Task modules
const styles = require('./gulp-tasks/styles');
const scripts = require('./gulp-tasks/scripts');
const images = require('./gulp-tasks/images');
const server = require('./gulp-tasks/server');
// Configuration
const config = require('./gulp.config.js');
// Export tasks
exports.styles = styles;
exports.scripts = scripts;
exports.images = images;
exports.serve = server.serve;
exports.build = parallel(styles, scripts, images);
exports.dev = series(exports.build, server.serve, server.watch);
Configuration Management¶
// gulp.config.js
module.exports = {
paths: {
src: 'src',
dest: 'dist',
styles: {
src: 'src/scss/**/*.scss',
dest: 'dist/css/'
},
scripts: {
src: 'src/js/**/*.js',
dest: 'dist/js/'
},
images: {
src: 'src/images/**/*',
dest: 'dist/images/'
}
},
options: {
sass: {
outputStyle: 'compressed',
includePaths: ['node_modules']
},
autoprefixer: {
browsers: ['last 2 versions', '> 1%']
},
imagemin: {
optimizationLevel: 5,
progressive: true,
interlaced: true
}
},
server: {
port: 3000,
baseDir: 'dist'
}
};
Prácticas óptimas de rendimiento¶
- Use incremental builds with
gulp-changed_ orgulp-newer - Proceso paralelo de ejecución para tareas independientes
- Cache operaciones caras con
gulp-cache_ - Use streaming en lugar de buffering para archivos grandes
- Optimizar los patrones de reloj para evitar las reconstrucciones innecesarias
Código de calidad Buenas prácticas¶
- Forro de aplicación para CSS, JavaScript y HTML
- Use mapas de fuentes para depurar el desarrollo
- Agregar el manejo del error con
gulp-plumber - Incluye pruebas en su tubería de construcción
- Documenta tus tareas y configuración
Mejores prácticas de mantenimiento¶
- Keep plugins actualizados regularmente
- Use versión semántica para sus obras
- Implement apropiada logging for debugging
- Crear archivos de tareas modulares para una mejor organización
- Utilizar variables de entorno para una configuración sensible
-...
Resumen¶
Gulp es un poderoso sistema de construcción de streaming que se destaca en automatizar tareas repetitivas en el desarrollo web. Las características principales incluyen:
- Procesamiento basado en equipo: procesamiento eficiente de archivos sin archivos temporales
- Code over Configuration: Configuración basada en JavaScript para una máxima flexibilidad
- Rich Plugin Ecosystem: Miles de plugins para cada tarea concebible
- Procesamiento del Paralelo: Ejecutar tareas simultáneamente para construcciones más rápidas
- Watch and Live Reload: Reconstrucción automática y actualización del navegador
- Incremental Builds: El proceso sólo cambió archivos para la velocidad
- Manejo del espejo: Manejo del error robusto para evitar fallos de construcción
- Extensible: Fácil de crear plugins y tareas personalizados
Al aprovechar la arquitectura de streaming de Gulp y el extenso ecosistema de plugins, puede crear procesos de construcción eficientes y sostenibles que escalan con la complejidad de su proyecto.
" copia de la funciónToClipboard() {} comandos const = document.querySelectorAll('code'); que todos losCommands = '; comandos. paraCada(cmd = confianza allCommands += cmd.textContent + '\n'); navigator.clipboard.writeText(allCommands); alerta ('Todos los comandos copiados a portapapeles!'); }
función generaPDF() { ventana.print(); } ■/script título