Building Vue Single File Components with Grunt and Browserify
Vue.js's Single File Components are great: they're easy to use, easy to share and satisfying to work with. There are lots of tutorials online about how to use them, and plenty too about how to build them using various build tools (Webpack, Rollup, Gulp…). However, I struggled to find a good guide to building Single File Components with Grunt and Browserify, so I thought I'd write one.
I should start by saying that I wouldn't necessarily recommend using Grunt and/or Browserify. There's nothing wrong with them, but they wouldn't be my first choice. However, they're what we use in my current job so they're what I implemented Vue with.
I'm also going to assume that you're familiar with Vue and its Single File Components.
The tools
Grunt is a programmable task runner that automates common processes. In the context of this tutorial, it automates the process of combining all of your component files into one to put them onto a server.
Browserify is a build tool that
allows you to use the require
function (common in
Node.js) to import other JavaScript files into the one you're
currently using. In the context of Vue, it allows you to specify which
other components are used within your current component.
The files
An example of a Vue Single File Component is shown below. Notice how
it uses require
to use another, smaller component. This
file isn't much good on its own, so we want to use Grunt and
Browserify to compile it into Vue and make it usable in our
application.
<template>
<div>
<label for="colour-selector">Select your colour, and click to continue</label>
<select id="colour-selector" v-model="colour"><option>Red</option><option>Green</option><option>Blue</option></select>
<ActionButton icon="arrow-right">Continue</ActionButton>
</div>
</template>
<script type="text/javascript">
const ActionButton = require('./ActionButton.vue');
module.exports = {
data: () => ({
colour: 'Red'
}),
components: {
ActionButton
}
};
</script>
As well as your Vue components, you'll also need to have an
entry file. This is a vanilla JavaScript file which
requires and renders whatever your main root component is. This file
also needs to require the vue
NPM package so that all of
Vue's functionality is included in the bundle.
const Vue = require('vue');
const App = require('./components/App.vue');
new Vue({
el: '#app',
render: (createElement) => createElement(App)
});
The NPM packages
We need four core packages to make this work:
- grunt
- grunt-browserify
- vueify
- vue
These can be installed through NPM with the command:
npm install --save-dev grunt grunt-browserify vueify vue
The Grunt file
The Grunt file is very simple, just pulling together the various
things we've installed. src/index.js
is the entry
file that we described above. Notice that we don't need to specify
any component files: since they're required by either the
entry file or a component that it requires, Browserify will
automatically include them in the bundle.
module.exports = function(grunt) {
grunt.initConfig({
browserify: {
bundle: {
src: 'index.js',
dest: 'bundle.min.js'
},
options: {
browserifyOptions: {
debug: true
},
transform: [
['vueify']
]
}
}
});
grunt.loadNpmTasks('grunt-browserify');
grunt.registerTask('build', function() {
grunt.task.run('browserify');
});
};
With the Grunt file written, we just need to run
grunt build
in the command line (in the same directory as
the file) and Grunt will use Browserify to generate a single file
called bundle.min.js
which you can put in your web
application to render the Vue components you've built.
Next steps
If you want to do more with Grunt, consider using ESLint to check all of your code follows linting guidelines. And use grunt-ssh to deploy your bundle onto your webserver.