Noel: Hello, and welcome to PodRocket. My name is Noel. I am an engineer at LogRocket, and today we're joined by Natalia Tepluhina, who is a Vue.js core team member and a staff engineer at GitLab. How's it going, Natalia? Natalia Tepluhina: So far so good. How are you? Noel: I'm good. I'm good. Well, yeah, thank you for joining us today. We got a whole bunch we can talk about and cover here. I guess, yeah, to get us rolling, though, can you tell us a little bit about yourself? Where you came from and what you've been working on recently? Natalia Tepluhina: As already mentioned, I'm Vue.js core team member and I work a lot on Vue.js documentation. So if you've been reading Vue docs, especially Vue 3 docs, there is a high chance that you've been reading something I wrote, and I'm not sorry for that. Natalia Tepluhina: And as for work, because Vue.js is not my main occupation, that's my open source activity. And for work, as you mentioned, I'm a staff frontend engineer at GitLab and I use Vue.js in my everyday work. So I work on the framework and work with the framework. And this is a really nice combination that works both ways. Noel: Yeah. Nice. I think it's a gift to be working on a team where you're able to use the open-source tool that you like to work on in your free time and your extra time that you have. Do you think that that is a requirement to get into a core team membership position? Do you have to be using the tool that you're working on every day to really get that comfortable with it? Or do you think that you... Isn't required, but is a nice to have? Natalia Tepluhina: It's a great question. I don't think it's required. I know that many team members of Vue.js don't work with the framework every day, especially those of us who have full-time job on the framework itself. It leaves really little time to work on something that uses the framework. Sometimes they do consulting, so they still work with the framework, but not the full time. But I think it's nice to have someone in the team who works with it because it brings you this feedback loop. That's something that you can report box, test new versions of the framework on the real life, big project. Work with ecosystem, with testing, with everything, and report back to the framework. And it works nice for the product you're working on because you know everything about the newest features coming. You have some insights you can use in the company because, well, even if they're insights and you're not sharing them, you still have something to like, "Okay, I know what to improve in my product in the light of common features." Noel: Right. Natalia Tepluhina: So yeah. I consider myself being privileged in this position. Noel: Yeah. Yeah. That's super cool, yeah. I's always awesome to hear about those. I guess I'm curious. Do you think that the problems that you guys are facing at GitLab, when you're working on stuff, does that ever influence where your time is spent when working on Vue, on the project? Natalia Tepluhina: Not on Vue core, but I can tell that it influences a lot on our contributions to Vue ecosystem because I'm not the only GitLabber who contributes to Vue ecosystem. I'm the only one that is core team member, but we have people working on Vue test details, on BootstrapVue, and many libraries in the ecosystem. And these contributions are highly influenced but what we need at GitLab. Noel: Right. Yeah. I mean, that makes sense. Again, I don't think it's a fault or anything. I was kind of curious how that all ends up playing together. Are you guys on Vue 3 at GitLab or how does that play? Natalia Tepluhina: I wish. I wish we were on Vue 3 because migration is cool, especially migration of the core with combat build, but ecosystem is not there. And we all know that ecosystem is not there. We know that there are many versions for libraries for Vue 3, but there are a few core, big... not core, but big ecosystem libraries that didn't migrate. And information on one of them is next, that was in release candidate for a long time. Really lacking behind of the core. Natalia Tepluhina: Vuetify is one of the component libraries also. And unfortunately for GitLab, it's also BootstrapVue because our component library is wrappers around BootstrapVue components. I know how it sounds. I know, don't make this face. Making the component library, wrapping another component library. Yeah. It was a temporary solution. And as every single temporary solution, it stays forever. And then it bites you back. And it happened with BootstrapVue. BootstrapVue never migrated to Vue 3. And I don't think maintainers even plan to do this. So we have two different paths. Migrate BootstrapVue ourselves, or rewrite our component library not to use BootstrapVue anymore, both extremely painful. We are looking at the first one, we're contributing to BootstrapVue. We have a few people who work on BootstrapVue components right now, but this kind of stops us from moving to Vue 3. I'm really not happy about it. Noel: Yeah, no, I feel like it's a pretty common pattern people fall into, is like, "Oh, we'll use a component library. And then we'll wrap a bunch of components. We'll have higher order components that are around it." I'm in a similar position myself. I have a bunch of side projects or even when I'm spinning up new stuff, I like to use Vue a lot, but I'm a big Vuetify user. And until we get stable Vue 3 Vuetify, I'm just like, I don't know if it's worth it yet for me. So much of the appeal of Vue for me is those component libraries being there and usable. Noel: So that leads me to an interesting question, then. Is Vue, I guess, in terms of adoption of Vue, do you feel like this split that we have right now, where there's a very robust ecosystem for 2, and 3, which is definitely more composable, more user friendly, it's a better experience, but the ecosystem isn't there yet. Do you think that that is steering people away from Vue at all? Natalia Tepluhina: I don't think it's steering, but you mentioned the split and I agree with that. The problem is if you start a brand new project right now, Vue 3 ecosystem is ready for you. There are enough component libraries. Yeah, so Vuetify is not there. There is Element Ui, though. And there is Oruga, there are other component libraries that you can adopt. But there is bunch of other libraries in the ecosystem and you can just start and be happy with your project. But if you have an existing one in Vue 2, migration is a different question. And I think it's so problematic to do a proper migration of at least mid-size project. Noel: Yeah. I agree. So, yeah. If you don't think that that is much of a barrier, what do you think are the big challenges for Vue adoption out in the wild? Natalia Tepluhina: Well, I don't think there are big challenges for Vue adoption, especially for new users. I would say that for people who use React, it's even easier now. Even some composables and hooks are very different things on the inside. The API is quite similar if you look at them. And for young people, it makes easier to start with Vue. So they don't have this nice options, API style that we used to. Yeah, I can just try hooks that are not hooks, but I'm fine. So there is nothing that prevents adoption, but I still believe that for people who are working on existing projects, the situation is unfair. Noel: Yeah. Gotcha. I am curious too... Again, I'm not nearly as tuned into the Vue ecosystem as you are. Again, I like to use it for site products when I can, but I did see that 2.7 was released recently. So how does that play against features in Vue 3? I guess, what does 2.7 bring to V2? What are the things that are addressed there? Natalia Tepluhina: So the biggest point of Vue 2.7 was to bring composition API to the core. Previously, you still could use composition API with Vue 2, but you would need an external plugin. It could be Vue Composition API, or Vue Demi or something like that. It would still be a third party library. And not everyone is happy about bringing new features with third party libraries, because just like BootstrapVue, you never know when it stops being supported. Now it's in the core and people feel safe about using Composition API for extracting logic. So they have new deal to extract logic. Natalia Tepluhina: It also brings Script Setup on top of that. So if you don't like your all good script and writing it up with Composition API with all the returns, you can use Script Setup. Again, this a bit... For me personally, it's a bit of a controversial part. I don't like Script Setup. I feel like coming out right now, but I prefer using script with setup and explicitly return everything. And it also brings a very nice thing, which is be bind with CSS, which means that you can use, right now, the reactive properties in your CSS, in the style scoped... Or not scope, just in the style part of your single file component. Natalia Tepluhina: But there is always "but", the reactivity system did not change. It doesn't mean that you start using proxies for your activity. We still have our old good object defined property, which means all the reactivity came but stay in the place. So you would still need to use Vue.set if you want to add something to your array with just an index of the element. So this is not fixed. Noel: Gotcha. Gotcha. So with that in mind, then, would you ever recommend new users starting new projects start on 2.7? Or would you basically say, "Always go to 3 if you can." Natalia Tepluhina: I would say if you start a new project, go to 3, because starting with Vue 2.7, you might risk to stay on Vue 2.7 for a long time. If it's a brand new project, probably your migration won't be as problematic as for old legacy ones, but I don't see why you should stay on Vue 2.7 while core is pretty stable right now, ecosystem is quite good. You might have issues if you want to use very specific library. Like I want to use Vuetify, no. You just cannot start with Vue 3. Oh, you can if you're fine with beta. Noel: Yeah. They have the beta version, right? Yeah. Yeah. Natalia Tepluhina: I mean, there should have been a release candidate somewhere around this time. But from what I remember, John Leider, who is leading Vuetify, just had his third baby. So it's blocking the release. They should be still soon. But anyway, if it's just a project you want to start and you're not bound to some specific libraries, go with Vue 3. If you're on the old project, try to upgrade to Vue 2.7. Noel: Nice. Do you think that if you're on an old project, that 2.7 upgrade will eventually ease the migration to Vue 3? Was that what a lot of the motivation for the feature set added in 2.7 was? Natalia Tepluhina: Thank you for this question. No, it was amazing because this was basically asked to me, I think, 10 times from people on Slack just after we announced Vue 2.7. It depends. How was this joke? If you're a real programmer wear a conference T-shirt and respond with, "It depends," to any question. It depends, but let me explain why. It will make your migration easier if you want to start extracting logic to Composition API right away and you want to use some libraries that only supports Composition API in the future. Because there are, let's say, good libraries and bad libraries, which is not fair, but there are libraries that support both options in Composition API. And there are those who only expose Composition API. And if you plan in the future to move to this, yes, it will make your life easier. Same applies to Script Setup, if you prefer to use it. But there is but. I think main blocker is not Composition API, neither Script Setup. The main blocker is still ecosystem dependencies, libraries. Unfortunately, Vue 2.7 doesn't make any change for those. Noel: Right. Right. So I guess, you probably think about this problem a lot then, right? These dependencies and stuff. Is there a light at the end of the tunnel? Do you think that there's any way to ease that pain for devs in general or what does that future look like? Natalia Tepluhina: Well, we had this discussion within the core team too. There was even a question that maybe we should help some major libraries with migrating to Vue 3. Basically, ecosystem defining libraries. Vuetify Nuxt, whatever. And maybe we will, but we definitely cannot, as a core team, just take the maintenance of BootstrapVue, let's say. So this will help. But I think it just depends on the people who use the libraries. Normally, when these things happen, there will be a new maintainer for the library. There will be just people who pick it up and move it forward. Just like every single time in the open source world. And I believe this is the light in the end of the tunnel. Just someone who takes initiative and makes the change. Noel: Yeah. I agree. The changes will proliferate eventually in one form or another. Or the dependence will start using something different or things will just eventually break down. There is a train coming. It's just like, how does that end up happening, I think, is the question. Yeah. But very cool. Thank you for letting us pry into that a little bit there. I know that was close to your work and figuring out how that migration process is all going to look. Emily: Hey, this is Emily, one of the producers for PodRocket. I'm so glad you're enjoying this episode. You probably hear this from lots of other podcasts, but we really do appreciate our listeners. Without you, there would be no podcast. And because of that, it would really help if you could follow us on Apple Podcasts so we can continue to bring you conversations with great devs, like Evan You and Rich Harris. In return, we'll send you some awesome PodRocket stickers. So check out the show notes on this episode and follow the link to claim your stickers as a small thanks for following us on Apple Podcasts. All right. Back to the show. Noel: Yeah. So you've given a bunch of talks recently. You've been a speaker for a while and you've covered a whole bunch of topics. It sounds recently you've been working on one or giving one concerning Vue Query and how that's useful. Can you give us a little bit of background there on maybe what Vue Query is and what the talk covers? Natalia Tepluhina: Yeah, totally. So Vue Query essentially is a wrapper around, surprise, React Query. And in React ecosystem React Query has been around for a while. Way more famous than Vue Query is in Vue ecosystem. Think it was lots of hype around it and what it is, if you never heard about it, because it's still fine not hear about some new stuff in the ecosystem. React Query is the tool that helps you working with your server cache. What is server cache? If we look at our local state managers, Vue 3 docs, Vuex, whatever. Xstate, if you're fancy. In the real life application, around 80 to 100% of data you store there is just something you fetch from the API because it's real life application, right? In reality, you're storing data on server and you just synchronize your client application with a server. Natalia Tepluhina: There is a chunk of local data, just client one that probably will disappear or maybe stored in the local storage. You want to add the command on GitHub or GitLab. And if you refresh your page, command is still there. If it's on the server it's normally stored in the local storage, but this is just a little part. Most of the part is something you fetch from the API. And how do you do this? You create a login flag. You create a custom error handling. You create a query application sometimes, as you need to. You update this cache every single time you send the request of the server, be it post [inaudible]. Some of you are lucky, just like me, and use Apollo Client that does everything for you just automatically, which is amazing. But you would need GraphQL. Not everyone has GraphQL. Natalia Tepluhina: What if you use REST API? And what if you don't want to care about this server part and store it in your storage? That was what React Query does for you. It basically creates a cache where it stores every single response of the request you send to the API. You can update it manually. You can modify it. You can have a bunch of settings. You can say, "Okay, we store data for five minutes, and after this, we consider the data stale." And every single move of the user will just refresh the data. You can refresh a window focus, make tries. It's just amazing library that solves so many issues, probably creating new ones in the process, like it always happens. But it still solves. Natalia Tepluhina: And for Vue, it was like terra incognita. There was nonexistent until in the beginning of this year, a nice guy whose name is Damian Osipiuk created a wrapper because React Query exposed the core, not just React library. And it was possible to create just wrappers for different frameworks. So now we have it in Vue. And this talk was basically demoing the local state that we have. We populate it with data. We try to update it with some extensions and I'm just showing how they're slowly turning into a hot mess and how Vue Query can solve the problem. Noel: Nice. Nice. Very cool. Why do you think it took so long for something like Vue Query to come along? Do you think a lot of devs were using, like you said, Apollo Client was solving that problem for them, or people just didn't think about it that much? Why do you think it took so long? Natalia Tepluhina: So I think it took so long because... It's funny because React Query already existed, but there was no core exposed. It was just a React library. And maybe for Vue... So we have less boiler plate in Vuex. Definitely. I can compare Vuex and Redux boiler plates for synchronous operations. Both are good size boiler plates, but Redux is two times bigger. So probably it wasn't an issue. And Vue has, in my opinion, a little better reactivity because we have mutability. Right now, all the people who have fancy mutability will disagree with me and probably stop listening. But for average person, it's easier to mutate the state than cross the idea of immutability. And for us, just changing data in the state, instead of writing resolvers, not reducers. The resolve is Apollo Client influencing me right now. It's just a bit easier to understand. Natalia Tepluhina: So first, okay, we just changed the state and it's fine for us. So maybe it led to less adoption in this terms. Right now, I think, maybe partly due to my talks, Vue Query becomes a really hot topic in Vue as well. And I know people start using it in production after that, and they're still happy. Normally, if you start using something after the conference it's like, "Okay, I'm completely disappointed after two months." No, they're still using it and they're still happy. And I would just like to see people experimenting more about state management, because I think I'm the one who complains about state management for at least three years. Fun fact, in 2020, I had a talk that literally had a name, You Might Not Need Vuex. And I didn't even realize how right I was. Two years after we don't need Vuex. Noel: Yeah. Gotcha. And I guess now, has that been realized because you can use this query caching layer to really do everything that one would've been leaning on Vuex to do before? Natalia Tepluhina: Yep. Yep. Totally. In my work, I use Apollo Client because I'm quite lucky we are migrating from REST to GraphQL. So we're still using both and wrapping REST responses in Apollo resolvers. But if we were staying on REST and not planning to move to GraphQL, I would definitely just adopt Vue Query tomorrow and start using it because our old state managers, our old states and Vues that didn't have this and used Trust API, I just can't look at them. And it's so easy to get lost. They have so many bugs because it's the duplication failing or some just data is not synchronizing properly. It's crazy. Noel: Yeah. Maintaining a state like that is a really hard problem, right? I guess, the caching problem in general, I feel like it is a manifestation of that and it is hard to do very well. So yeah, whenever we can lean on tools to do that hard work for us it's a bonus. Yeah. So we've talked about the Apollo Client a lot. I guess one final question on that note, if you are, again, doing everything from scratch yourself and you have the benefit of having everything in a GraphQL, is there any reason to use Vue Query over the Apollo clients? Or are they about at parody there? Natalia Tepluhina: No. And I can even tell why. Because Apollo Client will allow you to benefit from strong type responses in GraphQL. And most of the automatic updates that Apollo is capable of doing, Vue Query won't do by default. Because Apollo operates with GraphQL type name and ID, and using these two values, it can find the entity in the cache and update it automatically. While with Vue Query, in some cases you would need to write a manual update to the cache. Sometimes it's the case for Apollo too. If you add a completely new entity to the root level, you would need to update the cache too. But unfortunately Vue Query is not designed at least yet for GraphQL's strongly type responses. And it doesn't benefit from this type system. Noel: Gotcha. Is there any downside to using both? Say you have GraphQL... Some GraphQL APIs, some REST APIs are interacting with, would you recommend people use both? Is there any negative things? Natalia Tepluhina: No. I would say if you have both, you would still go with one. Probably Apollo because Apollo still can work with REST in a bad... Not in a bad way, but you would need to write local side resolvers. So when you're querying something from REST, have resolver that converts it to GraphQL shape and puts it to Apollo cache. And for Vue Query, you still don't have this benefit of working with GraphQL, which is a huge part of Apollo goodness. I'm probably praising Apollo too much. So if you're thinking about using Apollo, you need to know that it's a library that has a lot of hidden magic. Vue itself has a lot of hidden magic, but Apollo is like a king of hidden magic. And sometimes you will find yourself just trying to figure out why cache is not updating or why this is not working. Natalia Tepluhina: Oh, we missed that statement and error messages are very cryptic. Just look at the console and say something like, "This is undefined." And I have no idea what you want to tell me. And the error is deep in Apollo Client itself. So you just go and try to figure out what is going on. So don't get me wrong. Apollo is by no means an ideal library. It's very cool. It does a lot of work for you, but the price is dealing with the magic. Noel: Right. Yeah. It's like most of those super high power libraries. It's like, "Oh, it's great. Everything works good." Then you hit one bug and you're like, "Okay, this is going to take two hours." There's always you hit that. It's like, "I've saved 10 hours at this point, but fixing this bug that, if I had written it myself, it would be easy. It'll take me more time now." But again, I feel like we have a tendency as devs to get really frustrated with libraries when they do that. And it's easy to forget how much work they are saving you and how many other bugs you're not falling into along the way. Awesome. Natalia Tepluhina: Yeah, absolutely. Noel: Yeah. Well, thank you for all that insight there. Are there any other talks you've been giving recently or any topics you've been covering that you think I know would be particularly noteworthy or worth chatting about a bit? Natalia Tepluhina: Unit testing. I gave a talk about improving unit tests and I really loved it because it was a talk full of pain that basically consisted of everything I complain and merge requests at my work on tests. Because you just review, okay, this test doesn't test anything or you're testing the wrong thing, or, okay, we should improve this test in writing it in this way. And I just collected this pain points and brought them as a topic because if I want people to write good tests, I can share it with the community and maybe improve it globally instead of only my team. And I think from what I remember about the reactions of those who viewed this talk, it was mostly given during the online conferences when lockdown was still active. It was autumn and winter of the last year. And people were happy about it. Sometimes agreeing, sometimes disagreeing, but they were asking for slides to share slides with their team. And I consider it being at highest reward. If they want slide to share with the team, I probably did some good job. Noel: Yeah, absolutely. If people want to share, that's always a good sign. What are some of the common pitfalls? You talked about in pull requests, you have people coming in there. There's common things that people are doing where you're correcting, like this isn't actually testing anything or it's testing the wrong things. What are the pitfalls or what are the patterns to watch out for that you think devs are most often landing in? Natalia Tepluhina: First and the most important thing, it's testing component in internals, instead of testing the component external behavior. In Vue test details, if you find yourself checking something that is wrapper.vm.something, if you want to see if wrapper.vm.user is equal to John, you're doing it wrong. Because you are testing what component data is or maybe component computed property. Maybe component prop. What you should have been testing is that div with class user has a text John. How to see if you're doing it right? Try changing names for computers and methods and see if your test fails. If you change the name of the methods and your test fails, you are doing it wrong because now, your test is aware about component internal. But that shouldn't be... Your test shouldn't know what is the name of the method. Your test is basically clicking the bottom and seeing what's happening. Components in some event called. If that shouldn't be doing wrapper.vm.onclick handler. Natalia Tepluhina: And people do it so much, you wouldn't believe. It's like, ever since second test I've been reviewing it. Yeah. It's wrapper.vm.sendform. No, no. Click the button, call the submit event. So this was one of the biggest thing I've seen. And there was another one. A bit more controversial about Mount via shallowMount. I think it's a huge holy war in general in front-end world. Because there are people who're following [inaudible 00:28:07] idea and mounting the tree, which is cool because you're testing everything mounted. Super cool. But if you have a big size project and you don't have a perfect component architecture, you never have perfect component architecture if you work on seven years legacy. Sometimes you find yourself in a component tree that consists of 20 components and you're following the idea of everything should be mounted. You mount it. And the tests are good. And you're using component library somewhere in the end of the tree. Natalia Tepluhina: And then, component library decides to change some attribute on their button. 99% of your tests are red because apparently you're mounting the tree and now your tree is not matching the snapshot because you apparently use snapshots for 20 components deep nest, the tree. Use Mount to shallowMount wisely. If it's maybe two level nesting, okay, Mount is fine. If it's some complicated table that has multiple slots, maybe Mount is fine. Don't mount on the root level. Use shallowMount and learn what are component contracts, which is basically props and limited events. If you deal with a child component, it's enough to make sure that props are correct and component emits an event. So this was a big discussion on the talk as well. But mostly, it's like don't test component internals, please. Noel: Right. Why do you think that problem is so acute in front-end testing in general? We don't really when we're doing unit testing on the back-end. One could do that, but I feel like the tendency to do it is not there to the degree that it is with the front-end. Why do you think that that is? Natalia Tepluhina: Two reasons. Because from what I can see, not every single front of engineer writes test and people just tend to skip unit testing for front-end at all, thinking that end to end test will cover it. No. End to end test will cover some things, right, but if you want to find a granular issue with your project, you need tests still there. And I've seen so many projects where people don't try to unit test for their front-end. Not a single one. That there is no surprise that when they start doing this, they fall into some wrong assumptions. Natalia Tepluhina: Second one is Vue test details documentation. At least in the past. Right now, it's improved a lot. Actually used these patterns, mention them in a few places and people were just blindly following or it had some things like creating local Vue instance and using it in every test without any reason. And people don't read. People copy paste, here, code snippets. If you write documentation, that's a very common rule. That code snippets should be functional because people will stop reading and just copy paste the code that you have because reading is boring. Let's just bring it Stack Overflow style. And it also affected a lot of the unit tests. Natalia Tepluhina: And also, we didn't have clear guidelines besides Vue test studio, I think, anywhere. So people were just inventing the wheel and going with a easy path because it's easier. It's just easier to write wrapper.vm.something is equal to one, than test a rendered template. What people forget in this case is even if your wrapper.vm property, so data computed props, are absolutely correct, you as a developer can forget to put them in the template. Maybe user is really John, but you forgot to just put John's name in the proper div and on your screen component is failing, but your test is green. Noel: Right. Right. Do you think that there's improvements that could be made to the tooling, to the testing framework, to help prevent these kinds of problems? Is it even good to have linter checks that are checking for certain strings where you are observing something you shouldn't be here? Or are there other tools you'd recommend? Natalia Tepluhina: I think this is a great idea. We implemented this linter on the project level, but if we could bake it in back to Vue test details, it would be amazing. Just preventing some things like rapid.vm from checks. Yeah. That's totally great idea. Noel: Yeah. Cool. Cool. Well, yeah, keep that one to the back of your mind. Maybe that stuff will be coming out soon and this will be less of a painful problem at some point in the future. Awesome. So I think we have one other note here about a talk you were giving about large-scale refactoring. Was that a pretty recent talk or was that some time ago? Natalia Tepluhina: That was a recent talk. It was in June. JSHeroes Conference. I think it was the only one I gave it. And again, it was talk full of pain. It was funny because it was a talk about the migration from version two to version three, but not for you. Noel: Oh, gotcha. Natalia Tepluhina: And if you think like, "Yeah, migration, it shouldn't be a refactoring. It's easier. Right? You just data library, it just do NPM, install latest and everything is cool," and no, it was a migration from Apollo Client 2 to Apollo Client 3. And it took us 11 months with significant rewrites to our queries, to the way that we handle our tests, to some things that never should have been working, but they did in Apollo 2. Apollo 3 is more strict. And it's the moment when you update the library and you start thinking, "How did this even work? It shouldn't be working." So yeah, it was a large scale work that involved all the front-end team, lots of doing code-modes. So I even made a little impromptu live demo on code-modes and AST 3 modifier. So basically I was just showing the analyzer of AST of JavaScript and how to quickly change things for Apollo Client on some things. How we use linters because linters is one of the best tool that you can use during the large-scale refactoring. Natalia Tepluhina: Because you can just forbid people to do some things on their real life one and some hacks too, because sometimes you need to stop your team of doing some things, but you cannot lint against it. So quick example, what do I mean in this particular case? So in Apollo 3 and Apollo 2, we had a different mechanism of resolving that response in our tests. It still uses the mock Apollo client in tests. But with Apollo 2, we were, me myself including, dumb developers. We have an Apollo Query and we used Vue nextTick to resolve it. For those of you who don't use Vue, nextTick is just a tick that's required for the component to render on the screen. So you click something in a test, you wait for the nextTick, and you have model, for example. Natalia Tepluhina: And normally, you shouldn't use nextTick to wait until the query is resolved. It should have something that is called flushPromises or wait for Promises and is basically waiting for Promise results. But nextTick did work and it's easy. So we use nextTick. So you mount the component, you wait for the nextTick, you have your query result. Amazing. We migrate to Apollo Client 3. Nope. It's not working. It's not enough. And so what do we do? I cannot just move all the code base to Apollo Client 3 and write all the tests. I need something to affect my existing test so people stop adding nextTick. Can I lint against it? No. nextTick is viable. We use it to render components after we modify something. Props is modified and we want to check that now, for example, model is rendering. I cannot lint against it. Natalia Tepluhina: So how do I move people? And you make hacks, what do we do? We add a little helper to our mock Apollo client that traps the handlers or queries in the Promise. In the Promise. And we modify all the tests, replacing nextTick with flushPromises. Cool. Now when someone on the existing code base with Apollo Client 2 tries to use nextTick, the test fails and nothing motivates people to fix things more than failing tests. Because people, "Oh, why's failing?" And we have a guideline that explain, "Okay, we don't use nextTick anymore." And when they come to the front and check, "Why my test this failing now?" "Oh, we have this in the guidelines. Please check." Basically, in two weeks everyone was writing flushPromises and migration was easier. And this little things is something that you'll learn during a large-scale refactoring, because sometimes you will need to use hex. That's the only way. Noel: Yeah. Yeah. I'm thinking back to cases where... Yeah, we've done something similar where we've gone in and mocked something or stubbed it or in some manner gone in and put in a catch. So will change everything that's using the old way. If anyone tries to use the old way now, even if it would be working in other cases, if it would break in this instance, the thing we're testing against break it. I feel like it is hard. It's hard to abstract that concept, that way of doing things, though, because it is so situational. Those always come up in slightly different permutations. But yeah, I think that pattern is one that we don't think about in motivating and helping inform our teams. Even more than motivating is people just don't know a lot of the time. Right? Like you said, copying and pasting and this is the way it was done. So anyway. Yeah, I think that is a topic that probably needs more discussion than typically happens. Noel: Another thing you spoke to is the going in and trying to fix something when you're updating and you're realizing how broken it is. I can't count the number of times. All the time. It's like, how is this even working? There's so many bugs in this. Those are always the worst kind of rabbit holes to go down. Awesome. Cool. So again, we've covered so much. Is there anything in particular in the future of Vue that you're excited about or looking forward to? Natalia Tepluhina: In my work, I'm definitely excited about one day migrating to Vue 3, even though the work would be probably twice as hard as migrate to Apollo 3 for us. But still, using the composition API abstracting scenes, because currently our main logic abstraction is mixes. And it's very far from ideal. And speaking on the world of Vue, it's hard to say excited about anything because Vue 3 went into very stable phase right now. There won't be that much innovation. There will be some red sugar that is experimental right now. And I'm still a bit torn about it because it adds magic. And as we discussed during the Apollo part, magic is not always good. I'm excited to see where do we go with builtin SSR, because it's still evolving and this not only the SSRs in general, like Vite SSR. And I want to see how Vue will be working with this part. Quite excited to see what test an ecosystem will stabilize on. Because we have Vue test details. Natalia Tepluhina: Right now we have Vue test. I'm just curious to see what wins and what will be working because not everyone is using Vite right now. Because we have this little division and it's unstable, but usually there will be something that is winning, like it was with Chest and Karma in the past. And Chest won. So this part is interesting. Suspense is interesting too, because it never went to the stable one needed on React nor on Vue. So I'm curious to see where do we end up on Vue with Suspense because it's very promising concept. Complicated, but promising. And it could resolve so many things with just building the slot in state and the component from the start instead, maybe we can just drop it in Suspense and be happy. But we will see how it goes as well. So these are mostly the points I'm looking forward in Vue and ecosystem. Noel: Yeah. Gotcha. Back on what the testing tool suite ends up looking like long term, if you had to place a bet, where do you think we'll be, I don't know, in two or to three years? Natalia Tepluhina: For unit test, probably Vue test because eventually we... At least, Vue projects will probably move to Vite and I can see that not only Vue is moving to this one. I can say that React is using Vite too. And Svelte has Vite as a recommended solution. So it may become standard in two years. Can't bet on this, but it looks very promising. And it's a bit more complicated in terms of end to end testing because we had Cypress that was clear favorite for long time for JavaScript ecosystem. Right now, we also have Playwright and it's very promising as well. It looks amazing. So we will see Playwright also has a backend of Microsoft. Not that it's clear win, but it helps. Right? Noel: It helps. Yeah. Yeah. Natalia Tepluhina: It's also evolving fast and it looks very promising too. And I'm just angry, all these cool people who use Cypress or Playwright or whatever, because I'm using RSpec at my work. Noel: Yeah. I know. I know how that feels. Awesome. Cool. Well, was there anything else you want to plug or send listeners to? Natalia Tepluhina: Well, not really. It was an amazing podcast. Thank you for inviting me. Noel: Oh, of course, of course. It was my pleasure. It was great chatting again, letting us get into the weeds a little bit. Thanks so much, Natalia. Natalia Tepluhina: Thank you. Speaker 4: Thanks for listening to PodRocket. You can find us @podrocketpod on Twitter and don't forget to subscribe, rate, and review on Apple Podcasts. Thanks.