Integrating Vue 2.5, Webpack 4, Babel, and ESLint into an existing website

And the first step in the great migration away from jQuery

Ian Johnson
Skilljar Engineering
7 min readJul 11, 2018

--

By Ian Johnson, a Sr. Front End Engineer at Skilljar

Skilljar is the leading customer training platform for enterprises to accelerate product adoption and increase customer retention. Our platform provides all the essential tools for Customer Training and Enablement teams to successfully onboard, engage and retain customers.

At Skilljar one of our 2018 goals is modernizing our customer facing dashboard, both design and under the hood — and part of that is beginning the migration of some legen-(wait for it)-dary jQuery over to a reactive framework (ex. React, Vue, Angular, etc).

While we haven’t set any single direction in stone, our initial dive is adding a dash of Vue and its single file components into our existing app alongside that glorious, glorious, jQuery.

So how do we get these working together?

Let me Google that for you 👍

I kid, I kid, because I started there and everything was either out of date or overloaded for what I considered a real MVP (no, we don’t need hot module reload for the MVP), which left me untangling documentation for a pretty average use case — adding Vue, Webpack, Babel, and ESLint into an existing website that already uses it’s own asset pipeline (otherwise this would be one of the many start-from-scratch tutorials already out there).

What do I mean by that? A website that uses something like Grunt to build it’s Javascript and/or CSS as well as some form of cache busting asset tag, ala -

  • Django (Python): {% static 'assets/app.css' %}
  • Ruby on Rails: <%= stylesheet_link_tag 'app', media: 'all' %>
  • Laravel (PHP): {{ asset('assets/app.css') }}

Which take a static asset (ex. app.css) and detects and renames it if it’s changed (ex. to app.f5fbbd10a8fcabc133b3d653878f6eb6.css) so the user’s browser will get served the new version and bust the cache.

Side note: At Skilljar we also use Django and Heroku, so I’ll also highlight the (relatively small) steps to get this working with both of those as we go, but you really don’t need to be working with either for the this to be relevant.

Also ESLint is optional, so if you don’t want any linting I’ll call out what you can skip.

So then, onto the good stuff!

What… exactly are we doing here?

Don’t want to wait? Here’s the repo https://github.com/theianjohnson/blog-integrating-vue-2-5-webpack-4-babel-and-eslint-into-an-existing-website

We want to setup our Vue, Webpack, Babel, and ESLint to compile our .js, .scss, and .vue files into side by side app-v2.css and app-v2.js files work alongside the existing build pipeline (ex. Grunt), but still let our application take care of the cache busting with it’s own asset tags.

Side note: Many tutorials seem to recommend html webpack plugin to automatically inject your compiled assets to your HTML, but other than on a small personal site I just don’t see how that’d integrate well with a larger framework.

Let’s say our existing website file structure started out something like this

/
/assets
app-v1.css
app-v1.js
/images
logo.png
index.html

We’ll end up with something like this

/
/assets
app-v1.css
app-v1.js
app-v2.css // New Webpack'd file
app-v2.js // New Webpack'd file
/images
logo.png
/webpack-assets // Keeping all our new NPM and Webpack stuff here
.babelrc // Babel config
.eslintrc.js // ESLint config
app.js // New Javascript to be Webpack'd
app.scss // New SCSS to be Webpack'd
HelloWorld.vue // Sample .vue component
package.json // NPM packages
package-lock.json
postcss.config.js // PostCSS config (minifier and prefixer)
webpack.config.js // Webpack config
index.html

Tell me more

Specifically, we’re going to weave Vue, Webpack, Babel, and ESLint together to output our compiled CSS and JS files alongside our existing pipeline’s files that we can then add to the HTML as app-v2.css and app-v2.js (or whatever you’d like to name them).

And again - using the Django framework, being on Heroku, and installing ESLint are all optional.

First, my environment -

  • A mostly updated Macbook Pro running High Sierra (though this shouldn’t matter for what we’re doing)
  • Node v10.5.0 (We also have this running on Node v8.11.2)
  • NPM v6.1.0

The Setup

So first, let’s create a new directory so we don’t run into any conflicting NPM package.json’s — and we’ll output the compiled files to the correct directory later.

$ mkdir webpack-assets
$ cd webpack-assets

Let’s also make sure Node and NPM are installed (I have no idea what having a different version will change, so buyer beware).

webpack-assets$ node -v
v10.5.0
webpack-assets$ npm -v
6.1.0

If something’s not working go install https://nodejs.org/en/ from their website, then you can install NPM via the command line with Node, ala -

(The -g installs it globally, but if you don’t already have it, this shouldn’t really matter)

webpack-assets$ npm install npm@latest -g

And using our example existing website folder structure, it’d now look like this

/
/assets
app-v1.css
app-v1.js
/images
logo.png
/webpack-assets/
(empty)
index.html

The Configuration

Now let’s finally get this thing moving. Still in your webpack-assets (or whatever) directory, create your package.json file with the following (see below for what all these are for and which are optional).

package.json

Unfortunately I can’t inline comment .json files and I didn’t want to muddy that example up with errors, so — what do all these things do? Here’s a (non-runnable) example with inline comments -

It’s only a .js file for the code highlighting

And our Webpack config (with comments)

Note: For Django you’ll probably want to adjust the output paths to your static assets folder

webpack.config.js

And three more small configs (because config files are all the rage right now)

.babelrc

.eslintrc.js

and postcss.config.js

Now with all these config files our structure should look something like

/
/assets
app-v1.css
app-v1.js
/images
logo.png
/webpack-assets/
.babelrc
.eslintrc.js
package.json
postcss.config.js
webpack.config.js
index.html

Actual application files

Everything up till here has been our boilerplate for getting Vue, Webpack, Babel, and ESLint working in our project, so from here on out we’ll be creating some example files to make sure it works (and if you already know how to Vue and just needed help wiring things up, you should be able to comfortable stop here).

So then, let’s add some basic Vue, JS, and SCSS files so we can see what’s happening — this is where things will start getting more personalized for each of us beyond this example.

app.js

app.scss

HelloWorld.vue

One last look at our files

/
/assets
app-v1.css
app-v1.js
/images
logo.png
/webpack-assets/
.babelrc
.eslintrc.js
app.scss
app.js
HelloWorld.vue
package.json
postcss.config.js
webpack.config.js
index.html

And let’s get that Vue component on our website! Here’s a sample index.html -

index.html

And finally… let’s build this 👊

webpack-assets$ npm install // Will install all the thingswebpack-assets$ npm run dev // Run webpack in develop mode

Boom. Load up that HTML file (or your website or whatever you added this to) in your browser and look upon your shiny new toy that is Webpack and Vue.

index.html in all it’s glory

And if you’d like to run the linter (admittedly there’s not much to lint yet)

webpack-assets$ npm run lint

What about Heroku?

I did mention getting this to work on Heroku, and it’s actually pretty easy with buildpacks.

  1. Add your compiled files to your .gitignore since we’ll be compiling them as part of the buildpack step

.gitignore

# Webpack'd on the server
assets/app-v2.css
assets/app-v2.js

2. Add the Node buildpack to your app

On the Heroku dashboard, under your application’s settings

https://dashboard.heroku.com/apps/your-website-app-name/settings

Scroll down and add the heroku/nodejs buildpack

https://dashboard.heroku.com/apps/your-website-app-name/settings

Now when you deploy your app —

  1. The buildpack will look for a package.json in your root (so you will need to have that package.json we put in the /webpack-assets/ folder in your root)
  2. It will automatically run npm install
  3. It will look for both heroku-prebuild and heroku-postbuild commands in your package.json and run those. Which if you’ll remember, we set the heroku-postbuild to npm run build to compile our assets for production.

Interested in learning more about Skilljar? Check us out at https://www.skilljar.com/. We’d love to chat with you if you’re interested in joining the team. You can learn more about open positions at https://www.skilljar.com/about/careers/

And one last big shout out to Colty Harrison for running through all these instructions and helping me iron out the bugs. Cheers!

--

--

Ian Johnson
Skilljar Engineering

Owner, Front End Engineer, Data Engineer, Product Manager - Currently a Sr. Front End Engineer at Skilljar