Adding Vue.js to Sage 9: Dependencies and Approach

Wish I could help Stuart, but I’m just getting started with the Roots stack, myself.

I’m also having a small issue. Until this point, everything has been compiling fine, until trying to get mixins working properly. When creating one and using it all within a single file component – no problem. Works great. But when importing a mixin from an external file, it breaks the component. The external JS is even in the same directory.

So the external file (slideBase.js) looks something like this:

export const slideBase = {
    // mixin here
};

I also tried:

export default {
  // mixin here
}

In the single file component:

import { slideBase } from './slideBase.js'
export default {
  name: 'slide-half-2',
  mixins: [slideBase],
  data() {
    ...

This should be correct, yes?

Anyone else running into mixin problems? Couldn’t find any info remotely related to this. On the discourse or otherwise.

Cheers,

@db12

I haven’t had much experience with vue mixins but is it possible to use require instead of import? Something similar to the way I am defining components below:

components: {
	'test-component-1': require('./TestComponent1.vue').default,
	'test-component-2': require('./TestComponent2.vue'').default,
},

So in your case it would be:

mixins: [require("./slideBase.js").default]

I don’t understand why the ‘.default’ part is needed for my components. Perhaps the webpack script can be updated to avoid this?

Didn’t end up solving the problem. However, I’m getting the same console error that one of my variables is undefined. If my logic is correct, that could mean that it is indeed importing when trying both import and require, and something else is going on. I’m on Vue forums to try to understand the big picture of loading order for a component – since I’m using a vuex store and such. Will bring up more here if I find webpack/vue-loader to be the issue.

@pascallaliberte

A different issue – I’m having trouble getting global sass variables with sass-loader to work properly. I combined the instructions here with your method of adding vue-style-loader for CSS. So the rule is placed above the other test: /\.scss$/ and looks like this:

      {
        test: /\.scss$/,
        exclude: config.paths.assets,
        use: [
          { loader: 'vue-style-loader' },
          { loader: 'css-loader' },
          { loader: 'sass-loader',
            options: {
              data: `@import "scripts/vue/Project/SCSS/test.scss";`
            },
          },
        ],
      },

When I load a variable into test.scss, I’m still getting a build error ‘undefined variable’ when trying to use it in the single file component:

<style lang="scss">
</style>

The test: /\.css$/ rule from the above instructions is still present.

Any ideas?
Thanks.

Yeah, the one problem that I think is remaining from this setup is that the scss extracted from .vue files ends up being parsed before the rest of the site’s scss. Because of that, your global sass variables aren’t available at the time the .vue styles are parsed.

I haven’t looked deeper into why this is happening this way. Maybe someone will fall on the solution.

Am getting an error when i try to do any scss styles in the vue component. If left blank, it works. But if i add for eg body {}, i get a Module build failed: TypeError: Cannot read property 'postcss' of null at Processor.normalize

I wonder if Sage 10’s use of Laravel Mix will make Vue integration a little easier…

These configuration changes work well for the most part but I think they may be causing conflicts and browsersync issues…

2 Likes

I’ve followed all of the instructions here to get Vue setup. I’m using the latest Sage 9 version with Tailwind.

My console produces the following error:

[Vue warn]: You are using the runtime-only build of Vue where the template compiler is not available. Either pre-compile the templates into render functions, or use the compiler-included build.

In place of the component Vue renders:
<!--function (a, b, c, d) { return createElement(vm, a, b, c, d, true); }-->

This guide worked almost perfect for me.

However, I had error Parsing error: Unexpected token .. every second time when I ran yarn build (wierd).
Here is my code which caused the error:

  computed: {
    ...mapGetters({// <-- yarn build breaks here sometimes
      allDogPlaceCoordinates: 'allDogPlaceCoordinates',
    }),
  },

The good news Looks like this solution resolves this build error:
update value 'ecmaVersion': 2017
to value 'ecmaVersion': 2018
site/web/app/themes/theme-name/.eslintrc.js

source:

This was very helpful, I managed to get it working with vuex,
Thank you for posting this. I was wondering if you were using the chrome vue extension with this and if you were is there something I need to enable to use it?

Never mind I got it working :slight_smile:

I had this issue and it ended up being because I completely skipped the bit where it says to resolve in the webpack.config.js file:

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

No idea why I did that and no doubt you’ve got it fixed after 5 months but as it came up as the first hit on Google for me, I thought I’d post.

Hi,

First of all, thank you for this solution!
Everything works very well, except async and await.

When I use them, I always get a “Unexpected token” compilation error.

I put the line ‘ecmaVersion’: 2018,

Do you have an idea?

Thank you !

Is there any follow up to this?

Thanks for the instructions - I’ve managed to get Vue working quite well. However, the one issue I’ve come across so far is that my Sage site doesn’t seem to want to change es6.

This is my .eslintrc.js file. It has ecmaVersion set to 2017, which is the version in which async await were added.

module.exports = {
  'root': true,
  'extends': [
    'eslint:recommended',
    'plugin:vue/essential',
  ],
  'globals': {
    'wp': true,
  },
  'env': {
    'node': true,
    'es6': true,
    'amd': true,
    'browser': true,
    'jquery': true,
  },
  'parserOptions': {
    'ecmaFeatures': {
      'globalReturn': true,
      'generators': false,
      'objectLiteralDuplicateProperties': false,
      'experimentalObjectRestSpread': true,
    },
    'ecmaVersion': 2017,
    'sourceType': 'module',
  },
  'plugins': [
    'import',
  ],
  'settings': {
    'import/core-modules': [],
    'import/ignore': [
      'node_modules',
      '\\.(coffee|scss|css|less|hbs|svg|json)$',
    ],
  },
  'rules': {
    'no-console': 0,
    'quotes': ['error', 'single'],
    'comma-dangle': [
      'error',
      {
        'arrays': 'always-multiline',
        'objects': 'always-multiline',
        'imports': 'always-multiline',
        'exports': 'always-multiline',
        'functions': 'ignore',
      },
    ],
  },
};

I’m still getting the following error within a Vue component that is using async await.

 ERROR  Failed to compile with 1 errors                                          9:12:30 PM

 error  in ./resources/assets/scripts/vue/RequestForQuote.vue?vue&type=script&lang=js&

Module build failed: 
47 :   methods: {
48 : 
49 :     /* eslint-disable no-unused-vars */
50 :   
51 :     async addProduct() {
               ^
Unexpected token (51:10)

 @ ./resources/assets/scripts/vue/RequestForQuote.vue?vue&type=script&lang=js& 1:0-289 1:310-596
 @ ./resources/assets/scripts/vue/RequestForQuote.vue
 @ ./resources/assets/scripts/routes/common.js
 @ ./resources/assets/scripts/main.js
 @ multi ./resources/assets/build/util/../helpers/hmr-client.js ./scripts/main.js ./styles/main.scss

Everyone has mentioned the 'ecmaVersion': 2018 fix, however that doesn’t work for me. I get the same error, and the impression that it’s not really changing anything, and Sage isn’t actually changing its ecma version.

When I’ve looked into the environments being used by eslint, it only seems to list es6 as an environment - changing this to something like es8 results in an error.

Would greatly appreciate any help on the matter - at the very least being shown how to definitively change the ecmaVersion within Sage.

Thanks!

1 Like

Facing the exact same problem.

I’m fairly certain the issue you’re encountering is not related to eslint–if it were a linting issue, the error should be something more like “I’m afraid you can’t use async” instead of Unexpected token which almost always means that a parser has encountered an unsupported language feature. As mentioned elsewhere, Sage 9 uses Buble instead of Bable to transpile JS, and so far as I can tell Buble does no support async–hence the error you’re seeing. I haven’t tested this, but I think you should be able to rip out Buble and replace it with Babel and then just change the loader here: https://github.com/roots/sage/blob/f3e794a09374d2f110742d15b9b975490fcddbee/resources/assets/build/webpack.config.js#L58

1 Like

I fixed the async/await problem by installing ‘babel-loader’ and replacing ‘buble’ with ‘babel-loader’ in webpack.config.js (remove ‘buble’ options):

 {
    test: /\.js$/,
    exclude: [
      /node_modules(?![/|\\](bootstrap|foundation-sites))/,
    ],
    use: [
      {loader: 'cache'},
      {loader: 'babel-loader', options: {}},
    ],
  },

Not sure what other effects this has (apparently performance), but it seems to work fine for me…

3 Likes

Thank you for your response (and you too @alwaysblank) you are both correct - replacing buble with babel-loader did the trick! Very thankful!

1 Like

hey @flei, Are you facing any sort of issues, because of the switch?

Hello. I have followed the above instructions to incorporate vue in my sage theme. One question if I may:

Currently I am using one main_vue.js fie that contains all the instances of vue that are related to each page of my app. This one file is imported in main.js of sage and is loaded for all pages - when a id name of an element matches the one from the vue instances, the related component.vue is mounted.

Is there a reason for preferring separate files for the vue instances and importing them separately in main.js of sage, defining them as separate routes ( besides what the documentation says, about JavaScript DOM-based routing ) ?

Thank you.