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

Development mode: Ability to log actions/mutations within Vue devtools #908

Closed
b44rd opened this issue Aug 15, 2017 · 23 comments
Closed

Development mode: Ability to log actions/mutations within Vue devtools #908

b44rd opened this issue Aug 15, 2017 · 23 comments

Comments

@b44rd
Copy link

b44rd commented Aug 15, 2017

What problem does this feature solve?

Referencing to vuejs/devtools#179

A pretty sweet development feature would be to add another tab inside Vue devtools that track the flow of actions and mutations. The suggestion is to allow a function such as devtools.log inside both store.dispatch and store.commit that holds the passed params. I´ve been using a custom library to do this for a while (b44rd/jsbug), and it sure provides another level of debuggability. The problem though, is that I currently need to add a line of code inside each action/mutation to achieve this overview.

For instance, when dispatching an action, this might look like this inside a new tab inside Vue devtools:

▶ Action: [actionName] [timestamp]

When clicked, this can be expanded, such as

▼ Action: [actionName] [timestamp]
  {
    points: 1
  }

The result list then visible in Vue devtools might then look like this. Note: Making actions print in a different color than mutations makes it really easy to follow the flow

▶ Action: "init" 10:00:002
▶ Mutation: "INIT" 10:00:004
▶ Action: "jump" 10:01:026
▶ Mutation: "JUMP" 10:01:031
▼ Action: "collectPoint" 10:02:005
  {
    points: 1
  }
▼ Mutation: "SET_STATUS" 10:02:015
  {
    points: 1,
    status: 'hero'
  }

What does the proposed API look like?

I believe it can be an alternative to extend Vue.config to enable/disable this feature. Since Store.prototype.commit is already logging to the mutation panel, I believe Store.prototype.dispatch can also be modified to do the same, so we will basically be able to call something similar to these two when dispatching actions or committing mutations

devtools.logAction('actionName', payload)
devtools.logMutation('mutationName', payload)
@posva
Copy link
Member

posva commented Aug 15, 2017

Isn't this achieved with https://vuex.vuejs.org/en/plugins.html#built-in-logger-plugin?

@b44rd
Copy link
Author

b44rd commented Aug 15, 2017

@posva Thanks! Will have a look at this one. I´ve not studied the code enough to realize what´s fully happening in order for vue-devtools to pick this up. But isn´t this plugin mainly focusing on mutations? The overall idea of this feature request is to achieve a log that also tracks actions, so the action -> mutation flow somehow becomes debuggable inside a theoretical devtools panel.

@posva
Copy link
Member

posva commented Aug 15, 2017

Actions are not logged because they don't affect the state, and mutations can happen asynchronously inside of actions

@b44rd
Copy link
Author

b44rd commented Aug 15, 2017

Yes, your point is a valid one for sure. However, if actions also becomes a part of the same log, a list like this can easily be produced.

27032288-79734094-4f74-11e7-8977-13efe6a4cc2d

In this particular app, the actions are displayed in a light green color, while the mutations are defined in a darker green color. As seen in top of the screenshot, it doesn´t matter too much if the actions are asyncronous. You´re still able to debug what data was comitted from the action.

You´re right about the time travel though. It will not be possible to enable time travel using this feature, but the overall debugging becomes a lot easier. Knowing what´s passed to an action, and what the action dispatches will for sure make it easier to discover potential bugs.

@posva
Copy link
Member

posva commented Aug 15, 2017

You´re still able to debug what data was comitted from the action.

So you want the possibility to associate mutations to the action they were emitted from? This would be possible with an action enhancer (a function returning the actual action)

BTW, nice log 😄, I'm sure I saw it somewhere else already

@b44rd
Copy link
Author

b44rd commented Aug 15, 2017

Thanks! Yes, that log (jsbug) is for sure a really nice addition to vue devtools. 👍

That´s basically why I hoped it could be an alternative to automatically log everything related to actions and mutations in the same way inside a panel of vue devtools. The alternative to define a function that returns store.dispatch is also a nice approach, but having it as a part of the devtools would for sure simplify things.

The main reason I think it´s a good idea, is that when a mutation do not mutate the state as expected, I often find myself spending time debugging both the function dispatching the action, and also the actual action itself.

If actions and mutations are listed as in the screenshot, a diff of the expected outcome from action to mutation is very easy to figure out.

Your argument saying that actions are not compatible with time travel is also a valid argument. Because of the async nature, this will make the current vuex tab less usable.

skjermbilde 2017-08-15 kl 12 43 45

If however adding an actions tab, actions can be inspected in the same way, and optionally along with mutations inside the same list, I believe this could be pretty sweet. Pardon for a very rapid sketch, btw. But I believe it illustrates the usefulness quite well.

skjermbilde 2017-08-15 kl 12 55 54

Let me know your thoughts, and I´ll be happy to help with the implementation.

@posva
Copy link
Member

posva commented Aug 15, 2017

To me, the whole point of Vuex in devtools is inspecting how the state changes, so having actions there doesn't bring anything. It could, however, be an extra information when selecting the mutation (appearing on the right)

Pardon for a very rapid sketch, btw. But I believe it illustrates the usefulness quite well.

Taking the time for sketching is already nice, imo 🙂

@b44rd
Copy link
Author

