Adding Vue.js to Sage 9: Dependencies and Approach

sage9

#1

Here’s how to add Vue.js support to your Sage 9 project.

1. Add dependencies

yarn add vue
yarn add --dev babel-core babel-eslint babel-loader \
  babel-plugin-transform-runtime babel-preset-env \
  babel-preset-stage-2 babel-register \
  vue-loader vue-style-loader vue-template-compiler

2. Add a .babelrc file

{
  "presets": ["es2015", "stage-0"],
  "plugins": ["transform-runtime"]
}

3. Add stuff to webpack.config.js

To your webpack.config.js file (found in resources/assets/build/), add this to modules.rules:

{
  test: /\.vue$/,
  loader: 'vue'
},

And to force the runtime to include the full compiler (only needed if you want your root Vue element to be parsed as a Vue template), add this under resolve:

alias: {
  'vue$': 'vue/dist/vue.esm.js' // 'vue/dist/vue.common.js' for webpack 1
},

4. Setup a directory for your .vue components

resources/assets/scripts/vue/ seems like a good spot for those .vue components.

Here’s an example:

The root vue element is here:

And here’s home.js hooking a Vue instance to parse that element and calling that sites.vue component:


#2

Bravo, bravo :clap: :clap: :clap:


#3

Or just use laravel mix and be done with it.


#4

I really like the way Laravel Mix allows you to work with VueJS. However to integrate Laravel Mix into sage without compromising the way sage handles js/webpack is something I haven’t been able to accomplish yet.

So the way I make Vue possible within sage allows me to work with vue files quite similar as I would be working with Laravel Mix. Which is defining vue components in main.js that you store in a separate vue directory, and use them site-wide. This implementation is inspired by @pascallaliberte (thx!) and could definitively be improved as I’m not JS/webpack savvy but its working for my projects. I wanted to share it, in case someone else could benefit from it as well.

Step 1.
run from the theme folder: yarn add --dev vue vue-loader vue-template-compiler

Step2.
add the following blocks to resources/assets/build/webpack.config.js with the rules section

 {
    test: /\.vue$/,
    loader: 'vue-loader'
  }

Step 3.
Within resolve section of that same file:

alias: {
  vue: 'vue/dist/vue.js'
},

Step 4.
At the top of main.js file you add import Vue from 'vue'

Step 5.
Make sure you created the vue directory within the scripts directory

Step 6.
edit resources/config.js and add the following to the watch section "resources/scripts/vue/**/*.vue"

Step 7.
Define your components like Vue.component('your-element-name-goes-here', require('./vue/test.vue').default);

Step 8.
After your components add:

 new Vue({
  el: '#app',
});

Step 9.
Within views/layouts/app.blade.php make sure to embody @include(‘partials.header’) till @include(‘partials.footer) with <div id="app"></div> so you get something like

...
<div id="app">
@include(‘partials.header’)
...
@include(‘partials.footer)
</div>
...

Step 10.
Add your custom element to a page template and check it out with yarn run start / build

edit: Added an extra step (step 6) for watch support when running yarn run start


#5

Updated instructions for buble instead of babel

Sage 9 is now packaged with buble, so a few tweaks are needed.
Also, vue-loader is now setup differently, so we need to update that too.

So here’s an updated setup (assuming you’re starting from scratch with a new Sage 9 install):

Caveat: vue-style-loader not configured!

I haven’t figured out how to setup vue-style-loader with Sage 9’s buble setup. I just style my components as part of my central sass styles and I remove the <style> block in my .vue templates to avoid compilation errors.

If you figure out the vue-style-loader integration (especially handy for including third-party vue components), please comment below and I’ll update my post with instructions and attribution. Thanks!

1. Add dependencies

yarn add vue
yarn add --dev vue-loader vue-template-compiler eslint-plugin-vue

vue-style-loader not installed, see caveat above.

2. Add stuff to webpack.config.js

To your webpack.config.js file (found in resources/assets/build/), include vue-loader:

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

Add this to module.rules:

      {
        test: /\.vue$/,
        loader: 'vue-loader',
      },

And to force the runtime to include the full compiler (only needed if you want your root Vue element to be parsed as a Vue template), add this under resolve:

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

Now register VueLoaderPlugin under plugins.

    new VueLoaderPlugin(),

I placed mine after the debug watcher plugin (does it even matter?):

    new webpack.LoaderOptionsPlugin({
      minimize: config.enabled.optimize,
      debug: config.enabled.watcher,
      stats: { colors: true },
    }),
    new VueLoaderPlugin(), //here

3. Lint .vue files properly

In .eslintrc.js, replace the extends property with:

  "extends": [
    "eslint:recommended",
    "plugin:vue/essential",
  ],

4. Setup a directory for your .vue components

resources/assets/scripts/vue/ seems like a good spot for those .vue components.

See example reference above in the original post.


Hope this helps, and please share your suggestion for vue-style-loader integration.