@John0x I think you were too fast in adopting. The website and changelog still does not exist. As far as I can see the most important change is removing injectAs
from plugin creation and being able to export a function inside of any plugin file. But better roll back and wait for an official release with changelog
I'm getting this too:
Nuxt.js Error:
Error: [nuxt] state should be a function in store/index.js
Assuming that's a breaking change and not a bug?
Sigh
Nuxt.js Error:
Error: [nuxt] state should be a function in store/index.js
+1
What's surprising to me is that the new package was pushed to NPM, but no release was made on Github. It's entirely possible this release was a mistake and was intended for internal use.
That being said, since it's marked as _alpha_, I wouldn't bother reporting any errors until there's an actual release here on the repository.
New release 1.0.0-alpha1
is semver incompatible with previous releases 0.x.x
so exiting users should be safe as long as they don't explicitly upgrade dependencies. (This is just why versioning exists right? :D) We have intentionally postponed release notes and docs to get feedback from alpha users and releasing a final and stable migration guide to avoid multiply breaking changes.
Although Nuxt has many internal improvements since this version, but migration should be easy for exiting users. Here is an unofficial and incomplete migration guide for those who willing experiment new release:
Most of breaking changes are because of new vue SSR performance improvements. Each render request is by default executing in the same process context as server while this gives huge improvements it needs additional steps in your project code. learn more
As of global context, just like data function for components which returns a function instead of data itself we need to make this change for stores as well.
See vuex-store-modules and vuex-store examples for reference.
If your root store is currently returning a Vuex instance, it should be changed to something like this:
const createStore = () => new Vuex.store({
// Store options
}
export state = () => {
// initial state data
}
If your plugins are changing global state, such as store and API tokens you should export a function which sets it for each request.
injectAs
is now deprecated and same behavior can be achieved in the exported function (see i18n). If you are using nuxt API, now you should await on nuxt constructor to ensure that are modules are initialized.
new Nuxt(options).then(nuxt => {
nuxt.build()
.then(() => {
// You can use nuxt.render(req, res) or nuxt.renderRoute(route, context)
})
.catch((e) => {
// An error happened during the build
})
})
How would the vue-apollo example be updated with the new injectAs
deprecation in mind? I just spent the last few hours trying to get that working on a fresh app, had no idea there were breaking changes and not all examples were updated.
Note that I've seen the i18n example, but the vue-apollo integration needs to inject apolloProvider into the Vue instance. I don't see which line in the i18n example does this and I[m not familiar with that plugin.
Thanks.
@pi0 How to get store instance now? In the previous version is
import VueStore from '~store'
I'd like to know this too. I figured out the answer to my own question--turns out app
is the root Vue instance so adding properties to that injects them--but now I need to access the store in my Apollo client to set authentication tokens. Can't see how to do that now that it's a function.
Thanks.
Store instance is available in vue components instance as this.$store
. It is also passed into plugins and middleware function context as store
. Not tried to locally test Apollo integration.
Ok, i has been found it, i use store instance in plugins, example https://nuxtjs.org/examples/i18n/
Thanks.
If I understand correctly, the Nuxt constructor now returns a promise?
Isn't this a bad practice as explained here ?
@lewebsimple Thanks for your tip. With alpha3
nuxt constructor will no longer return a promise (c5ca8c64f18d29b83137399b2aa5f6164f53b3c6)
@pi0 do you know how the changes on alpha3
can make vue-apollo
work correctly? It would be great if the example could get updated. Thanks!
@dohomi Sure. Will work on that soon ;)
@pi0 how do you import in plugins now? Ie I normally import axios through an instance i created as a plugin.
For example, import axios from '~plugins/axios'
Now that '~' is no longer available and the plugin file returns a function, are the plugins registered somewhere globally?
@pi0 is there a more expansive breaking changes document? window.onNuxtReady
is also no longer available.
@uptownhr For your first question, access plugins instance is a little more tricky, as SSR context is shared across request. You may use axios module for easier usage or looking into it's implementation to get idea how we could access context from inside components. (There is also another workaround using this.$ssrContext
but i haven experimented it yet)
window.onNuxtReady is also no longer available.
It should not happen!! If possible please prepare a glitch test to reproduce problem and opening an issue for that.
hi @pi0 modules is new to me and I need to look at it more. But it looks like it will not resolve the issue I am having. As I'd like to get access to the same axios instance from all parts of the app. Like store, plugins, middleware or even my own personal library.
Last night i wrote a quick workaround but let me know if I'm thinking about this incorrectly and if there is a better approach.
Here is my plugins/axios.js
import axios from 'axios'
let options = {}
if (process.SERVER_BUILD) {
options.baseURL = `http://localhost:3000/api`
} else {
options.baseURL = `/api`
}
const apiHandler = axios.create(options)
export default function ({store, router}) {
apiHandler.interceptors.response.use( response => {
return response
}, error => {
if ( error.response.status == 401) {
//alert('You have been logged out')
return store.dispatch('logout').then( res => {
router.push('/login')
})
}
throw error
})
console.log('onnuxtready', window.onNuxtReady)
return apiHandler
}
export { apiHandler as axios }
This exports the default function to retrieve the context and exports another axios. Now I can import import {axios} from ~plugins/axios
and get the same axios instance.
Consider axios instance is created in global context! So is being shared across requests in server side. This is a wrong and insecure approach. Actually your workaround is working, until we need adding some request specific options like tokens from cookies.
Take a look at axios/plugin.js#L87 :
export default ({app}) => {
// Create new axios instance
const axios = Axios.create({
baseURL: API_URL + (process.env.API_PREFIX || '/api')
})
// Setup instance interceptors
axios.interceptors.request.use(withCredentials);
axios.interceptors.response.use(undefined, handleError);
// Make accessible using {this,$nuxt}.$root.$options.$axios
app.$axios = axios
// setToken helper
axios.setToken = setToken.bind(axios)
}
@pi0 Why are only states supposed to return a function and not actions and mutations?
And how can I use axios inside a store now?
@pi0 How to get store instance now? In the previous version is
import VueStore from '~store'
Know any one a solution for that?
@LowM4N Do you want to access store outside of components/plugins/middleware ? Please explain more about use case.
@pi0 Is there a new general solution for this kind of thing?
I don't see how one would access the axios instance within a store for example.
@John0x Sorry for delay answering. Give us a little more time we are actively working on new changes and their documentation, Also will update axios and auth store modules soon for reference :)
@pi0 I want encapsulate my api logic in classes, but for that i need the jwt token from my store. I have the same problem with the router, I want use it in my store modules, but I dont know how to get him. A solution is to pass it to the action as parameter, but I found this to hacky.
@pi0 I also tried to migrate my project to version 1.0 but I failed so far. I am using apollo-client
instead of vue-apollo
, because the ssr documentation was not complete, when I started building my app.
Like others here did as well, I imported the client instance from the
My apollo.js plugin file looks like this:
let hostUrl = __API__
export default ({app}) => {
var networkInterface = createNetworkInterface({
uri: hostUrl + '/graphql',
transportBatching: true,
opts: {
credentials: 'same-origin'
}
})
let apolloClient = new ApolloClient({
networkInterface: networkInterface
})
networkInterface.use([{
applyMiddleware (req, next) {
// auth stuff
next()
}
}])
app.apolloClient = app.$apolloClient = apolloClient
...
}
From what I understood, the documentation implies that this plugin snippet should provide a global option to use this.$apolloClient
inside any of my components. Well, I can at least access it in asyncData ({app})
which is nice and everything is rendered as expected, but where I need it even more is on client-side reactively calling queries from inside the components and this is not working. Since I can not import it directly anymore, I have no idea what to do at that point.
Maybe I could put it into my store, but this seems like a dirty patch to me.
Or did I misunderstand something from the examples?
I have been using 1.0-alpha4
@tillkolter here is a small repo as a follow up on vuex apollo and vue-apollo: https://github.com/PierBover/vuex-apollo-example-project
Maybe it helps, I'm also thinking of moving away from vue-apollo and use the vuex approach
@dohomi I also use your suggested pattern in my app. I must admit not consistently, but I do use it in a lot of cases exactly like that. The problem with your posted solution is, that it wouldn't work with the suggested pattern for Nuxt 1.0 if you want to explicitly make apollo.js
a plugin. Maybe it should be treated as a plugin at all? I have a couple of types in my schema which are only resolved if the user is authenticated that why it is convenient to have its initialisation inside some instance connected hook to connect the authentication middleware. I used this pattern mostly because I wanted to use vue-cookie
(like this.$cookie
). Dont know if I should skip the plugin approach now and handle Apollo and cookies the Vanilla way, but I was hoping to find an "official" recommendation on that.
You guys are killing me. As a new nuxt user, I naively ran yarn add nuxt
(per the docs), which gave me the latest (alpha.4). The docs are written for 0.10.6
, and the examples are apparently current (leaving the user scratching their head as to the reason why). The release docs are lacking things like the removal of injectAs
and the store process is now different. If you're lucky, you'll find this issue thread, which provides _some_ insight as to what's going on.
At minimum, update the docs to tell the user to install 0.10.6
so you can roll out experimental prereleases without causing confusion. Not everyone has been following Nuxt from day-1, and reading through every commit to piece together the differences between the docs and the code.
@bjunc Apologies for any inconveniences. First docs are indicating are based on 0.10.7
and alpha
tagged releases started for more advanced users that can find out this changes quickly and getting feed back about final release. Next release would be probably Beta tagged and comes with docs with short delay. Anyway feel free asking questions, Our opensource community always tries it's best answer this questions in best manner as possible :)
Is it possible NOT to make alpha packages as default-latest packages?
I mean... why npm install gives me alpha version which is broken?
Shouldn't alpha version be optional (now we have working package as optional)?
I'm not an NPM expert, but I believe it is possible by using tags (not latest
). So for instance, if you wanted to install the alpha prerelease, you would run npm install nuxt@alpha
. It appears though that the alpha releases are being treated as the latest.
My request is more simple. Just explicitly put the version number in the installation guide that matches up with the version the documentation is for, and don't sprinkle prerelease examples in.
Currently, the doc pages say VERSION 0.10.6
. So in my opinion, there shouldn't be any examples of alpha releases in there, and the NPM install should explicitly target 0.10.6
.
By the way, I think Nuxt is great – I was just annoyed since I spent hours second guessing myself before I found this thread and realized the docs weren't for the version being pushed out via npm install
.
Me too:
plugins/axios.js
import store from '~store'
import router from '~router'
in interceptors got router/store on undefined
,
so, right now i can't use router.push
to call other view,
instead i have to use window.location.href
?
@pi0 @Atinux I would like to suggest that you guys keep release notes in a simple CHANGELOG.md. Its a very well known place and you could add the release notes for each of the alpha releases as well. You would get more early adopters and testers - like me :) - on board. Thanks!
@pi0 are there any news about accessing plugins from within stores?
Or is it not recommended to use axios within your store to fetch the data on demand?
@pi0 How to customize axios ? I want to use an interceptor in the plugin
Why was this issue closed? 1.0 is still in the release candidate phase.
@alexchopin this should not be closed, should it? The issues are still not resolved
Having this issue. Not into switching objects to return functions and back again and so forth. I think Nuxt could implement whatever strategy on the backend but let developers generally code the same way they're used to with Vue. Especially important for those of us maintaining more than one javescript platform (I'm using vue-nativescript, as well as browser support)
While I've successfully used Nuxt in multiple large projects, I completely agree with @irthos. The main issue with Nuxt is that it's very opinionated (about the way you define things, routing, etc.) without any good reason. One of the main reasons Vue is good is that it's not opinionated on these matters. I wish Nuxt would follow suit.
@irthos @Etheryte Nuxt.js is opinionated and we know that not everyone will like it, but we tried to enforce best practices to avoid any side-effects with server-side rendering (and yes there is a lot of side effects if you don't respect the best practices).
For example, about returning a function for the state in the store files, it's actually Evan who implemented it into Nuxt.js to avoid having the same state between 2 concurrent requests (https://github.com/nuxt/nuxt.js/commit/74652e3974b1092b00ac11f008005fd144afd2c1#diff-8fac4fd11fc23380db7318a93b0762bd).
Nuxt.js is a meta framework which force to use certains tools (Vuex, vue-meta, vue-router), so of course if you want to use other librairies you won't be able with Nuxt, but if you don't mind and look for a framework handling the complexity of code-splitting, asyncData, layouts, pages routing without any configuration, it will be perfect for you ;)
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.
Most helpful comment
New release
1.0.0-alpha1
is semver incompatible with previous releases0.x.x
so exiting users should be safe as long as they don't explicitly upgrade dependencies. (This is just why versioning exists right? :D) We have intentionally postponed release notes and docs to get feedback from alpha users and releasing a final and stable migration guide to avoid multiply breaking changes.Although Nuxt has many internal improvements since this version, but migration should be easy for exiting users. Here is an unofficial and incomplete migration guide for those who willing experiment new release:
runInNewContext
Most of breaking changes are because of new vue SSR performance improvements. Each render request is by default executing in the same process context as server while this gives huge improvements it needs additional steps in your project code. learn more
Store & Sub Modules state should return a function
As of global context, just like data function for components which returns a function instead of data itself we need to make this change for stores as well.
See vuex-store-modules and vuex-store examples for reference.
If your root store is currently returning a Vuex instance, it should be changed to something like this:
Plugins should export a function if want to mutate global state
If your plugins are changing global state, such as store and API tokens you should export a function which sets it for each request.
injectAs
is now deprecated and same behavior can be achieved in the exported function (see i18n).(for programmatically usage, with express or ..)
UPDATE: This will revert with next alpha release (alpha3) and change wont be needed any more
If you are using nuxt API, now you should await on nuxt constructor to ensure that are modules are initialized.