(Grunt + Rollup + Babel) x non-relative directories = ARGH

First let me start with a big thank you sweet Jesus for finally finding the solution to my latest hair-puller, this rollup babel transpiling error:

babel couldn’t find preset “es2015” relative to directory

This was the situation:

I have a file directory structure which due to some integration with AEM, goes something like this (key files/folders to note are bolded):

> component specific files
– component
– hbs
– sass
– js
> shared site assets
– js
      – bundle.js
      – src
          – entry.js
– sass
– etc…
> node_modules
> gruntfile.js
> package.json, etc…

When I tried to implement the grunt-rollup module bundler, and added the babel plugin with ‘es2015-rollup’ set as the preset, as explained here and here and in any other config blog posts I could find (although granted, since rollup is relatively new there really aren’t all that many), I kept getting the error in red above.

My grunt task config was essentially identical to the how-to article:

rollup: {
      options: {
        plugins: function () {
          return [
              exclude: './node_modules/**',
              presets: ['es2015-rollup'],
      main: {
        dest: 'build/main.js',
        src: 'src/main.js', // Only one source file is permitted

I tried uninstalling the plugin, rollup, presets, installing again, clearing my npm cache, using an absolute path for the present instead of the string, etc.

I had an idea that it had something to do with the fact that I was trying to transpile code that existed in a folder structure who’s parent was at the same level to the folder containing my gruntfile, because I read that babel will search the project hierarchy to find the preset. But I could not for the life of me figure out how to solve for that.

Until, finally! Ran across a post that solved a similar problem within a webpack config. It uses ‘require.resolve’ which as far as I can tell is a node utility that resolves the path relatively, or in node’s own words:

Use the internal require() machinery to look up the location of a module, but rather than loading the module, just return the resolved filename.

So my updated working grunt task now looks like:

rollup: {
 options: {
   plugins: [
      exclude: './node_modules/**',
      presets: [require.resolve('babel-preset-es2015-rollup')]
 files: {
   'src' : 'js/src/entry.js'

And OMG thank you to the interwebs for all the random posts that led me finally to this solution!


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s