Rollup is a ES6 module bundler. Each Rollup config file only works with one entry and one destination file. Here comes a problem, say I have an entry file src/lib.js, and I want to create a bundle build/lib.js and another minified bundle build/lib.min.js.

You might consider using multiple config files like the following:

// rollup.config.js
export default {
  entry: 'src/lib.js',
  dest: 'build/lib.js',
  // ...
}
// rollup.config.uglify.js
export default {
  entry: 'src/lib.js',
  dest: 'build/lib.min.js',
  // ...
  plugins: [
    // ...
    uglify({})
  ]
}
rollup -c
rollup -c rollup.config.uglify.js

This definitely works, but too much hassle. What if I want to create two bundles at the same time? The answer is to use Rollup API.

First, create a file named build.js. Import rollup module and other plugins you plan to use:

const rollup = require('rollup')
const babel = require('rollup-plugin-babel')
const eslint = require('rollup-plugin-eslint')
const uglify = require('rollup-plugin-uglify')

Then, let’s generate bundles:

// ...

const defaultPlugins = [
  babel({
    exclude: 'node_modules/**'
  }),
  eslint({})
]

// Regular bundle
rollup.rollup({
  entry: 'src/lib.js',
  moduleName: 'Awesome',
  plugins: defaultPlugins
}).then(bundle => {
  bundle.write({
    format: 'umd',
    dest: 'build/lib.js'
  })
})

// Minified bundle
rollup.rollup({
  entry: 'src/lib.js',
  moduleName: 'Awesome',
  plugins: [ ...defaultPlugins, uglify({}) ]
}).then(bundle => {
  bundle.write({
    format: 'umd',
    dest: 'build/lib.min.js',
  })
})

Finally, run node build.js and we got two bundles! This is pretty straight forward, right?

But…How about watching these files using the API?

The watch option -w is for command line only, however, we are free to use any watch library to achieve the goal. Let’s go with the official rollup-watch module. It’s time to do some code refactoring:

// ...

const defaultPlugins = [
  babel({
    exclude: 'node_modules/**'
  }),
  eslint({})
]

const destDefault = 'build/lib.js'
const destMinify = 'build/lib.min.js'

// config to feed the watcher function
const config = (dest, plugins) => {
  return {
    entry: 'src/lib.js',
    dest: dest,
    format: 'umd',
    moduleName: 'Awesome',
    sourceMap: true,
    plugins: plugins
  }
}

const configDefault = config(destDefault, defaultPlugins)
const configMinify = config(destMinify, [ ...defaultPlugins, uglify({}) ])

const watcherDefault = watch(rollup, configDefault)
const watcherMinify = watch(rollup, configMinify)

// stderr to stderr to keep `rollup main.js > bundle.js` from breaking
const stderr = console.error.bind(console)

const eventHandler = (event, filename) => {
  switch (event.code) {
    case 'STARTING':
      stderr('checking rollup-watch version...')
      break
    case 'BUILD_START':
      stderr(`bundling ${filename}...`)
      break
    case 'BUILD_END':
      stderr(`${filename} bundled in ${event.duration}ms. Watching for changes...`)
      break
    case 'ERROR':
      stderr(`error: ${event.error}`)
      break
    default:
      stderr(`unknown event: ${event}`)
  }
}

watcherDefault.on('event', (event) => eventHandler(event, destDefault))
watcherMinify.on('event', (event) => eventHandler(event, destMinify))

Run node build.js and you will see it starts watching and generating both of your bundles ;) I hope it gets you started with Rollup API to create bundles more efficiently!