Gulp Task Automation

Gulp task runner examples including build automation, file processing, and development workflows

Key Facts

Category
Build Tools
Items
2
Format Families
sample

Sample Overview

Gulp task runner examples including build automation, file processing, and development workflows This sample set belongs to Build Tools and can be used to test related workflows inside Elysia Tools.

💻 Gulp Basic Tasks javascript

🟢 simple ⭐⭐⭐⭐

Essential Gulp tasks for modern web development including file processing, watching, and building

⏱️ 45 min 🏷️ rollup, plugins, advanced
Prerequisites: Rollup basics, JavaScript AST, Plugin architecture
// Gulp Basic Tasks Setup
// Modern Gulp 4.x configuration for web development workflows

// ===== package.json =====
{
  "name": "my-gulp-project",
  "version": "1.0.0",
  "description": "Modern web application using Gulp for task automation",
  "main": "index.js",
  "scripts": {
    "dev": "gulp dev",
    "build": "gulp build",
    "watch": "gulp watch",
    "clean": "gulp clean",
    "serve": "gulp serve",
    "test": "gulp test",
    "lint": "gulp lint",
    "deploy": "gulp deploy"
  },
  "devDependencies": {
    "gulp": "^4.0.2",
    "gulp-cli": "^2.3.0",
    "gulp-sass": "^5.1.0",
    "gulp-postcss": "^9.0.1",
    "autoprefixer": "^10.4.0",
    "cssnano": "^5.1.0",
    "gulp-terser": "^2.1.0",
    "gulp-babel": "^8.0.0",
    "@babel/core": "^7.20.0",
    "@babel/preset-env": "^7.20.0",
    "@babel/preset-react": "^7.18.0",
    "gulp-imagemin": "^8.0.0",
    "gulp-rename": "^2.0.0",
    "gulp-uglify": "^3.0.2",
    "gulp-clean-css": "^4.3.0",
    "gulp-concat": "^2.6.1",
    "gulp-sourcemaps": "^3.0.0",
    "gulp-eslint": "^6.0.0",
    "gulp-stylelint": "^13.0.0",
    "gulp-htmlmin": "^5.0.1",
    "gulp-file-include": "^2.3.0",
    "gulp-replace": "^1.1.4",
    "gulp-size": "^4.0.0",
    "gulp-brotli": "^2.0.2",
    "gulp-zip": "^5.1.0",
    "gulp-plumber": "^1.2.1",
    "gulp-if": "^3.0.0",
    "gulp-notify": "^4.0.0",
    "browser-sync": "^2.27.0",
    "del": "^7.0.0",
    "through2": "^4.0.2",
    "vinyl-buffer": "^1.0.1",
    "vinyl-source-stream": "^2.0.0",
    "node-sass": "^8.0.0",
    "tailwindcss": "^3.2.0",
    "postcss": "^8.4.0",
    "webpack-stream": "^7.0.0",
    "dotenv": "^16.0.0",
    "cross-env": "^7.0.3"
  }
}

// ===== gulpfile.js =====
const { src, dest, watch, series, parallel, task } = require('gulp');
const gulp = require('gulp');
const plumber = require('gulp-plumber');
const notify = require('gulp-notify');
const sourcemaps = require('gulp-sourcemaps');
const rename = require('gulp-rename');
const replace = require('gulp-replace');
const size = require('gulp-size');
const del = require('del');

// Load environment variables
require('dotenv').config();

// Configuration
const config = {
    src: {
        html: 'src/**/*.html',
        css: 'src/scss/**/*.scss',
        js: 'src/js/**/*.js',
        images: 'src/images/**/*',
        fonts: 'src/fonts/**/*',
        assets: 'src/assets/**/*'
    },
    build: {
        html: 'dist',
        css: 'dist/css',
        js: 'dist/js',
        images: 'dist/images',
        fonts: 'dist/fonts',
        assets: 'dist'
    },
    isProduction: process.env.NODE_ENV === 'production',
    isDevelopment: process.env.NODE_ENV === 'development'
};

// Error handler
function errorHandler(err) {
    notify.onError({
        title: 'Gulp Error',
        message: '<%= error.message %>'
    })(err);
    this.emit('end');
}

// Clean build directory
function clean() {
    return del(['dist/**/*', '!dist/.gitkeep']);
}

// HTML tasks
const htmlmin = require('gulp-htmlmin');
const fileInclude = require('gulp-file-include');

function html() {
    return src(config.src.html)
        .pipe(plumber({ errorHandler }))
        .pipe(fileInclude({
            prefix: '@@',
            basepath: 'src/'
        }))
        .pipe(gulpIf(config.isProduction, htmlmin({
            collapseWhitespace: true,
            removeComments: true,
            removeRedundantAttributes: true,
            removeScriptTypeAttributes: true,
            removeStyleLinkTypeAttributes: true,
            useShortDoctype: true,
            minifyCSS: true,
            minifyJS: true
        })))
        .pipe(replace('%%VERSION%%', process.env.npm_package_version || '1.0.0'))
        .pipe(gulpIf(config.isProduction, size({ title: 'HTML:', showFiles: true })))
        .pipe(dest(config.build.html));
}

// CSS/SCSS tasks
const sass = require('gulp-sass')(require('node-sass'));
const postcss = require('gulp-postcss');
const autoprefixer = require('autoprefixer');
const cssnano = require('cssnano');
const cleanCSS = require('gulp-clean-css');

function styles() {
    const processors = [
        autoprefixer(),
        gulpIf(config.isProduction, cssnano())
    ];

    return src(config.src.css)
        .pipe(plumber({ errorHandler }))
        .pipe(gulpIf(config.isDevelopment, sourcemaps.init()))
        .pipe(sass({
            outputStyle: config.isProduction ? 'compressed' : 'expanded',
            includePaths: ['node_modules']
        }).on('error', sass.logError))
        .pipe(postcss(processors))
        .pipe(gulpIf(config.isProduction, cleanCSS()))
        .pipe(rename({ suffix: '.min' }))
        .pipe(gulpIf(config.isDevelopment, sourcemaps.write('.')))
        .pipe(gulpIf(config.isProduction, size({ title: 'CSS:', showFiles: true })))
        .pipe(dest(config.build.css));
}

// JavaScript tasks
const babel = require('gulp-babel');
const terser = require('gulp-terser');
const concat = require('gulp-concat');

function scripts() {
    return src(config.src.js)
        .pipe(plumber({ errorHandler }))
        .pipe(gulpIf(config.isDevelopment, sourcemaps.init()))
        .pipe(babel({
            presets: [
                ['@babel/preset-env', {
                    targets: {
                        browsers: ['last 2 versions', 'not dead']
                    },
                    modules: false
                }]
            ]
        }))
        .pipe(gulpIf(config.isProduction, concat('bundle.min.js')))
        .pipe(gulpIf(config.isProduction, terser({
            compress: {
                drop_console: true,
                drop_debugger: true
            }
        })))
        .pipe(gulpIf(config.isDevelopment, sourcemaps.write('.')))
        .pipe(gulpIf(config.isProduction, size({ title: 'JavaScript:', showFiles: true })))
        .pipe(dest(config.build.js));
}

// Vendor JavaScript (libraries from node_modules)
function vendorScripts() {
    const vendorFiles = [
        'node_modules/jquery/dist/jquery.min.js',
        'node_modules/bootstrap/dist/js/bootstrap.bundle.min.js'
    ];

    return src(vendorFiles)
        .pipe(concat('vendor.min.js'))
        .pipe(gulpIf(config.isProduction, terser()))
        .pipe(dest(config.build.js));
}

// Image optimization
const imagemin = require('gulp-imagemin');

function images() {
    return src(config.src.images)
        .pipe(plumber({ errorHandler }))
        .pipe(imagemin([
            imagemin.gifsicle({ interlaced: true }),
            imagemin.mozjpeg({ quality: 80, progressive: true }),
            imagemin.optipng({ optimizationLevel: 5 }),
            imagemin.svgo({
                plugins: [
                    { removeViewBox: false },
                    { collapseGroups: true }
                ]
            })
        ]))
        .pipe(gulpIf(config.isProduction, size({ title: 'Images:', showFiles: true })))
        .pipe(dest(config.build.images));
}

// Font handling
function fonts() {
    return src(config.src.fonts)
        .pipe(plumber({ errorHandler }))
        .pipe(dest(config.build.fonts));
}

// Other assets
function assets() {
    return src(config.src.assets)
        .pipe(plumber({ errorHandler }))
        .pipe(dest(config.build.assets));
}

// Code quality tasks
const eslint = require('gulp-eslint');
const stylelint = require('gulp-stylelint');

function lintJS() {
    return src(config.src.js)
        .pipe(eslint())
        .pipe(eslint.format())
        .pipe(eslint.failAfterError());
}

function lintCSS() {
    return src(config.src.css)
        .pipe(stylelint({
            reporters: [
                { formatter: 'string', console: true }
            ]
        }));
}

// Development server
const browserSync = require('browser-sync').create();

function serve() {
    browserSync.init({
        server: 'dist',
        port: 3000,
        open: true,
        notify: false,
        ghostMode: false,
        files: [
            'dist/css/**/*.css',
            'dist/js/**/*.js',
            'dist/**/*.html'
        ]
    });

    watch(config.src.html, html);
    watch(config.src.css, styles);
    watch(config.src.js, scripts);
    watch(config.src.images, images);
    watch(config.src.fonts, fonts);
    watch(config.src.assets, assets);
}

// Build tasks
const build = series(clean, parallel(html, styles, scripts, vendorScripts, images, fonts, assets));

// Development task
const dev = series(clean, parallel(html, styles, scripts, vendorScripts, images, fonts, assets), serve);

// Production build
function production() {
    process.env.NODE_ENV = 'production';
    return build();
}

// Watch task
function watchFiles() {
    watch(config.src.html, html);
    watch(config.src.css, styles);
    watch(config.src.js, scripts);
    watch(config.src.images, images);
    watch(config.src.fonts, fonts);
    watch(config.src.assets, assets);
}

// Export tasks
exports.clean = clean;
exports.html = html;
exports.styles = styles;
exports.scripts = scripts;
exports.vendorScripts = vendorScripts;
exports.images = images;
exports.fonts = fonts;
exports.assets = assets;
exports.lint = parallel(lintJS, lintCSS);
exports.build = build;
exports.dev = dev;
exports.production = production;
exports.watch = watchFiles;
exports.serve = serve;
exports.default = dev;

// ===== gulpfile.config.js =====
module.exports = {
    src: {
        root: 'src',
        html: 'src/**/*.html',
        css: 'src/scss/**/*.scss',
        js: 'src/js/**/*.js',
        ts: 'src/ts/**/*.ts',
        jsx: 'src/jsx/**/*.jsx',
        tsx: 'src/tsx/**/*.tsx',
        images: 'src/images/**/*',
        fonts: 'src/fonts/**/*',
        icons: 'src/icons/**/*',
        data: 'src/data/**/*',
        templates: 'src/templates/**/*'
    },
    build: {
        root: 'dist',
        html: 'dist',
        css: 'dist/css',
        js: 'dist/js',
        vendor: 'dist/vendor',
        images: 'dist/images',
        fonts: 'dist/fonts',
        icons: 'dist/icons',
        data: 'dist/data',
        templates: 'dist/templates'
    },
    temp: {
        root: '.tmp',
        styles: '.tmp/styles'
    },
    nodeModules: 'node_modules',
    browsersync: {
        server: {
            baseDir: ['dist'],
            index: 'index.html'
        },
        port: 3000,
        open: true,
        notify: true,
        ghostMode: {
            clicks: true,
            scroll: true,
            forms: true
        }
    },
    plumber: {
        errorHandler: function(err) {
            notify.onError({
                title: 'Gulp Error',
                message: '<%= error.message %>',
                sound: 'Beep'
            })(err);
            this.emit('end');
        }
    },
    autoprefixer: {
        overrideBrowserslist: ['last 2 versions', 'not dead'],
        cascade: true
    },
    sass: {
        outputStyle: 'expanded',
        includePaths: ['node_modules']
    },
    esLint: {
        configFile: '.eslintrc.json',
        failAfterError: false
    },
    styleLint: {
        configFile: '.stylelintrc.json',
        failAfterError: false
    },
    imagemin: {
        optimizationLevel: 5,
        progressive: true,
        interlaced: true,
        multipass: true
    },
    htmlmin: {
        collapseWhitespace: true,
        removeComments: true,
        removeRedundantAttributes: true,
        removeScriptTypeAttributes: true,
        removeStyleLinkTypeAttributes: true,
        useShortDoctype: true,
        minifyCSS: true,
        minifyJS: true,
        processConditionalComments: true
    },
    terser: {
        compress: {
            drop_console: true,
            drop_debugger: true,
            collapse_vars: true,
            reduce_vars: true
        },
        mangle: true,
        output: {
            comments: false
        }
    },
    cleanCSS: {
        level: 2,
            return Promise.resolve([file]);
        }

        return Promise.resolve(file);
    }

    async process(bundleGraph) {
        const outputOptions = this.options;

        // Store bundle graph for later use
        this.bundleGraph = bundleGraph;

        // Run original bundling
        const result = await this.defaultBundler.bundle(bundleGraph, outputOptions);

        // Run post-processing
        await this.postProcess(result, bundleGraph);

        return result;
    }

    async postProcess(bundleResult, bundleGraph) {
        // Additional processing after bundling
        console.log('Running post-processing...');

        // Example: Generate statistics
        const stats = await this.generateStats(bundleGraph);
        this.emit('buildStats', stats);
    }

    async generateStats(bundleGraph) {
        const bundles = bundleGraph.getBundles();
        const stats = {
            bundleCount: bundles.length,
            totalSize: 0,
            bundles: []
        };

        bundles.forEach(bundle => {
            const size = this.getBundleSize(bundle);
            stats.totalSize += size;

            stats.bundles.push({
                name: bundle.getEntryAssets()[0]?.filePath || 'unknown',
                size,
                type: bundle.type
            });
        });

        return stats;
    }

    getBundleSize(bundle) {
        let size = 0;
        bundle.getEntryAssets().forEach(asset => {
            size += asset.stats.size;
        });
        return size;
    }
} catch (error) {
    return originalBundler;
}

// Add catch-all to prevent fatal errors
} else {
    console.warn('Bundler not found in context, skipping plugin');
}

// Ensure we always return the original bundler
return originalBundler;
} catch (error) {
    return originalBundler;
} finally {
    // Reset error if it was thrown
    if (originalBundler) {
        return originalBundler;
    }
}

// Final fallback
return originalBundler || class MockBundler {
    async bundle() {
        console.warn('Mock bundler used');
    }
};
}

module.exports = bundlerWrapper;

// ===== PLUGIN ENHANCEMENT =====

// parcel-plugin-enhancer.js
const { promises: fs } = require('fs');

class PluginEnhancer {
    constructor() {
        this.enhancements = new Map();
        this.middlewares = [];
    }

    enhance(pluginName, enhancer) {
        if (!this.enhancements.has(pluginName)) {
            this.enhancements.set(pluginName, []);
        }
        this.enhancements.get(pluginName).push(enhancer);
    }

    addMiddleware(middleware) {
        this.middlewares.push(middleware);
    }

