Middleman v4 & ES6

The other day I was working on a Middleman (v4) site. I really wanted to use ES6… how hard could it be 😅 ? As it turns out, not too too bad…

Middleman v4 deprecated the Rails' Asset Pipeline in favour of something called the 'External Pipeline'. Basically what this means is that Middleman outsources asset compilation to the third party command instead of trying to deal with it itself. Makes sense… so, how do we set this up?

Firstly you'll need to make sure you have Node & NPM installed - head over to https://nodejs.org for those.

Next, we're going to be using Babel to perform the transpiling to ES6. To get all that setup, run the following:

$ npm init
$ npm install --save-dev babel-brunch babel-preset-es2015

Note: The --save-dev flags here simply make sure that NPM adds these packages to your package.json under the devDependencies section

Next you'll need to setup your brunch-config.js file. Mine currently looks like this:

module.exports = {
  modules: {
    wrapper: false,
    definition: false
  },
  paths: {
    watched: ["source/javascripts"],
    public: '.tmp/dist'
  },
  files: {
    javascripts: {
      joinTo: 'javascripts/all.js'
    }
  },
  plugins: {
    babel: {
      presets: ['es2015'],
      pattern: /\.(es6)$/
    }
  }
}

See: http://brunch.io/docs/config for more info

Essentially, we'll be asking Brunch to transpile the ES6 file in the (watched) source/javascripts directory. It'll then place the transpiled files into .tmp/dist as javascripts/all.js which will expand to the full path of: .tmp/dist/javascripts/all.js. More will become apparent in just a moment…

Finally, you'll want to setup your Middleman's config.rb like this:

activate :external_pipeline,
  name: :brunch,
  command: "brunch #{build? ? 'build --production' : 'watch'}",
  source: ".tmp/dist",
  latency: 2

# If you're rolling with Livereload, you might also want to add this...

# activate :livereload, ...etc then...
  ignore: [/\.es6/, /\.js\.map/]

# Finally, we don't want Middleman putting the ES6 files and associated source maps into the build...

ignore '*.es6'
ignore '*.js.map'

For some reason the ignore option in Livereload v3.4.6 seems to be broken 😞 . A commit fixes this, so I actually needed to use this in the Gemfile:

gem "middleman-livereload", github: "middleman/middleman-livereload", ref: "d0ac967"

After adding that, run up bundle install and you should be good to go…

Just to break that down just quickly:

Note that the source option essentially updates the paths so that /javascripts/all.js works again with your nicely transpiled ES6 JS file!

Middleman also provides a build? helper method which determines what mode you're currently in. With the above example, if you're in non-build mode, Brunch will be watching for changes. If you are in build mode (i.e. middleman build) then it will run the standard brunch build command.

If you want to go deeper into the code… the external_pipeline is here on Github.

There we have it! You should now be seeing your transpiled ES6 file pop out into the /javascripts/all.js path!

Lovely stuff! 😎

Just a quick note about versions… this was tested with Babel v6.0, Middleman v4.1, NPM v3.10 and Nodejs v6.3


Bonus tip: If you want to make sure your .tmp folder doesn't end up in source control (remember, it's generated via Brunch so it's a semi-cache at this point) you can add that to your .gitignore:

$ echo ".tmp" >> .gitignore