Skip to content

Modern Gulp plugin for Rollup 4.x - Bundle JavaScript modules with tree-shaking, multiple output formats (UMD, ESM, CJS, IIFE), and full Rollup API support. Actively maintained.

License

Notifications You must be signed in to change notification settings

orcunsaltik/gulp-rollup-2

Repository files navigation

gulp-rollup-2

CI npm version npm downloads node version license

Modern, production-grade Gulp plugin for Rollup

gulp-rollup-2 is a ground-up rewrite for Rollup v3+ (fully tested with v4), delivering robust behavior in caching, sourcemap handling, and multi-output scenarios. This package aims to overcome limitations of legacy gulp-rollup / rollup-stream approaches.

Features

  • Rollup 3.x / 4.x compatibility - Fully tested with latest Rollup
  • Native Rollup API in Gulp pipe() chains
  • Multiple output formats - ES, CJS, UMD, IIFE, AMD, System
  • Production-grade caching - Intelligent incremental builds with object-hash
  • Duplicate detection - Prevents configuration conflicts automatically
  • Memory-safe - Automatic bundle cleanup, no leaks
  • Sourcemap intelligence - Secure merge & fallback handling
  • Dual modes - Use with gulp.src() or standalone src() factory
  • Deterministic builds - No streaming, predictable output

Requirements

  • Node.js >= 18.0.0 (recommended: latest LTS)
  • Gulp >= 4.0.0
  • Rollup >= 4.0.0 (tested with 4.x)

Installation

npm install --save-dev gulp-rollup-2 rollup

Basic Usage (Pipe Mode)

The most common usage scenario:

const gulp = require('gulp');
const rollup2 = require('gulp-rollup-2');
const resolve = require('@rollup/plugin-node-resolve');
const commonjs = require('@rollup/plugin-commonjs');

gulp.task('bundle', () =>
  gulp
    .src('src/index.js')
    .pipe(
      rollup2.rollup({
        plugins: [resolve(), commonjs()],
        output: {
          file: 'bundle.js',
          format: 'iife',
          name: 'App',
          sourcemap: true,
        },
      })
    )
    .pipe(gulp.dest('dist'))
);

Multiple Outputs

Generate multiple formats from a single input:

.pipe(rollup2.rollup({
  plugins: [resolve(), commonjs()],
  output: [
    { file: 'app.esm.js', format: 'es', sourcemap: true },
    { file: 'app.umd.js', format: 'umd', name: 'App', sourcemap: true },
    { file: 'app.cjs.js', format: 'cjs', sourcemap: true }
  ]
}))

Important: Output files must be unique. Duplicate output files will throw an error.

Cache Behavior

gulp-rollup-2 leverages Rollup's native caching mechanism with enhanced reliability:

How It Works

  • Cache keys are generated using object-hash for stability
  • Incremental builds reuse cached AST when input configuration matches
  • Automatic invalidation when configuration changes

Example

const { watch } = require('gulp');

function bundle() {
  return gulp
    .src('src/**/*.js')
    .pipe(
      rollup2.rollup({
        input: 'src/index.js',
        cache: true, // Enable Rollup's cache
        plugins: [resolve(), commonjs()],
        output: {
          file: 'bundle.js',
          format: 'umd',
          name: 'MyLib',
        },
      })
    )
    .pipe(gulp.dest('dist'));
}

// Watch mode benefits from caching
watch('src/**/*.js', bundle);

v2.1.0 Cache Improvements

  • Stable cache keys using object-hash algorithm
  • Duplicate detection prevents conflicting configurations
  • Memory management with automatic bundle.close()

Disabling Cache

If your Rollup plugins have dynamic behavior:

rollup2.rollup({
  cache: false,  // Disable caching
  plugins: [...]
})

Note: Some Rollup plugins may behave differently with the same name but different configurations. This edge case is intentionally kept simple.

Sourcemaps

Sourcemap handling is production-grade:

  • Rollup-first: If Rollup generates output.map, it's used directly
  • Fallback support: If no Rollup map, upstream Gulp sourcemaps are preserved
  • Path correction: Source paths are automatically resolved

This ensures seamless integration with:

  • gulp-sourcemaps
  • Transpiler chains (Babel, TypeScript, etc.)
  • Multi-stage build pipelines

Example with gulp-sourcemaps

const sourcemaps = require('gulp-sourcemaps');

gulp.task('bundle', () =>
  gulp
    .src('src/**/*.js')
    .pipe(sourcemaps.init())
    .pipe(
      rollup2.rollup({
        input: 'src/index.js',
        output: {
          file: 'bundle.js',
          format: 'umd',
          name: 'App',
          sourcemap: true, // Rollup generates sourcemap
        },
      })
    )
    .pipe(sourcemaps.write('.'))
    .pipe(gulp.dest('dist'))
);

src() Mode (Advanced)

For builds outside the Gulp graph:

  • No gulp.src() required
  • Async factory pattern
  • Ideal for: Multi-entry scenarios, CI/CD pipelines
