Skip to content
2

[Bug Report] "$attrs is readonly" and "$listeners is readonly" console messages. #4068

Answered by KaelWD
appurist asked this question in General
[Bug Report] "$attrs is readonly" and "$listeners is readonly" console messages. #4068
May 15, 2018 · 121 answers · 12 replies

Versions and Environment

Vuetify: 1.1.0-alpha.4
Vue: 2.5.16
Browsers: Chrome 66.0.3359.139
OS: Linux x86_64

Steps to reproduce

Expected Behavior

Normal console messages (quieter). This was the case in 1.0.

Actual Behavior

This pair of messages appears for every button in the toolbar. There are two buttons in the repo example, so there are four messages total (first 2 shown below, repeats not shown).

./node_modules/vue/dist/vue.runtime.common.js:589 [Vue warn]: $attrs is readonly.

found in

---> <VBtn>
       <VToolbar>
         <VApp>
           <Electify> at src/renderer/App.vue
             <Root>
warn @ ./node_modules/vue/dist/vue.runtime.common.js:589
./node_modules/vue/dist/vue.runtime.common.js:589 [Vue warn]: $listeners is readonly.

found in

---> <VBtn>
       <VToolbar>
         <VApp>
           <Electify> at src/renderer/App.vue
             <Root>
warn @ ./node_modules/vue/dist/vue.runtime.common.js:589

Reproduction Link

https://github.com/appurist/electrify

Other comments

  1. Replace 1.1.alpha.4 with 1.0 and the messages disappear.
  2. Removing the buttons resolves the messages.
  3. Removing the footer entirely resolves the messages.
  4. Removing app from the footer resolves the messages.
  5. Removing app from the header does NOT resolve the messages.
  6. Replacing the v-button/v-icon combinations with simple v-icon resolves the messages.

Note: If the dev tools are not visible for the console when running the app, Ctrl-Shift-I shows them (also menu). I was unable to reproduce this with a web build of the app, thus unable to reproduce with a simpler codepen either; there may be some kind of conflict between Vuetify's use of an app mix-in and Electron.

Replies

121 suggested answers
·
12 replies
1

I believe the problem may lie in src/mixins/applicationable.js due to the watch triggering an unbind/bind sequence after Vue has completed initialization. (Is this used anywhere other than Jest testing?)

0 replies
1

Note that the warnings only come out (from Vue) in src/core/instance/lifecycle.js if isUpdatingChildComponent (which starts as true) has already been set to false. This is expected to be true once and then report this error if modifications are attempted after it is cleared.

There are several references to this error being triggered if Vue is included more than once (e.g. more than one version) but I don't think that's the case here. More detail here.

0 replies
1

Oh I just found this: vuejs/vue-test-utils#532
The "two instances of Vue" problem might be esm vs commonjs.

0 replies
1

two instances of Vue

That'll probably be because we have to import vue ourselves now for TS to work. Particularly if it only happens with VBtn. I tried fixing this with 4890c83 but I think it'll need to be factory functions instead unfortunately.

0 replies
1

This should change it for us too: https://github.com/appurist/electrify/blob/master/.electron-vue/webpack.renderer.config.js#L125

Were you using yarn link?

0 replies
1

I started by making the same change in my webpack file and it did not help, it seems like there's still two different paths to Vue, even if they are all esm, which may mean two instances. With webpack, if one path is absolute and one is relative, perhaps it treats those as different? Or one is being webpacked and one not...

I had used yarn link earlier, but once I completed my commits/PRs, while trying to track this down, I had reinstalled vuetify@next and nuked the whole node_modules tree and reinstalled. Also, my coworker has the same trouble and doesn't use link. It doesn't seem to affect our web build, maybe it's defaulting to production there, but it does affect both our 'dev' and 'build' Electron builds.

But it's not Electron-specific, the vue-test-utils issue mentioned above includes a codesandbox repro which isn't electron. They made a change in a beta update and when they attempt to use it with Vuetify, they have the same problem. (That looks like maybe 1.0 of our code here, but their explanation for the trigger may provide a clue, changing their waters to sync triggering an extra rerender.

To be honest, this feels like a bug in the check in Vue to me, but I don't really understand the problem yet so the jury is out on that.

Hmmm. Is the Vuetify load of Vue available from the object, e.g. as Vuetify.$vue or something like that? If so, maybe instead of importing it we just assign it like Vue = Vuetify.$vue and use that one.

0 replies
1

Yeah I'm not sure either, but as it's happening outside of tests and works fine with vuetify 1.0, I don't really know what else it could be. Vuetify's vue import is not made available anywhere, but WebpackBundleAnalyzer will show if there's different versions loaded.

I had to do this to the docs repo to prevent it from loading vue from the symlinked node_modules: vuetifyjs/legacy-docs@5fa3c69

0 replies
1

This will occur when using a locally linked Vuetify package and not aliasing vue to the esm file.

2 replies
@vegerot

How do I test a locally linked Vuetify package?

Not quite sure where I alias the esm file. Do I do the alias in my vue.config.js?

@vegerot

I know this is probably a silly question, but what I want to do is "transparently" replace the npm installd Vuetify with the Vuetify I've built locally. I don't want to change my project at all for this to work

1

This still occurs even even with aliasing 'vue$': 'vue/dist/vue.esm.js', in webpack config for jest/vue-test-utils tests for me.

0 replies
1

In regards to vue-test-utils, this was a bug introduced in beta updates, vuejs/vue-test-utils#532

0 replies
1

In my repo above, I'm not doing any tests, or using vue-test-utils at all. I've also tried forcing the vue$ alias with both relative and path.resolve naming to no effect. I've also just confirmed it reproduces with the beta.0 release, however, I see now that the two versions of Vue are loaded, mostly vue.esm.js but also vue.common.js for the top three stack frames:
stack trace on breakpoint
As far as I can tell, that's all Vue code, just two copies and in the instance that complains, the isUpdatingChildComponent was initialized to false and updateChildComponent is never called (in that instance of Vue) so it has never been set to true.

The Vue check is to confirm that the code is in updateChildComponent (which it is, 4th stack frame in the traceback) but it is in the other instance so the boolean is still false in the runtime-only instance.

0 replies
1

tl;dr: Externalising vue but not vuetify causes duplicate modules. Add vuetify in here too to fix it: https://github.com/appurist/electrify/blob/master/.electron-vue/webpack.renderer.config.js#L21

What's happening is you have a copy of vue that's been run through webpack (the one in renderer.js, image 1) and the original straight from node_modules (image 2). Your application uses the webpacked one, and vuetify imports the original directly because webpack doesn't touch it. This wasn't a problem in 1.0 because our components were just bare objects, but now with typescript we have to export vue instances instead.

image

image

image

0 replies
1

Aha, I finally understand how the second copy is being loaded, which is which, etc. Thanks so much @KaelWD !

And I can confirm that if I include both vue and vuetify in that whiteListedModules list (i.e. treat them both the same way in the externals section of the config), that the problem goes away for both the 'electrify' sample repo above, as well as our internal project.

Case closed, we don't even need a change to Vuetify for this, we can take care of it in our webpack configs.

0 replies
1

I think this issue can be considered resolved, especially with Vue issue #8278 tracking the better longer-term solution.

The actual fix for this is to ensure both Vue and Vuetify are treated the same way in the webpack externals, e.g. putting both (or neither?) in the let whiteListedModules = ['vue', 'vuetify'] line in these vuetify webpack builds.

3 replies
@Phancie

The vuetify webpack being referred to here is the webpack.renderer.config.js which can be found in the .electron-vue folder.
Took me 3days to figure it out. Hope it makes someone else's life more easier

@mirikerstein

Hi appurist, if you're still around, can you expand on the solution a bit? I'm stuck on this as well... thanks.

@VIXI0

STOP!! HERE IS THE ANSWER let whiteListedModules = ['vue', 'vuetify'] IS LOCATED IN webpack.renderer.config.js

THANKS TO @appurist

1

@KaelWD @johnleider

Posting here as I can't find the time to create a reproduction at work for now.

Upgrading to v1.1.1 - this issue seems to occurring for my project because I was vendoring vuetify using Webpack 4 DllPlugin. The problem seems to go away if I've taken vuetify out of the vendoring. Whether "vue" is in the vendoring or not don't seem to make a difference.

If you think this is a legit issue you'd like to look at, please let me know if I should open a new ticket or if you'd just like to reopen. Thank you.

Dary

0 replies
1

If you run into this problem via a Rails web app, here is a skeleton app on how to fix it

https://github.com/lukebyrne/rails-vuetify-test

Just follow the git commits to see the changes made to get it resolved.

Many thanks to @KaelWD

the link is dead @lukebyrne

0 replies
1

That is, typically in the .electron-vue/webpack.renderer.config.js file, or where ever your webpack config file is. Find the whiteListedModules assignment and make sure it includes both 'vue' and 'vuetify'.

But i'm not in a electron app, how to add whiteListedModules in vueconfig/VueCLI3 ?
I tried insert in chainWebpack, but it doesn't work

@AlexandroWillianHervis - did you solved this problem? I have the same problem now

1 reply
1

@emancypage. I fixed by removing the vuetify-loader of my package.json: Try it.

0 replies
1

@emancypage. I fixed by removing the vuetify-loader of my package.json: Try it.

Can't remove that loader, because of peerDependency of @nuxtjs/vuetify

0 replies
1

There will be no absolute fix for this in the v2 major. This will naturally resolve in v3 with the new composition api.

If you have any additional questions, please reach out to us in our Discord community.

0 replies
1

@emancypage. I fixed by removing the vuetify-loader of my package.json: Try it.

This didn't work for me. Anyone else achieved a workaround?

0 replies
1

Is this possibly going anywhere..? I've been having this problem after adding firebase cloud functions folder to my project...

0 replies
1
2

There seems to be some confusion around this as it can be caused by a few unrelated things:

Unit testing

We use Vue.extend in our components, so the vuetify plugin must be installed globally to work properly.

Incorrect:

import Vuetify from 'vuetify'
import { mount, createLocalVue } from '@vue/test-utils'
import component from './my-component.vue'

const localVue = createLocalVue()

localVue.use(Vuetify)

describe('module', () => {
  let vuetify
  beforeEach(() => {
    vuetify = new Vuetify()
  })

  it('should do something', () => {
    const wrapper = mount(component, {
      localVue,
      vuetify
    })
  })
})

Correct:

import Vue from 'vue'
import Vuetify from 'vuetify'
import { mount, createLocalVue } from '@vue/test-utils'
import component from './my-component.vue'

Vue.use(Vuetify)

const localVue = createLocalVue()

describe('module', () => {
  let vuetify
  beforeEach(() => {
    vuetify = new Vuetify()
  })

  it('should do something', () => {
    const wrapper = mount(component, {
      localVue,
      vuetify
    })
  })
})

Non-default vue import

Incorrect:

// main.js
import Vue from 'vue/dist/vue.runtime.esm.js'

Correct:

// main.js
import Vue from 'vue'

// webpack.config.js
module.exports = {
  //...
  resolve: {
    alias: {
      'vue$': 'vue/dist/vue.runtime.esm.js'
    }
  }
}

Monorepo/symlinks

If you have a directory structure like this:

project/
├── app/
│   └── node_modules/
│       └── vue/
└── library/
    └── node_modules/
        └── vue/

or are developing a library and testing it with yarn link

import Vue from 'vue' will resolve project/app/node_modules/vue in the app and project/library/node_modules/vue in the library, resulting in two copies of vue being loaded. We need to configure webpack to only load one.
The first step is making sure the library doesn't include vue or vuetify when it's built:

// library/webpack.config.js
module.exports = {
  //...
  externals: {
    vue: {
      commonjs: 'vue',
      commonjs2: 'vue',
      amd: 'vue',
      root: 'Vue'
    },
    vuetify: {
      commonjs: 'vuetify',
      commonjs2: 'vuetify',
      amd: 'vuetify',
      root: 'Vuetify'
    }
  }
}

Then we tell the app to only load its copy:

// app/webpack.config.js
const path = require('path')
module.exports = {
  //...
  resolve: {
    symlinks: false,
    alias: {
      'vue$': 'vue/dist/vue.runtime.esm.js',
      '^vuetify': path.resolve(__dirname, 'node_modules/vuetify')
    }
  }
}
5 replies
@flyingL123

For me this did not work. I was still getting two versions of vue. I needed to change the vue line to:

'vue$': path.resolve(__dirname, 'node_modules/vue/dist/vue.esm.js'),

That seems to have resolved it.

Source: vuejs/vue-cli#4271 (comment)

@emanuelgsouza

Thank you so much for this comment. It worked here

Answer selected by KaelWD
2

createLocalVue is designed specifically to prevent polluting the global Vue instance. Especially if not all the tests require some plugins or test behaviour that assumes the plugin to not exist.

0 replies
1

Too bad, it doesn't work with Vue.extend()

0 replies
1

For anyone experiencing this problem with Rails and Webpacker if you are importing Vue with the compiler:

import Vue from 'vue/dist/vue.esm'

to resolve this issue add the following line to the config/webpack/environment.js file:

environment.config.resolve.alias = { 'vue$': 'vue/dist/vue.esm.js' };

just before this line:

module.exports = environment
1 reply
1

@dennyf you're a lifesaver, thanks!

0 replies
1

Hi! I'm working on a Vue Microfrontend POC with Vuetify and SystemJS: https://github.com/Saveriu/vue-microfrontends
I have a lot of errors when I load a Vuetify (/app2) app into another (/main).
I think it's caused by a confusion between webpack modules at build time and systemjs at runtime.
If you guys have the time to check on that project it will be great! Thanks a lot!

0 replies
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Category
#️⃣
General
Labels
None yet
Converted from issue
Beta