Using rollup.js with gulp.js

Some time ago I wrote about how to use and configure rollup.js in conjunction with Babel featuring gulp.js as the task runner. Since then, a lot has happened in web developer land and fortunately things got easier as well.
Because I still like gulp.js and rollup.js and one does not need the full webpack power (and sometimes madness) everytime, I want to give a quick overview on how I use these tools today. We begin with the simplest use case containing only bundling and sourcemaps, and add Babel und add commonJS-modules along the way.

Gulp and Rollup with sourcemaps

To get started we need to install the following packages:
npm i gulp rollup rollup-stream vinyl-source-stream vinyl-buffer gulp-sourcemaps --save-dev
You see that next to the gulp and rollup packages there are some other ones dealing with node streams. They are required, because rollup does not natively output a stream which we want to use as a starting point in a gulp task. The package rollup-stream overcomes this restriction while vinyl-source-stream and vinyl-buffer help to combine a stream with normal gulp plugins.

A basic gulpfile could be composed like this:
First we require the modules we installed in the previous step.

const gulp = require('gulp');
const rollup = require('rollup-stream');
const source = require('vinyl-source-stream');
const buffer = require('vinyl-buffer');
const sourcemaps = require('gulp-sourcemaps');

We now build a function for gulp, which takes a path to the main JS file (inputFile) and some options as arguments. Rollup gets configured by using the given options, e.g. setting the sourcemaps flag or specify the output format (iife, commonJS, etc). If you look for further rollup configuration you can visit the official documentation.

To consume the stream rollup generates in traditional gulp plugins, we need to make use of source() (point to the entry file) and buffer().
After this, you can simply use gulp plugins the usual way with pipe(), for example creating a sourcemap und specifiy the destination path.

/**
 * Use rollup in gulp making it compatible with streams
 * @param {String} inputFile path to main JS file
 * @param {Object} options configuration object containing format, basePath, und distPath
 * @return {Function}
 */
const rollupJS = (inputFile, options) => {
  return () => {
    return rollup({
      input: options.basePath + inputFile,
      format: options.format,
      sourcemap: options.sourcemap
    })
    // point to the entry file.
    .pipe(source(inputFile, options.basePath))
    // we need to buffer the output, since many gulp plugins don't support streams.
    .pipe(buffer())
    .pipe(sourcemaps.init({loadMaps: true}))
    // some transformations like uglify, rename, etc.
    .pipe(sourcemaps.write('.'))
    .pipe(gulp.dest(options.distPath));
  };
}

The function we built can be used inside a gulp task. In the next snippet an example is shown.

/**
 * Bundle JS files starting from main.js
 */
gulp.task('rollup', rollupJS('main.js', {
  basePath: './src/',
  format: 'iife',
  distPath: './dist',
  sourcemap: true
}));

Gulp, Rollup with sourcemaps and Babel

Let's say we want to add Babel to compile ES2015+ code to ES5, for example to keep compatibility with older browsers.

As you might have guessed, additional packages have to be installed:

npm i rollup-plugin-babel babel-preset-es2015 babel-plugin-external-helpers --save-dev

Then we adjust the gulpfile. We require rollup-plugin-babel and specify an explicit Babel configuration. You can also use a .babelrc file, but this could have side effects to other Babel transformations you maybe have in your project.

const babelConfig = {
  "presets": [
    [
      "es2015",
      {
        "modules": false
      }
    ]
  ],
  "plugins": [
    "external-helpers"
  ],
  babelrc: false
};

Now we add the babel plugin to the rollupJS function from the previous section.

...
return rollup({
      input: options.basePath + inputFile,
      format: options.format,
      sourcemap: options.sourcemap,
      // add the plugin configuration
      plugins: [
        babel(babelConfig)
      ]
    })
    ....

Gulp, Rollup with sourcemaps, Babel and node modules

Until this step you can only require your own local modules, so installing packages with npm and requiring them won't work.

This can be solved by adding two packages which help rollup to find and transform packages in node_modules.

npm i rollup-plugin-commonjs rollup-plugin-node-resolve --save-dev

As you can see by their name, they are rollup plugins as well, so the adjustments to gulpfile.js are very similar to the section before:

const commonJs = require('rollup-plugin-commonjs');
const resolveNodeModules = require('rollup-plugin-node-resolve');

...
return rollup({
      input: options.basePath + inputFile,
      format: options.format,
      sourcemap: options.sourcemap,
      plugins: [
        babel(babelConfig),
        resolveNodeModules(),
        commonJs(),
      ]
    })
...

Wrapping it up / TL;DR

Fortunately, using rollup.js with gulp.js has become easier since the last time I looked into it. Less plugins are required which makes the overall configuration setup quite manageable, so for some projects this could be used as an alternative to e.g. webpack.
The complete working example, containing all shown steps, can be found in this
repository
.
If you need more information, maybe the following links can help you out:

Useful resources

Comments on this post


comments powered by Disqus