Skip to content

Store not working in web components #2304

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
katerlouis opened this issue Aug 21, 2018 · 19 comments
Closed

Store not working in web components #2304

katerlouis opened this issue Aug 21, 2018 · 19 comments

Comments

@katerlouis
Copy link
Contributor

katerlouis commented Aug 21, 2018

Version

3.0.1

image

Node and OS info

node 10.7.0 / npm 6.3.0

Steps to reproduce

– Go to vue-cli GUI
– create new project (vuex, babel, less-css, no typescript)
– make a simple state in vuex: foo: "bar"
– make it a getter aswell
– go to App.vue
– import mapGetters from vuex
– use mapGetters in computed to get the foo value
– use it in the App.vue template: This is foo: {{ foo }}
– build a web component named: my-component
– open demo.html in a browser

What is expected?

No error

What is actually happening?

Error in console regarding the store :(


Without the store, webcomponents seem to work fine

@Kocal
Copy link
Contributor

Kocal commented Aug 21, 2018

What's the error in the console?

@katerlouis
Copy link
Contributor Author

omg, sorry for the missing error information. I edited the main post

@Kocal
Copy link
Contributor

Kocal commented Aug 21, 2018

It looks like vuex is not registered correctly. Is your main.js contains those lines? :

  • import VueRouter from 'vue-router'
  • Vue.use(VueRouter)

Also can you profide a reproduction repo please? It will easier for us to help you 🙂

@katerlouis
Copy link
Contributor Author

You are talking about VueRouter; did you just misspoke or do you actually mean the router? Because in my setup vuerouter doesn't play in :)

The main.js looks like this:

import Vue from 'vue'
import App from './App.vue'
import store from './store'

Vue.config.productionTip = false

new Vue({
  store,
  render: h => h(App)
}).$mount('#app')

I am facing the issue with a freshly created vue-cli project.
That's why I think the best is you create a fresh one yourself with the settings layed out in "steps to reproduce", don't you think? This way we surely ruled out it has anything to do with my doing / my code.

@Kocal
Copy link
Contributor

Kocal commented Aug 21, 2018

Oh damn, I always confound vuex and vue-router 😢

I will check on my side

@katerlouis
Copy link
Contributor Author

katerlouis commented Aug 21, 2018

Question not reagarding the bug:
When I got the webcomponent working, could I call a function from outside the console?
Following usecase: I make a webapp which is served as a modal; and the modal should be openable from many different buttons throughout the site. The easiest would be to do something like this:

document.querySelector('my-configurator').modalOpen()

(or some other way to trigger internal methods from the Wecomponent)

@Kocal
Copy link
Contributor

Kocal commented Aug 21, 2018

I made a reproduction repo here: https://github.com/Kocal/vue-cli-web-components-store

I confirm that building for web app (vue-cli-service build --mode production --dest dist --target app) works fine, but building for web component (vue-cli-service build --mode production --dest dist --target wc --name my-component) fails.

Sorry, I don't know enough about web components, I can't help you more 🤷‍♂️

@katerlouis
Copy link
Contributor Author

katerlouis commented Aug 21, 2018

Just to clear out possible misunderstandings:

The actual building process is successful for me; since 3.0.0rc13, where a --name bug was fixed, the actual building step works.

So building the webcomponent, both WITH and WITHOUT a store, seems to work.

The store-less version also works in the browser and correctly displays the app,
whereas the store version breaks with the mentioned error and displays nothing.

@Kocal
Copy link
Contributor

Kocal commented Aug 21, 2018

Yea sorry, when I mean "it works fine" and "it fails", I actually mean that app (always with store) is displayed when targeting web app, and is not displayed when targeting web component.

I look like Vue.use(Vuex) is not executed, or maybe there is a problem with vue-web-component-wrapper... 🤔

@katerlouis
Copy link
Contributor Author

Vue.use(Vuex) is inside the store.js by default; that's correct, right?

@Kocal
Copy link
Contributor

Kocal commented Aug 21, 2018

Yep

@haoqunjiang
Copy link
Member

A web component is a library, conceptually.

So its entry point is not main.js, but an entry-wc.js file generated here: https://github.com/vuejs/vue-cli/blob/dev/packages/%40vue/cli-service/lib/commands/build/resolveWcEntry.js

So to use vuex in web component target, you need to initialize the store in App.vue:

import store from './store'

// ...

export default {
  store,
  name: 'app',
  // ...
}

@katerlouis
Copy link
Contributor Author

katerlouis commented Aug 21, 2018

It works! Both in a webcomponent and a library as target.

tenor-1

Thank god you people are faster than an ambulance–

no way I would've figured that out without your help.

Just to be sure now @sodatea
Will it become a problem when I leave the "global declaration" of the store both in the main.js AND the App.vue? Right now it is working on the localhost:8080 served page with a store declaration in BOTH files.

But I'm afraid this is not a good idea.
Would be cool to leave it in both, though, because the app will be shipped as a single SPA and a Library/Webcomponent aswell.

PS: is this behaviour documented somewhere? I'm so overworked I probably wouldn't have found it anyways; but this is definitely worth a notice somewhere.

@haoqunjiang
Copy link
Member

It's ok to leave it in both.

  1. store.js will execute only once;
  2. store injection works fine for this kind of usage, as you can tell from vuex source code:
    https://github.com/vuejs/vuex/blob/dev/src/mixin.js#L22

@katerlouis
Copy link
Contributor Author

Nice! +1
I can't find anything regarding vuex when building a library or webcomponent.
How about putting this as a notice on the build targets page?
https://cli.vuejs.org/guide/build-targets.html

@haoqunjiang
Copy link
Member

PRs are welcome 😀

@katerlouis
Copy link
Contributor Author

You entrust me, the one struggling with the terminology and concepts behind it, to alter / enhance the official documentation?

tumblr_njzrzaicmg1s3h43ko1_500

katerlouis added a commit to katerlouis/vue-cli that referenced this issue Aug 22, 2018
I really needed this tip and luckily got it from this awesome community in a github issue.
This definitely needs to be in the docs aswell:
vuejs#2304 (comment)
@sudoris
Copy link

sudoris commented Nov 6, 2018

what is different about projects created using Vue CLI 3.0 that this extra step is now required?

@chipit24
Copy link

chipit24 commented Dec 5, 2018

From the Vuex docs:

When using a module system, it requires importing the store in every component that uses store state, and also requires mocking when testing the component.

Vuex provides a mechanism to "inject" the store into all child components from the root component with the store option (enabled by Vue.use(Vuex)):

Is this somehow possible to set up with a library build target? In lib mode, Vue is externalized, so we can't rely on new Vue({ store, ... }).

Simply007 added a commit to Kentico/ems-extension-marketplace that referenced this issue Jul 16, 2019
pksunkara pushed a commit that referenced this issue Oct 11, 2019
I really needed this tip and luckily got it from this awesome community in a github issue.
This definitely needs to be in the docs aswell:
#2304 (comment)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants