nuxt / nuxt

The Intuitive Vue Framework.
https://nuxt.com
MIT License
54.53k stars 4.99k forks source link

Allow installing Vuex plugins #560

Closed ndarilek closed 7 years ago

ndarilek commented 7 years ago

I want to use vuex-persistedstate in my app. This requires that I inject the plugin like so:

new Vuex.Store({plugins: ...})

Maybe nuxt.config.js could have a vuex.plugins option for initializing the store with the specified plugins?

This question is available on Nuxt.js community (#c485)
atinux commented 7 years ago

You can do it by using the Classic Mode.

ndarilek commented 7 years ago

Any way to do this in non-classic mode?

It also isn't clear how to do it in classic mode, since it looks like there's no way to inject parameters into the new Store(...) call.

atinux commented 7 years ago

Since in Class Mode you create yourself the store with new Vuex.Store, you can inject the plugins manually.

sebastianmacias commented 7 years ago

are there any plans to eventually support it in modules mode?

atinux commented 7 years ago

Right now there is now plan for supporting it @sebastianmacias

We could imagine exporting in the store/index.js a pluginsarray that can be given to the Vuex Store instace.

Any PR is welcome for implementing this :)

sebastianmacias commented 7 years ago

I would love to contribute. I short writeup on nuxtjs.org, listing the steps required to setup a development environment for nuxt would be great.

bitmage commented 7 years ago

+1... prefer modules, but they seem to fall short in not supporting this...

rof20004 commented 7 years ago

+1 I am with the same problem right now.

atinux commented 7 years ago

It will be supported in the upcoming release (1.0.0-alpha1)

rof20004 commented 7 years ago

Thanks @Atinux

ndarilek commented 7 years ago

So how does this feature work now that the respective alpha is out? I can't see how I'd add the vuex-persistedstate plugin. Tried exporting a plugins list in index.js like so:

export const plugins = [createPersistedState()]

But I suspect that won't work. What I probably need to do is export a function that initializes the plugins, then have that function's result added to the plugins option when the store is created. But that doesn't seem to work either.

krasevych commented 7 years ago

Hi guys! I have a problem: I have store:

import Vuex from 'vuex';
import auth from 'src/store/modules/auth';
import createPersistedState from 'vuex-persistedstate';

export const plugins = [
  createPersistedState(),
];

export default new Vuex.Store({
  strict: process.env.NODE_ENV !== 'production',
  modules: {
    auth,
  },
});

and I got a error:

ReferenceError: window is not defined
    at createPersistedState (D:\Projects\Vue\Smart Landing\smart-landing-client\node_modules\vuex-persistedstate\dist\vuex-persistedstate.js:54:66)
    at Object.module.exports.Object.defineProperty.value (src/store/index.js:6:2)
    at __webpack_require__ (webpack:/webpack/bootstrap 9f07d01ff16351a90719:25:0)
    at webpackContext (webpack:/src/store ^\.\/.*\.js$:6:0)
    at getModule (.nuxt/store.js:9:13)
    at Object.module.exports.Object.defineProperty.value (.nuxt/store.js:31:19)
    at __webpack_require__ (webpack:/webpack/bootstrap 9f07d01ff16351a90719:25:0)
    at Object.<anonymous> (.nuxt/index.js:6:0)
    at __webpack_require__ (webpack:/webpack/bootstrap 9f07d01ff16351a90719:25:0)
    at Object.module.exports.Object.defineProperty.value (.nuxt/server.js:10:0)
    at __webpack_require__ (webpack:/webpack/bootstrap 9f07d01ff16351a90719:25:0)
    at module.exports.$Object (webpack:/webpack/bootstrap 9f07d01ff16351a90719:93:0)
    at Object.<anonymous> (server-bundle.js:98:10)
    at evaluateModule (D:\Projects\Vue\Smart Landing\smart-landing-client\node_modules\vue-server-renderer\build.js:6967:21)
    at D:\Projects\Vue\Smart Landing\smart-landing-client\node_modules\vue-server-renderer\build.js:6985:15
    at D:\Projects\Vue\Smart Landing\smart-landing-client\node_modules\vue-server-renderer\build.js:6983:12

