Hooking Up VueJS

In this article we're going to look at including the VueJS Framework with our Webpack project. Much like Angular, there is a VueJS CLI, which creates a pre-made webpack boilerplate for you. But this course is all about deciphering what's in those boilerplates, so we're going to build it with plain Webpack to under stand it better.

We're going to start from a common place. The hookup branch.

git clone https://github.com/lawwantsin/webpack-course.git
cd webpack-course
git checkout hookup
npm install

Let's start by installing vue and the vue loader.

In the terminal:

npm install vue \
  vue-loader

Now let's add those to the webpack config.

In webpack.dev.js:

const { VueLoaderPlugin } = require('vue-loader')

module: {
    rules: [
      {
        test: /\.vue$/,
        use: 'vue-loader'
      }
    ]
  },
  plugins: [
    new VueLoaderPlugin()
  ]

Next we need to hookup the .vue templates and styles.

In terminal:

npm install vue-template-compiler \
vue-style-loader

We also want some new files.

touch src/app.js src/App.vue

In main.js let's put app.js in our requires.

require("babel-runtime/regenerator")
require("webpack-hot-middleware/client?reload=true")
require("./main.css")
require("./images/link.jpg")
require("./index.html")
require("./app") // Add this

Now lets setup the root of our new VueJS app in app.js:

import Vue from "vue"
import App from "./App.vue"

new Vue({
  el: "#app",
  render: h => h(App)
})

the render property takes a function, that gets passed as it's first argument, a function that turns vue templates into Virtual DOM. This argument is called createElement, usually abbreviated with h.

Let's take the profile out of our index.html file and put it into the App.vue file inside a template element.

In index.html:

<html>
  <head>
  </head>
  <body>
    <div id="app"></div>
  </body>
</html>

In ./App.vue:

<template>
  <div class="profile">
    <img src="./images/link.jpg" alt="">
    <h1>Link's Journal</h1>
  </div>
</template>

No need to change class to className. Vue templaes just work like HTML, but with more magical attributes, if you will. The Vue loader can find images in context just as well as any other framework, so we see images is the full path in the output.

Vue Devtools

When we load the page, we see it's working as before. One thing, the console advises is to get the Vue chrome extension.

Search Vue chrome extension and download. When we open it up we can see we have a single component, with no state.

https://github.com/vuejs/vue-devtools

Component State

So let's add a state to our top component to illustrate that.

In app.js, you're going to want to change things a bit, to use a component within your Vue app.

import Vue from "vue"
import App from "./App.vue"
import Profile from "./components/profile"

new Vue({
  el: "#app",
  components: { Profile },
  render: h => h(App)
})

We denote the components that this app recognizes in the components object. Let's create a new file, in terminal:

mkdir src/components
touch src/components/profile.js

Let's take the profile html out of there are replace it with a Profile component.

In App.vue:

<template>
  <Profile  />
</template>

In components/profile.js let's paste the profile html in a template inline template literal:

import Vue from "vue"
export default Vue.component("Profile", {
  data: () => ({
    name: "Law"
  }),
  template: `
    <div class="profile">
      <img src="./images/link.jpg" alt="">
      <h1>{{ name }}'s Journal</h1>
    </div>
  `
})

You'll notice, the profile doesn't show up and we have a somewhat cryptic error message about a runtime library vs a compile library.

What this means is we are pointing at the production version of VueJS by default. The way to grab the development version, in development.

In webpack.dev.js:

resolve: {
  alias: {
    vue$: "vue/dist/vue.esm.js"
  }
},

We'll then be able to use components in VueJS.

In Sum

In this episode we got into VueJS. We added a vue-loader and plugin and a simple alias to our webpack dev config, so as to be able to use VueJS components.

You can see, there's not much new or special about vue js file types. Webpack gobbles them up and turns them into javascript like everything else.