b44rd commented Aug 15, 2017

Hey! That's perhaps the absolutely optimal solution indeed. 😀

The important thing is to somehow be able to inspect the params of the action, and compare those with the params of the mutation, and then be able to see the result of the chain.

I believe this will provide valuable information for a lot of developers, and at the same time save a lot of debugging time. 👌

Are the action name and params already available for the logger? Because then it can simply be provided as a mutation callee list item, that can be displayed directly after the mutation item?

@posva
Copy link
Member

posva commented Aug 15, 2017

No, it doesn't exist yet, but you can create an action enhancer. The concept may not be clear yet as we haven't documented it but you can look it up at vuexfire

Having an action driven view in devtools can be useful but it should be another view different from mutations' one

@b44rd
Copy link
Author

b44rd commented Aug 15, 2017

Agreed. Will have a look and try to understand action enhancers then! 👍

But then, how do you think the actions will be displayed in an optimal way? Adding it as a list item to the right column, under state - getters - mutation? As for example "action"..?

Then, the action can be shown approximately as within the sketch. Though, perhaps only with the labels "name" and "arguments/payload". This way, the payload of the mutation can be diffed/compared very fast and efficient against the arguments/payload of the action. What do you think?

@deini
Copy link
Contributor

deini commented Aug 29, 2017

@b44rd Do you have any update on this? I'm really interested in this feature, let me know if I can help!

@b44rd
Copy link
Author

b44rd commented Aug 29, 2017

Hi, @deini, haven't yet been able to investigate this further, but it's for sure on my todo-list. I believe making the gui inside vue-devtools will be a quite simple task though, so the first action point will be to be utilize the action enhancers, in order to pass the name and params of the action to some logging function.

From this stage, I really like the idea of adding another field to the right side Vuex pane. I believe a field named action, containing the callee action name, action timestamp and action params will do the job quite well. It will at least make it possible to debug which action caused the mutation, and if the parameters passed along to the action corresponds to the ones passed to the mutation. Plus you will no longer need to debug/log actions elsewhere.

If you'll be able to start before I do, please let me know which branch you're working on, and we can continue together.

@deini
Copy link
Contributor

deini commented Aug 30, 2017

Thanks for the info @b44rd would love to work together on this.

I was looking at action enhancers and if I understand the concept correctly this will require the users to use a custom action, like import { firebaseAction } from 'vuexfire' and then use that to compose actions. Is that correct @posva?

Is that the only option we have? Not sure if that would be ideal since now the user will need to use this custom enhancer just to get the logs.

@posva
Copy link
Member

posva commented Aug 30, 2017

Yeah, that would be the way and no, it's far from ideal 😅
This is something that few people find useful and is a dev only feature, so IMO having it as part of Vuex is not reasonable unless it gets completely stripped off in production builds

@b44rd
Copy link
Author

b44rd commented Aug 31, 2017

@posva Would it be an accepted alternative to add a log function inside the dispatch method if process.env.NODE_ENV !== 'production' then? It for sure seem like the easiest way to achieve this feature.

Agreed that few people need this initially, but as mentioned above, this is a very good way to verify that the params passed to the action corresponds with the expected params of the mutation.

@posva
Copy link
Member

posva commented Aug 31, 2017

A simple log wouldn't be enough to track which action does a mutation belongs to. You need to wrap the commit function to track mutations

@b44rd
Copy link
Author

b44rd commented Sep 1, 2017

@posva I see your point. I´ve studied the code a bit more, and see that plugins/devtool makes vue-devtools able to track mutations simply by adding a store subscriber that listens for mutations:

store.subscribe((mutation, state) => {
  devtoolHook.emit('vuex:mutation', mutation, state)
})

I´m not sure I fully understand the code enough at this stage to be able to wrap the commit function without making a mess though. Any ideas?

@b44rd
Copy link
Author

b44rd commented Oct 13, 2017

Closing this issue, as it was merged in #960. Great stuff, @deini! 👍

@b44rd b44rd closed this as completed Oct 13, 2017
@b44rd
Copy link
Author

b44rd commented Oct 14, 2017

I see we need to add the following code

store.subscribeAction(({ type, payload }, state) => {
   devtoolHook.emit('vuex:action', payload, state)
})

inside

src/plugins/devtool.js

in order for vue-devtools to be able to pick the action beeing fired. Will add this as a pull request from dev...b44rd:add-action-subscription once having something usable to create a pull request from within vue-devtools repo. 👍

@deini
Copy link
Contributor

deini commented Oct 14, 2017

That's already part of #987 we can start working on the devtools

@b44rd
Copy link
Author

b44rd commented Oct 14, 2017

Ah! My bad. Great stuff!

@freeqaz
Copy link

freeqaz commented Jun 7, 2019

Is there still interested in adding this feature? Would be quite nice to have for debugging! Mutations are awesome. Seeing the actions too would also be awesome. Thank you!

@benwinding
Copy link

Hey guys, I was annoyed by this, so I made a package to trace actions and mutations it's called vuex-trace:

screenshot

import { mutationLogger, actionLogger } from 'vuex-trace'

const store = new Vuex.Store({
  state,
  mutations,
  plugins: [mutationLogger(), actionLogger()]
})

Have a go and let me know, it's based on vuex's built-in-logger-plugin

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