what do I do wrong?

atinux commented 7 years ago

@krasevych you are using a plugin which is not SSR compatible (since it uses window directly).

You can try with spa mode (rc5) but you won't have SSR benefits.

sullivanpt commented 7 years ago

@krasevych you might be able to use cookies with 'vuex-persistedstate' using its customize storage, and being careful to access req.cookies verses document.cookies as in the example with-cookies. Caveat is you'll want to use filter to keep the persisted state very small since it will be sent with each server request and be limited 4096 characters. As I think on it, you'll probably have to do something clever with vuex-persistedstate replaceState handling too, since it will conflict with Nuxtjs client side hydration.

Let me know how it works out.

michaelpumo commented 7 years ago

Ah, such a roadblock for me.

I am trying, like @krasevych to use vuex-persistedstate in my Vuex store.

Nuxt seems to accept the plugin, but I get the same window error.

I don't mind just having vuex-persistedstate on the client-side - is there a way to make that happen at all that anyone knows of? No need for a server-side version.

:(

bitmage commented 7 years ago

@michaelpumo You're supposed to be able to do something like this:

{
  src: '~plugins/vuex-persistedstate.js',
  ssr: false
},

And you could define your own file in the plugins directory that loads the plugin into vuex. The {ssr: false} (I think it stands for server side rendering?) should prevent your loading script and any further files it includes from being included in the server side build. I'm trying that with another library though, and it doesn't seem to be working for me. :-/

ndarilek commented 7 years ago

There's a difference between Vue plugins and Vuex plugins, which must be created along with the store.

Since I don't know that this is supported in Nuxt, I've instead just created the store myself like so:

import Vuex from "vuex"
import createPersistedState from "vuex-persistedstate"

import auth from "./auth"

export default () => new Vuex.Store({
   strict: process.env.NODE_ENV !== "production",
   plugins: process.browser ? [createPersistedState()] : [],
   modules: {
     auth
   }
})

Not sure if that works yet, but at least it doesn't error.

atinux commented 7 years ago

Please take a look at https://github.com/nuxt/nuxt.js/tree/dev/examples/vuex-persistedstate :)

krasevych commented 7 years ago

@Atinux but there are mode 'spa', as I know it spot ssr, only client side rendering, but I need SSR and vuex-persistedstate. Can I use both?

mtnptrsn commented 7 years ago

+1 I also use nuxt and vuex-persistedstate. I want to keep the the ssr setting and persist the state. Is that possible?

atinux commented 7 years ago

@krasevych @mtnptrsn

You cannot use vuex-persistedstate with SSR since it uses localStorage (not accessible on server-side) and this will create a mismatch between server-side & client-side.

Right now, the only possible solution is to use the cookies to store and use it on both client & server.

mtnptrsn commented 7 years ago

@Atinux All right. Thanks for the help!

krasevych commented 7 years ago

@mtnptrsn I made some trick for it, maybe you are interesting it:

function restoreState(store) {
  if (process.browser && store) {
    if (window.__NUXT__ && window.__NUXT__.state) {
      store.replaceState(window.__NUXT__.state);
      delete window.__NUXT__.state;
    }
  }
}

function createPersistedStateWrapper(store) {
  if (process.browser && store) {
    createPersistedState()(store);
  }
}

export default function() {
  return new Vuex.Store({
    strict: process.env.NODE_ENV !== 'production',
    modules: {
  ............
    },
    plugins: [restoreState, createPersistedStateWrapper],
  });
}
mtnptrsn commented 7 years ago

@krasevych That looks interesting! I'll def give that a try. Thank you very much!!

mnishihan commented 7 years ago

I've posted a solution for using vuex-persistedstate plugin without using spa mode in issue#972, that works nicely along with ssr mode.

lock[bot] commented 5 years ago

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.