    async applyEnhancements(plugin, pluginName) {
        const enhancements = this.enhancements.get(pluginName) || [];
        let enhancedPlugin = plugin;

        for (const enhancer of enhancements) {
            enhancedPlugin = await enhancer(enhancedPlugin);
        }

        // Apply middlewares
        for (const middleware of this.middlewares) {
            enhancedPlugin = await middleware(enhancedPlugin, pluginName);
        }

        return enhancedPlugin;
    }
}

const enhancer = new PluginEnhancer();

// Add common enhancements
enhancer.enhance('@parcel/transformer-js', (transformer) => {
    return {
        ...transformer,
        transformWithEnhancements: async (asset) => {
            const result = await transformer.transform(asset);

            // Add enhancement features
            if (result.code) {
                // Add source mapping support
                result.code += `\n// Enhanced by parcel-plugin-optimizer`;
            }

            return result;
        }
    };
});

// Add middleware
enhancer.addMiddleware(async (plugin, pluginName) => {
    if (typeof plugin === 'function') {
        return async (...args) => {
            const result = await plugin(...args);

            // Log plugin usage
            console.log(`Using enhanced plugin: ${pluginName}`);

            return result;
        };
    }

    return plugin;
});

module.exports = enhancer;

// ===== REAL-TIME PLUGIN SYSTEM =====

// parcel-plugin-system.js
class ParcelPluginSystem {
    constructor() {
        this.plugins = new Map();
        this.hooks = new Map();
        this.config = new Map();
        this.status = 'idle';
        this.metrics = {
            pluginsLoaded: 0,
            hooksExecuted: 0,
            errors: 0
        };
    }

    // Plugin registration
    registerPlugin(name, plugin) {
        if (this.plugins.has(name)) {
            throw new Error(`Plugin ${name} already registered`);
        }

        this.plugins.set(name, {
            name,
            plugin,
            status: 'registered',
            loadedAt: null,
            error: null
        });

        this.emit('pluginRegistered', { name, plugin });
        return this;
    }

    // Load all registered plugins
    async loadPlugins() {
        this.status = 'loading';
        const loadPromises = Array.from(this.plugins.entries()).map(
            ([name, { plugin }]) => this.loadPlugin(name, plugin)
        );

        await Promise.allSettled(loadPromises);
        this.status = 'loaded';
        this.emit('pluginsLoaded', { count: this.metrics.pluginsLoaded });
    }

    async loadPlugin(name, plugin) {
        const pluginInfo = this.plugins.get(name);

        try {
            // Initialize plugin if it has init method
            if (typeof plugin.init === 'function') {
                await plugin.init(this);
            }

            pluginInfo.status = 'loaded';
            pluginInfo.loadedAt = Date.now();
            this.metrics.pluginsLoaded++;

            this.emit('pluginLoaded', { name });
        } catch (error) {
            pluginInfo.status = 'error';
            pluginInfo.error = error;
            this.metrics.errors++;

            this.emit('pluginError', { name, error });
        }
    }

    // Hook registration
    registerHook(hookName, handler, options = {}) {
        if (!this.hooks.has(hookName)) {
            this.hooks.set(hookName, []);
        }

        this.hooks.get(hookName).push({
            handler,
            options,
            id: Math.random().toString(36).substr(2, 9)
        });

        return this;
    }

    // Execute hooks
    async executeHook(hookName, context = {}) {
        const handlers = this.hooks.get(hookName) || [];
        const results = [];

        this.metrics.hooksExecuted++;

        for (const { handler, options } of handlers) {
            try {
                const result = await handler(context, this);

                if (options.stopPropagation && result === false) {
                    break;
                }

                results.push(result);
            } catch (error) {
                this.metrics.errors++;
                this.emit('hookError', { hookName, error });

                if (options.breakOnError) {
                    throw error;
                }
            }
        }

        return results;
    }

    // Configuration management
    setConfig(key, value) {
        this.config.set(key, value);
        this.emit('configChanged', { key, value });
    }

    getConfig(key) {
        return this.config.get(key);
    }

    // Event emission
    emit(event, data) {
        // Implement event emission
        console.log(`[PluginSystem] ${event}:`, data);
    }

    // Plugin unloading
    async unloadPlugin(name) {
        const pluginInfo = this.plugins.get(name);
        if (!pluginInfo) {
            throw new Error(`Plugin ${name} not found`);
        }

        try {
            // Call plugin cleanup if available
            if (pluginInfo.plugin && typeof pluginInfo.plugin.cleanup === 'function') {
                await pluginInfo.plugin.cleanup();
            }

            pluginInfo.status = 'unloaded';
            this.emit('pluginUnloaded', { name });
        } catch (error) {
            pluginInfo.error = error;
            this.emit('pluginUnloadError', { name, error });
        }
    }

    // Get plugin status
    getPluginStatus(name) {
        const pluginInfo = this.plugins.get(name);
        return pluginInfo ? pluginInfo.status : 'not_found';
    }

    // List all plugins
    listPlugins() {
        return Array.from(this.plugins.entries()).map(([name, info]) => ({
            name,
            status: info.status,
            error: info.error,
            loadedAt: info.loadedAt
        }));
    }

    // Performance metrics
    getMetrics() {
        return {
            ...this.metrics,
            status: this.status,
            pluginCount: this.plugins.size,
            hookCount: Array.from(this.hooks.values()).reduce((sum, hooks) => sum + hooks.length, 0)
        };
    }

    // Cleanup
    async cleanup() {
        this.status = 'cleaning';

        const cleanupPromises = Array.from(this.plugins.entries())
            .filter(([name, info]) => info.status === 'loaded')
            .map(([name]) => this.unloadPlugin(name));

        await Promise.allSettled(cleanupPromises);

        this.plugins.clear();
        this.hooks.clear();
        this.config.clear();

        this.status = 'cleaned';
        this.emit('systemCleanup');
    }
}

// Example plugin system usage
const pluginSystem = new ParcelPluginSystem();

// Register a sample plugin
pluginSystem.registerPlugin('samplePlugin', {
    init: async (system) => {
        console.log('Sample plugin initialized');
        system.setConfig('samplePlugin.enabled', true);
    },

    transform: async (asset) => {
        // Simple transformation
        if (asset.type === 'js') {
            asset.code += `\n// Processed by sample plugin`;
        }
        return asset;
    },

    cleanup: async () => {
        console.log('Sample plugin cleanup');
    }
});

// Register hooks
pluginSystem.registerHook('beforeBuild', async (context, system) => {
    console.log('Before build hook executed');
});

pluginSystem.registerHook('afterBuild', async (context, system) => {
    console.log('After build hook executed');
    console.log('Build metrics:', system.getMetrics());
});

module.exports = ParcelPluginSystem;

💻 Rollup Plugin Ecosystem javascript

🟡 intermediate ⭐⭐⭐⭐

Building plugins that integrate with the broader Rollup ecosystem and common patterns

⏱️ 40 min 🏷️ rollup, plugins, ecosystem
Prerequisites: Rollup plugin development, JavaScript ecosystems, Build tools
// Rollup Plugin Ecosystem Integration
// Building plugins that work seamlessly with other Rollup plugins and tools

// ===== PLUGIN INTEROPERABILITY =====

// 1. Plugin Communication System
// plugin-communication.js
export class PluginCommunication {
    constructor() {
        this.channels = new Map();
        this.globalState = new Map();
    }

    // Subscribe to a channel
    subscribe(channel, callback) {
        if (!this.channels.has(channel)) {
            this.channels.set(channel, []);
        }
        this.channels.get(channel).push(callback);
    }

    // Publish to a channel
    publish(channel, data) {
        const subscribers = this.channels.get(channel) || [];
        subscribers.forEach(callback => callback(data));
    }

    // Set global state
    setState(key, value) {
        this.globalState.set(key, value);
        this.publish('stateChange', { key, value });
    }

    // Get global state
    getState(key) {
        return this.globalState.get(key);
    }
}

// 2. Plugin Registry System
// plugin-registry.js
export class PluginRegistry {
    constructor() {
        this.plugins = new Map();
        this.hooks = new Map();
        this.communication = new PluginCommunication();
    }

    // Register a plugin
    register(plugin) {
        if (!plugin.name) {
            throw new Error('Plugin must have a name');
        }

        if (this.plugins.has(plugin.name)) {
            throw new Error(`Plugin ${plugin.name} is already registered`);
        }

        // Initialize plugin hooks
        this.initializeHooks(plugin);

        // Store plugin
        this.plugins.set(plugin.name, plugin);

        // Notify other plugins
        this.communication.publish('pluginRegistered', { plugin });

        return this;
    }

    // Initialize plugin hooks
    initializeHooks(plugin) {
        const hookNames = [
            'buildStart', 'buildEnd', 'moduleParsed', 'resolveId',
            'load', 'transform', 'generateBundle', 'writeBundle',
            'renderChunk', 'renderStart', 'renderError'
        ];

        hookNames.forEach(hookName => {
            if (plugin[hookName]) {
                if (!this.hooks.has(hookName)) {
                    this.hooks.set(hookName, []);
                }
                this.hooks.get(hookName).push({
                    plugin: plugin.name,
                    handler: plugin[hookName].bind(plugin)
                });
            }
        });
    }

    // Execute hooks
    async executeHook(hookName, ...args) {
        const hooks = this.hooks.get(hookName) || [];
        const results = [];

        for (const { plugin, handler } of hooks) {
            try {
                const result = await handler(...args);
                results.push({ plugin, result });
            } catch (error) {
                console.error(`Error in hook ${hookName} for plugin ${plugin}:`, error);
                results.push({ plugin, error });
            }
        }

        return results;
    }
}

// 3. Plugin Lifecycle Manager
// lifecycle-manager.js
export class PluginLifecycleManager {
    constructor(registry) {
        this.registry = registry;
        this.phases = new Map();
    }

    // Register a phase
    registerPhase(name, plugins = []) {
        this.phases.set(name, plugins);
        return this;
    }

    // Execute a phase
    async executePhase(name, context = {}) {
        const phasePlugins = this.phases.get(name) || [];

        for (const pluginName of phasePlugins) {
            const plugin = this.registry.plugins.get(pluginName);
            if (plugin && plugin.phaseHandler) {
                await plugin.phaseHandler(name, context);
            }
        }
    }
}

// ===== INTEGRATION WITH COMMON PLUGINS =====

// 4. Alias Resolution Plugin
// alias-resolver-plugin.js
function aliasResolverPlugin(options = {}) {
    const { alias = {}, preserveSymlinks = false } = options;

    return {
        name: 'alias-resolver',

        resolveId(id, importer) {
            // Check if the ID matches any alias
            for (const [key, value] of Object.entries(alias)) {
                if (id === key || id.startsWith(key + '/')) {
                    const replacement = id.replace(key, value);
                    return this.resolve(replacement, importer, { preserveSymlinks });
                }
            }
            return null;
        },

        // Integrate with node-resolve
        async buildStart() {
            // Ensure node-resolve is available
            if (!this.getPluginInfo('node-resolve')) {
                this.warn('alias-resolver works best with @rollup/plugin-node-resolve');
            }
        }
    };
}

// 5. Virtual Modules Plugin
// virtual-modules-plugin.js
function virtualModulesPlugin(modules = {}) {
    const virtualModulePrefix = '\0virtual:';
    const virtualModules = new Map();

    // Initialize with provided modules
    Object.entries(modules).forEach(([id, content]) => {
        virtualModules.set(virtualModulePrefix + id, content);
    });

    return {
        name: 'virtual-modules',

        resolveId(id) {
            if (virtualModules.has(virtualModulePrefix + id)) {
                return virtualModulePrefix + id;
            }
            return null;
        },

        load(id) {
            if (virtualModules.has(id)) {
                return virtualModules.get(id);
            }
            return null;
        },

        // API to add virtual modules at runtime
        api: {
            addModule(id, content) {
                virtualModules.set(virtualModulePrefix + id, content);
            },
            hasModule(id) {
                return virtualModules.has(virtualModulePrefix + id);
            }
        }
    };
}

// 6. CSS Processing Plugin (with PostCSS integration)
// css-processor-plugin.js
import postcss from 'postcss';
import autoprefixer from 'autoprefixer';
import cssnano from 'cssnano';

function cssProcessorPlugin(options = {}) {
    const {
        plugins = [autoprefixer, cssnano],
        inject = false,
        outputName = 'styles.css',
        minimize = process.env.NODE_ENV === 'production'
    } = options;

    let cssCode = '';
    const processedCSS = new Set();

    return {
        name: 'css-processor',

        transform(code, id) {
            if (!id.endsWith('.css') && !id.endsWith('.scss') && !id.endsWith('.sass')) {
                return null;
            }

            // Collect CSS code
            cssCode += code + '\n';
            return {
                code: 'export default null;',
                map: null
            };
        },

        buildEnd() {
            if (!cssCode.trim()) return;

            return postcss(minimize ? [...plugins, cssnano] : plugins)
                .process(cssCode, { from: undefined })
                .then(result => {
                    const processedResult = result.css;
                    processedCSS.add(processedResult);

                    if (inject) {
                        // Create CSS injector
                        const injector = `
(function() {
    var css = ${JSON.stringify(processedResult)};
    if (typeof document !== 'undefined') {
        var style = document.createElement('style');
        style.textContent = css;
        document.head.appendChild(style);
    }
})();
                        `;
                        this.emitFile({
                            type: 'chunk',
                            id: 'css-injector',
                            fileName: 'css-injector.js',
                            code: injector
                        });
                    } else {
                        // Emit CSS file
                        this.emitFile({
                            type: 'asset',
                            fileName: outputName,
                            source: processedResult
                        });
                    }
                })
                .catch(error => {
                    this.error(`CSS processing failed: ${error.message}`);
                });
        }
    };
}

// 7. Environment Configuration Plugin
// environment-config-plugin.js
function environmentConfigPlugin(options = {}) {
    const {
        environments = {},
        defaultEnv = 'development',
        configFile = '.rollup.env.js'
    } = options;

    let currentEnv = defaultEnv;
    let envConfig = {};

    return {
        name: 'environment-config',

        buildStart() {
            // Load environment configuration
            const fs = require('fs');
            const path = require('path');

            if (fs.existsSync(configFile)) {
                delete require.cache[require.resolve(path.resolve(configFile))];
                const userConfig = require(path.resolve(configFile));
                currentEnv = process.env.ROLLUP_ENV || userConfig.env || defaultEnv;
                envConfig = { ...userConfig, ...environments[currentEnv] };
            } else {
                currentEnv = process.env.ROLLUP_ENV || defaultEnv;
                envConfig = environments[currentEnv] || {};
            }

            console.log(`🌍 Using environment: ${currentEnv}`);
        },

        resolveId(id, importer) {
            // Handle environment-specific modules
            const envMatch = id.match(/^(.*)\.env\.(\w+)$/);
            if (envMatch) {
                const [, baseId, env] = envMatch;
                if (env === currentEnv) {
                    return this.resolve(baseId, importer);
                }
                return null;
            }
            return null;
        },

        transform(code, id) {
            // Replace environment variables in code
            const envRegex = /__ENV_([A-Z_]+)__|__CURRENT_ENV__/g;
            let hasReplacements = false;

            const result = code.replace(envRegex, (match, varName) => {
                hasReplacements = true;
                if (varName) {
                    return JSON.stringify(envConfig[varName.toLowerCase()] || process.env[varName] || '');
                }
                return JSON.stringify(currentEnv);
            });

            if (hasReplacements) {
                return {
                    code: result,
                    map: null
                };
            }
        },

        api: {
            getEnv() {
                return currentEnv;
            },
            getConfig() {
                return envConfig;
            },
            isDevelopment() {
                return currentEnv === 'development';
            },
            isProduction() {
                return currentEnv === 'production';
            }
        }
    };
}

// ===== ADVANCED ECOSYSTEM INTEGRATION =====

// 8. Plugin Dependency Manager
// dependency-manager-plugin.js
function dependencyManagerPlugin(options = {}) {
    const { dependencies = {}, autoInstall = false } = options;

    return {
        name: 'dependency-manager',

        buildStart() {
            // Check plugin dependencies
            for (const [pluginName, requiredVersion] of Object.entries(dependencies)) {
                const pluginInfo = this.getPluginInfo(pluginName);

                if (!pluginInfo) {
                    if (autoInstall) {
                        this.warn(`Installing missing plugin: ${pluginName}`);
                        // In a real implementation, you might want to install the plugin
                    } else {
                        this.error(`Required plugin not found: ${pluginName}`);
                    }
                } else {
                    // Version check (simplified)
                    const version = pluginInfo.version || '0.0.0';
                    if (!this.satisfiesVersion(version, requiredVersion)) {
                        this.warn(`Plugin version mismatch: ${pluginName} requires ${requiredVersion}, found ${version}`);
                    }
                }
            }
        },

        satisfiesVersion(current, required) {
            // Simplified version comparison
            const currentParts = current.split('.').map(Number);
            const requiredParts = required.split('.').map(Number);

            for (let i = 0; i < Math.max(currentParts.length, requiredParts.length); i++) {
                const currentPart = currentParts[i] || 0;
                const requiredPart = requiredParts[i] || 0;

                if (currentPart > requiredPart) return true;
                if (currentPart < requiredPart) return false;
            }
            return true;
        }
    };
}

// 9. Plugin Configuration Validator
// config-validator-plugin.js
function configValidatorPlugin(options = {}) {
    const {
        requiredOptions = [],
        optionValidators = {},
        strict = false
    } = options;

    return {
        name: 'config-validator',

        buildStart() {
            // Validate required options
            for (const option of requiredOptions) {
                if (!(option in this.options)) {
                    const message = `Required option '${option}' is missing`;
                    if (strict) {
                        this.error(message);
                    } else {
                        this.warn(message);
                    }
                }
            }

            // Run custom validators
            for (const [option, validator] of Object.entries(optionValidators)) {
                if (option in this.options) {
                    try {
                        const result = validator(this.options[option]);
                        if (!result) {
                            this.warn(`Option '${option}' failed validation`);
                        }
                    } catch (error) {
                        this.warn(`Validation error for option '${option}': ${error.message}`);
                    }
                }
            }
        }
    };
}

// 10. Bundle Optimization Pipeline
// optimization-pipeline-plugin.js
function optimizationPipelinePlugin(options = {}) {
    const {
        stages = [],
        parallel = false,
        timeout = 30000
    } = options;

    return {
        name: 'optimization-pipeline',

        generateBundle(outputOptions, bundle) {
            const pipeline = stages.map(stage => {
                if (typeof stage === 'string') {
                    return this.getOptimizationStage(stage);
                }
                return stage;
            });

            let optimizedBundle = { ...bundle };

            if (parallel) {
                // Run stages in parallel
                return Promise.all(
                    pipeline.map(stage => this.runOptimizationStage(stage, optimizedBundle))
                ).then(() => {
                    // Merge results
                    this.mergeOptimizationResults(optimizedBundle, pipeline);
                });
            } else {
                // Run stages sequentially
                return pipeline.reduce((promise, stage) => {
                    return promise.then(() => this.runOptimizationStage(stage, optimizedBundle));
                }, Promise.resolve());
            }
        },

        getOptimizationStage(name) {
            const stages = {
                'dedupe': this.dedupeStage.bind(this),
                'compress': this.compressStage.bind(this),
                'mangle': this.mangleStage.bind(this),
                'treeshake': this.treeshakeStage.bind(this),
                'optimize-imports': this.optimizeImportsStage.bind(this)
            };

            return stages[name] || (() => Promise.resolve());
        },

        runOptimizationStage(stage, bundle) {
            return new Promise((resolve, reject) => {
                const timer = setTimeout(() => {
                    reject(new Error('Optimization stage timeout'));
                }, timeout);

                try {
                    const result = stage(bundle);
                    if (result && typeof result.then === 'function') {
                        result.finally(() => clearTimeout(timer)).then(resolve).catch(reject);
                    } else {
                        clearTimeout(timer);
                        resolve();
                    }
                } catch (error) {
                    clearTimeout(timer);
                    reject(error);
                }
            });
        },

        // Optimization stage implementations
        dedupeStage(bundle) {
            // Remove duplicate modules
            const seen = new Set();
            const deduped = {};

            for (const [fileName, chunk] of Object.entries(bundle)) {
                const hash = this.createChunkHash(chunk);
                if (!seen.has(hash)) {
                    seen.add(hash);
                    deduped[fileName] = chunk;
                }
            }

            // Update bundle in place
            Object.keys(bundle).forEach(key => delete bundle[key]);
            Object.assign(bundle, deduped);
        },

        compressStage(bundle) {
            // Compress chunks (simplified)
            for (const chunk of Object.values(bundle)) {
                if (chunk.type === 'chunk' && chunk.code) {
                    // Basic compression - in practice, you'd use a proper minifier
                    chunk.code = chunk.code
                        .replace(/\/\*[\s\S]*?\*\//g, '') // Remove comments
                        .replace(/\s+/g, ' ') // Collapse whitespace
                        .trim();
                }
            }
        },

        createChunkHash(chunk) {
            const crypto = require('crypto');
            const content = chunk.code || chunk.source || '';
            return crypto.createHash('md5').update(content).digest('hex');
        }
    };
}

// ===== ROLLUP CONFIGURATION WITH ECOSYSTEM INTEGRATION =====

// rollup.config.js - Complete ecosystem example
import { nodeResolve } from '@rollup/plugin-node-resolve';
import commonjs from '@rollup/plugin-commonjs';
import typescript from '@rollup/plugin-typescript';
import json from '@rollup/plugin-json';
import { terser } from 'rollup-plugin-terser';
import alias from '@rollup/plugin-alias';

// Import custom plugins
import aliasResolverPlugin from './plugins/alias-resolver-plugin.js';
import virtualModulesPlugin from './plugins/virtual-modules-plugin.js';
import cssProcessorPlugin from './plugins/css-processor-plugin.js';
import environmentConfigPlugin from './plugins/environment-config-plugin.js';
import dependencyManagerPlugin from './plugins/dependency-manager-plugin.js';
import configValidatorPlugin from './plugins/config-validator-plugin.js';
import optimizationPipelinePlugin from './plugins/optimization-pipeline-plugin.js';

// Virtual modules
const virtualModules = {
    'config': `
export const API_URL = __ENV_API_URL__;
export const VERSION = '__CURRENT_ENV__-v1.0.0';
`,
    'constants': `
export const APP_NAME = 'My App';
export const BUILD_DATE = new Date().toISOString();
`
};

export default {
    input: 'src/index.js',
    output: [
        {
            file: 'dist/bundle.esm.js',
            format: 'es',
            sourcemap: true
        },
        {
            file: 'dist/bundle.cjs.js',
            format: 'cjs',
            sourcemap: true
        },
        {
            file: 'dist/bundle.umd.js',
            format: 'umd',
            name: 'MyApp',
            sourcemap: true
        }
    ],

    plugins: [
        // Configuration validation
        configValidatorPlugin({
            requiredOptions: ['input'],
            optionValidators: {
                input: (value) => typeof value === 'string',
                output: (value) => Array.isArray(value) || typeof value === 'object'
            },
            strict: true
        }),

        // Dependency management
        dependencyManagerPlugin({
            dependencies: {
                'node-resolve': '^13.0.0',
                'typescript': '^8.0.0'
            },
            autoInstall: false
        }),

        // Environment configuration
        environmentConfigPlugin({
            environments: {
                development: {
                    API_URL: 'http://localhost:3000/api',
                    DEBUG: true
                },
                production: {
                    API_URL: 'https://api.myapp.com',
                    DEBUG: false
                },
                test: {
                    API_URL: 'http://test-api:3000/api',
                    DEBUG: true
                }
            }
        }),

        // Core plugins
        nodeResolve({
            browser: true,
            preferBuiltins: false
        }),
        commonjs(),
        typescript(),
        json(),

        // Alias resolution
        alias({
            entries: [
                { find: '@', replacement: './src' },
                { find: '@utils', replacement: './src/utils' },
                { find: '@components', replacement: './src/components' }
            ]
        }),

        // Custom alias resolver (works with node-resolve)
        aliasResolverPlugin({
            alias: {
                'react': 'preact/compat',
                'react-dom': 'preact/compat'
            }
        }),

        // Virtual modules
        virtualModulesPlugin(virtualModules),

        // CSS processing
        cssProcessorPlugin({
            inject: process.env.NODE_ENV === 'development',
            minimize: process.env.NODE_ENV === 'production',
            plugins: [
                require('autoprefixer'),
                require('cssnano')({
                    preset: 'default'
                })
            ]
        }),

        // Optimization pipeline
        optimizationPipelinePlugin({
            stages: ['dedupe', 'optimize-imports', 'compress'],
            parallel: true
        }),

        // Production optimizations
        process.env.NODE_ENV === 'production' && terser({
            format: {
                comments: /^!/,
                ascii_only: true
            },
            compress: {
                drop_console: true,
                drop_debugger: true,
                pure_funcs: ['console.log', 'console.info'],
                passes: 2
            },
            mangle: {
                properties: {
                    regex: /^_/
                }
            }
        })
    ].filter(Boolean)
};

// Export for use in other files
export {
    aliasResolverPlugin,
    virtualModulesPlugin,
    cssProcessorPlugin,
    environmentConfigPlugin,
    dependencyManagerPlugin,
    configValidatorPlugin,
    optimizationPipelinePlugin
};