const rollup2 = require('gulp-rollup-2');
const { dest } = require('gulp');

(async () => {
  const stream = await rollup2.src({
    input: 'src/index.js',
    plugins: [resolve(), commonjs()],
    output: {
      file: 'bundle.js',
      format: 'es',
      sourcemap: true,
    },
  });

  stream.pipe(dest('dist'));
})();

Error Detection (v2.1.0)

Duplicate Input Configurations

Prevents accidental configuration conflicts:

// ❌ This will throw an error:
rollup2.rollup([
  {
    input: 'src/app.js',
    plugins: [resolve()],
    output: { file: 'bundle1.js', format: 'umd' },
  },
  {
    input: 'src/app.js',
    plugins: [resolve()], // Same config!
    output: { file: 'bundle2.js', format: 'umd' },
  },
]);
// Error: gulp-rollup-2: Duplicate input configurations

Duplicate Output Files

Prevents multiple outputs targeting the same file:

// ❌ This will throw an error:
rollup2.rollup({
  input: 'src/app.js',
  output: [
    { file: 'bundle.js', format: 'umd' },
    { file: 'bundle.js', format: 'es' }, // Same file!
  ],
});
// Error: gulp-rollup-2: Multiple outputs target the same file

Unsupported

The following are intentionally not supported:

  • Streaming input (file.isStream())
  • Rollup v1 / v2

These constraints are deliberate design decisions for reliability and predictability.

Philosophy

This plugin:

  • No magic - Transparent Rollup integration
  • Doesn't hide Rollup behavior - Native API exposed
  • Deterministic builds - Predictable, reproducible outputs
  • Production-ready - Battle-tested in CI/CD environments

If your goals are:

  • Modern Rollup integration
  • Robust build outputs
  • Production CI reliability

Then gulp-rollup-2 is the right tool.

API Reference

rollup2.rollup(config)

Use inside a Gulp pipeline.

Parameters:

  • config (Object | Array | String) - Rollup configuration
    • Object: Single Rollup config
    • Array: Multiple Rollup configs
    • String: Format shorthand (e.g., 'umd', 'es')

Returns: Transform stream

rollup2.src(config)

Standalone bundle factory (async).

Parameters:

  • config (Object | Array) - Rollup configuration
  • config.input (String) - Required - Entry point

Returns: Promise<Stream>

Changelog

v2.1.0 (2025)

✨ New Features

  • Production-grade caching: Improved cache system using object-hash for reliable cache key generation
  • Duplicate detection: Automatic detection and prevention of duplicate input configurations
  • Duplicate output detection: Prevents multiple outputs targeting the same file
  • Memory leak prevention: Automatic bundle.close() after each build

🐛 Bug Fixes

  • Fixed sourcemap paths: Corrected sourcemap path resolution for accurate debugging
  • Better error messages: More descriptive errors for configuration issues
  • Deep equality checks: Proper configuration comparison using deep equality

🔧 Internal Improvements

  • Modern async/await patterns throughout
  • Replaced custom equality with robust deep equality checking
  • Better memory management with Map-based caching
  • Added object-hash dependency for stable cache keys

v2.0.2 (2025)

  • Updated config files to latest standards
  • Improved development workflow
  • Better code quality tools
  • Updated SEO-friendly package description

v2.0.0 (2025)

  • Updated to Rollup 4.x
  • Node.js 18+ support
  • Modernized dependencies
  • Added GitHub Actions CI
  • Improved code quality with Prettier & ESLint

Migration Guide

From v2.0.x to v2.1.0

No breaking changes! v2.1.0 is fully backward compatible.

What's New:

  • Automatic duplicate detection (will catch configuration errors early)
  • Improved caching reliability
  • Better memory management
  • Fixed sourcemap paths

Action Required:

  • ✅ None! Just upgrade: npm install gulp-rollup-2@latest
  • ⚠️ If you have duplicate configurations, they will now throw errors (this is intentional!)

Troubleshooting

Cache Issues

If you experience unexpected caching behavior:

rollup2.rollup({
  input: 'src/app.js',
  cache: false,  // Disable cache temporarily
  plugins: [...],
  output: { file: 'bundle.js', format: 'umd' }
})

Duplicate Configuration Errors

Check that:

  1. Input configurations are unique (different input, external, or treeshake options)
  2. Output files have unique paths

Memory Issues

v2.1.0 automatically calls bundle.close() to prevent memory leaks. If you still experience issues, please open an issue.

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

  1. Fork the repository
  2. Create your feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add some amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

License

MIT © Orçun Saltık

Author

Orçun Saltık


Made with care for the Gulp + Rollup community 🚀

About

Modern Gulp plugin for Rollup 4.x - Bundle JavaScript modules with tree-shaking, multiple output formats (UMD, ESM, CJS, IIFE), and full Rollup API support. Actively maintained.

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published