Skip to content
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

1.0.0-alpha Breaking changes #754

Closed
John0x opened this issue May 22, 2017 · 44 comments
Closed

1.0.0-alpha Breaking changes #754

John0x opened this issue May 22, 2017 · 44 comments

Comments

@John0x
Copy link

John0x commented May 22, 2017

Hello, it seems like 1.0.0-alpha1 has been pushed to npm last night.
My Nuxt.js project is broken now. Can anyone tell, what the breaking changes are?

This question is available on Nuxt.js community (#c645)
@dohomi
Copy link

dohomi commented May 22, 2017

@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

@johnlindquist
Copy link

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?

@ghost
Copy link

ghost commented May 22, 2017

Sigh

@w550
Copy link

w550 commented May 23, 2017

Nuxt.js Error:

Error: [nuxt] state should be a function in store/index.js

+1

@Etheryte
Copy link

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.

@pi0
Copy link
Member

pi0 commented May 23, 2017

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:

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:

const createStore = () => new Vuex.store({
  // Store options
}
  • All of your stores (including sub modules) should return a function instead of object :
export state = () => {
  // initial state data
}

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.

  • See i18n example for reference.
  • Consider that if you don't take this step, it may lead to potential SECURITY BUGS as tokens are reused across requests
  • 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.

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
    })
})

@ndarilek
Copy link

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.

@co-kevin
Copy link

co-kevin commented May 24, 2017

@pi0 How to get store instance now? In the previous version is

import VueStore from '~store'

@ndarilek
Copy link

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.

@pi0
Copy link
Member

pi0 commented May 24, 2017

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.

@co-kevin
Copy link

Ok, i has been found it, i use store instance in plugins, example https://nuxtjs.org/examples/i18n/

Thanks.

@lewebsimple
Copy link
Contributor

If I understand correctly, the Nuxt constructor now returns a promise?
Isn't this a bad practice as explained here ?

@pi0 pi0 changed the title 1.0.0-alpha1 Breaking changes? 1.0.0-alpha Breaking changes May 31, 2017
@pi0
Copy link
Member

pi0 commented May 31, 2017

@lewebsimple Thanks for your tip. With alpha3 nuxt constructor will no longer return a promise (c5ca8c6)

@dohomi
Copy link

dohomi commented May 31, 2017

@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!

@pi0
Copy link
Member

pi0 commented May 31, 2017

@dohomi Sure. Will work on that soon ;)

@uptownhr
Copy link

@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?

@uptownhr
Copy link

uptownhr commented Jun 1, 2017

@pi0 is there a more expansive breaking changes document? window.onNuxtReady is also no longer available.

@pi0
Copy link
Member

pi0 commented Jun 1, 2017

@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.

@uptownhr
Copy link

uptownhr commented Jun 1, 2017

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.

@pi0
Copy link
Member

pi0 commented Jun 1, 2017

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)
}

@John0x
Copy link
Author

John0x commented Jun 7, 2017

@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?

@rpisarew
Copy link

rpisarew commented Jun 8, 2017

@pi0 How to get store instance now? In the previous version is
import VueStore from '~store'

Know any one a solution for that?

@pi0
Copy link
Member

pi0 commented Jun 8, 2017

@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 :)

@rpisarew
Copy link

rpisarew commented Jun 8, 2017

@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.

@tillkolter
Copy link

@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

@dohomi
Copy link

dohomi commented Jun 15, 2017

@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

@tillkolter
Copy link

tillkolter commented Jun 15, 2017

@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.

@bjunc
Copy link

bjunc commented Jun 18, 2017

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.

@pi0
Copy link
Member

pi0 commented Jun 18, 2017

@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 :)

euvl added a commit to euvl/example-todomvc that referenced this issue Jun 19, 2017
Fix of “Error: [nuxt] state should be a function in store/index.js” as
explained at nuxt/nuxt#754
@ghost
Copy link

ghost commented Jun 20, 2017

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)?

@bjunc
Copy link

bjunc commented Jun 20, 2017

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.

@ghost
Copy link

ghost commented Jun 20, 2017

  1. "It appears though that the alpha releases are being treated as the latest." - EXACTLY
  2. It is pretty natural to run "npm install" on given official examples and expect that they will work... :)

@lukasborawski
Copy link

lukasborawski commented Jun 20, 2017

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?

@dohomi
Copy link

dohomi commented Jun 27, 2017

@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!

@John0x
Copy link
Author

John0x commented Jul 5, 2017

@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?

@SzHeJason
Copy link

@pi0 How to customize axios ? I want to use an interceptor in the plugin

@Etheryte
Copy link

Etheryte commented Aug 8, 2017

Why was this issue closed? 1.0 is still in the release candidate phase.

@John0x
Copy link
Author

John0x commented Aug 8, 2017

@alexchopin this should not be closed, should it? The issues are still not resolved

@34r7h
Copy link

34r7h commented Jan 17, 2018

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)

@Etheryte
Copy link

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.

@atinux
Copy link
Member

atinux commented Jan 18, 2018

@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 (74652e3#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 ;)

@lock
Copy link

lock bot commented Nov 5, 2018

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.

@lock lock bot locked as resolved and limited conversation to collaborators Nov 5, 2018
@danielroe danielroe added the 2.x label Jan 18, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests