大话西游免费版法宝用经验升一级要多少

    1. <form id=TuUEamabd><nobr id=TuUEamabd></nobr></form>
      <address id=TuUEamabd><nobr id=TuUEamabd><nobr id=TuUEamabd></nobr></nobr></address>

      TypeScript, Wayfinder, and Ranger with Joe Tannenbaum

      Matt Stauffer:
      All right, welcome back to Laravel podcast season seven. I'm your host, Matt Stauffer, CEO of a Tighten. And in this season, I'm joined every episode by usually a different member of Laravel team. But today we have our first repeat guest. I'm so happy to have Joe Tannenbaum and Joe. I don't actually have your title in front of me, so you'll have to tell everybody. But can you say hi to everybody and tell them about what you do at Laravel?

      Joe Tannenbaum:
      Sure. I'm Joe Tannenbaum. I'm the open source lead engineer at Laravel and I begged to get back on the show. So that's why I'm back out. Well, I love you and that's why I want to be back on the show.

      Matt Stauffer:
      That's a lie. I love you, but that is a lie. I beg to get you back. Okay, fair fair fair. So because you're a repeat guest, we're not gonna kind of go through the origin story for anybody who has not gotten a chance to listen to the previous episode. I highly recommend you listen to it. We'll link it in the show notes. But today we want to talk about yet another thing that you're actually involved in. Today it's something called Wayfinder. And some of you all have heard of Wayfinder before because you attended or watched Laracon or you're actively plugged in. But I know from my history of talking to people who listen to the podcast that there's a lot of people who listen to the podcast who don't consume every video that comes out and watch every tweet or whatever. And so I just want us to get started by saying like, what is Wayfinder just from an elevator pitch? You know, what is it? And then we'll kind of dive into what it means and what's changed about Wayfinder since Laracon and everything like that. But first of all, just what is Wayfinder?

      Joe Tannenbaum:
      Okay, well there's two versions of Wayfinder. The current version that is out is generating TypeScript and JavaScript for your Laravel routes. So it analyzes your Laravel application, it analyzes your routes, and it generates TypeScript that you can import into your client-side code. And so that allows you to have some end-to-end type safety between the server stuff and your...

      Matt Stauffer:
      Okay.

      Joe Tannenbaum:
      your client side code in terms of routes. The new version of Wayfinder will do that plus a thousand other things, but we can get into more detail about that later.

      Matt Stauffer:
      Yeah. Yes, perfect. And one of the reasons we're doing the Wayfinder episode right now is because you are you have released the version that does the routes and you're working on a releasing soon based on when we drop this off the beta of the of the new version. So let's talk about the existing version quickly so that we can kind of use that as the base. And one of the things I told you ahead of time is I want to talk about Ziggy as a kind of comparison. So for those who listen to the podcast, who don't use TypeScript.

      You are likely in a case that I was in pretty recently where you're like, I keep hearing about this TypeScript thing and I keep talking about type safety and this, that and the other. And I'm just kind of like, what's the actual thing here? So I wanted to use Ziggy as our kind of comparison point. Ziggy is a tool that Daniel Colborne built while he was at Tighten and we still maintain it that allows you in JavaScript to use your Laravel defined route names. And so if you say, I want to link to the show book page,you link to, you know, books.show or whatever the short name is for your route and Ziggy kind of converts that into a URL. And so just like in your backend code where you can use Laravel's route helpers, you can also use Ziggy in your front end code to generate that URL. So the initial release of Wayfinder does a very similar thing, but it's different and largely I think because of the TypeScript aspect. Can you talk to me as imaginary listener, who is using JavaScript and who's using Ziggy and is not using TypeScript in a day to day and talk about what does the TypeScriptiness of this benefit and what does it give to us that we don't get from just pure JavaScript.

      Joe Tannenbaum:
      Okay, let me take you back just a little bit to I was looking through the Slack messages today to be like, how did this all start? I can't really remember because it feels like it was so long ago. I originally was going to build something into Inertia.

      Matt Stauffer:
      Uh-huh.

      Joe Tannenbaum:
      that was a drop in replacement for Ziggy, but it was generated on the client side. So I was building a little route helper and then it would just generate TypeScript so that you would get some auto completion around like routes and parameters and things like that. And then it would compile and then whatever you didn't use kind of went away.

      Matt Stauffer:
      How nice.

      Joe Tannenbaum:
      That was the original vision. was just like, okay, we have Ziggy. Let's do a drop in replacement. It's going to be kind of inertia specific and we'll just, we'll just roll with that. My teammate, Tim McDonald, Galaxy brain Tim McDonald, maybe one of the smartest people I've ever spoken to. I do not know what's going on in Australia, but there is something in the water because man, they are cranking out some insane devs.

      Matt Stauffer:
      Yeah.

      Same. Something in the water. Yep.

      Joe Tannenbaum:
      Tim said, Hey bud, I've been working on something called Wayfinder for a while and I'm doing, I'm just taking a very different approach. Do you like this approach? Should we like combo on this and figure it out? I loved his approach. Now his approach was forget route names.

      Matt Stauffer:
      Yeah.

      Joe Tannenbaum:
      What is the controller? What is the method you're hitting? So instead of saying, you know, form action, login, you would say form action is authenticated session controller store, right? So that you're kind of just like taking the name abstraction away and getting right to the code you've actually written on the other side. Then, that generates both the methods. So like the posts put patch, whatever you're using in the URL...

      Matt Stauffer:
      Yeah. Yeah.

      Joe Tannenbaum:
      within that little method call on JavaScript. That way, anything that you change on the server side gets automatically reflected. All of the URLs and methods, they don't exist anymore in your client-side code. It's just a reflection of what you've written on the PHP side.

      The benefit here, the benefit of TypeScript, and by the way, you don't need to be writing TypeScript to take advantage of this stuff. It happens to be generating TypeScript, but you can consume it in a regular JavaScript file. You just get more intelligence around it if you're also writing TypeScript. So the benefit of something like TypeScript is that...

      You get auto completion like if you like all of that IDE auto completion and pop-ups and intelligence as you write something like PHP. You get all of that in JavaScript too if you're writing TypeScript, right? So like if you hit quotes and we've defined possible values for that value, it'll pop up with a list of things that you can type there, and then it'll squiggle red when you type in something that's not in that list, right? So that's a very basic example, but that's the benefit of TypeScript. That's why we're writing this in TypeScript and strongly typing everything that Wayfinder is generating so that you get the maximum level of intelligence that you can in your IDE and at compile time that you can. I meandered a little bit there, but we got there.

      Matt Stauffer:
      Yeah, that's very helpful. No, it's good. It's very helpful because I think that only maybe two weeks ago or three weeks ago did I first hear somebody make the pitch that TypeScript is for IDE, not for, you know, because when people hear type safety, usually hear these things around protecting from developers making mistakes and helping with your compile. And it's a lot of stuff that we just tend to like care about a little bit less than some of the more kind of like.

      Joe Tannenbaum:
      You kinda shrug it off a little bit. Yeah. Yeah.

      Matt Stauffer:
      Yeah, right. It's like, OK, that's cool. Or yeah, those people are probably the people who put final before their classes. Like they're just trying to lock everything down more than I am. Right. But when you say, you know, TypeScript gives you a much better experience in your ID and it gives you auto completion for things. You everyone's like, yeah, great. Give me give me better auto completions. Give me a little pop up that says here's the parameter order that you should be expecting from this thing. And the way I'm used to in other languages that I'm not giving for my JavaScript. So I'm like, great. Sold. Makes sense.

      Joe Tannenbaum:
      That's right.

      Joe Tannenbaum:
      Yeah. And, and I think, I think especially, I don't want to make a huge generalization here, but I think PHP dev see there's very complicated typescript. You can write extremely complicated types and we've all seen them screen-shotted on the internet and passed around and like, this is the scary bit of typescript. That is a scary bit of typescript, but that's not the typescript you're probably going to be writing unless you're writing a typescript package, right? Like that's like package level code in your, in your day-to-day applications. You're not running anything...

      Matt Stauffer:
      Yeah, yeah, yeah. Uh-huh.

      Joe Tannenbaum:
      close to that. I mean, there's it's for the 99 % case. You're writing like really simple types that probably look relatively familiar to you from writing types in PHP, to be honest. Yeah.

      Matt Stauffer:
      Yeah, and PHP, yeah. And to your point, the idea that you can get benefits from a package being written in TypeScript without writing any TypeScript yourself, I think is also a message that is not being shared very much. So I'm very helpful that you shared that. Yeah, that's very cool.

      Joe Tannenbaum:
      That's the huge boost. Yes. Absolutely.

      Matt Stauffer:
      OK, so we have a version of Wayfinder out today that is for routes. And it's similar to Ziggy in that it allows you to link to your routes in the front end, but it adds two new benefits. One of the benefits being that because of the way it's compiled, one of the benefits being this TypeScript, so we get that kind of knowledge. But another one being the way that it's compiled, we have access to link it not just to your route names, which are kind of like pre-output, but instead it kind of directly links through the backend to your controller names and methods. So those are kind of the two big things we have going on now. But that's out. Very cool. Try it out. Experience what it's like. That's not the big story. What's the big story? OK.

      Joe Tannenbaum:
      Well, I'll add a third thing there, which is like, you know, I love Ziggy. I think Ziggy was great. I I'm a big Ziggy fan. One of the main complaints that people have is like, it exposes all my routes. And the first thing that I tell them is you should write your application as if everybody knows your routes. You should protect it accordingly. Right? So like that's the route isn't the secret. That's that should be, you could make all your routes public and you should still lock it down accordingly. That's point one.

      Matt Stauffer:
      Yeah, 100%.

      Joe Tannenbaum:
      One of the ways that we made Wayfinder is that any route you're not using in your actual client side code gets tree shaken out. Now there are, depending on how you decide you want to import them. So if you import the full controller namespace, so if you import like, you know, postcontroller.store,

      Matt Stauffer:
      Yeah. Yeah.

      Joe Tannenbaum:
      Well, everything from post controller down, you know, will be in your client side bundle, but you can also just import the store method and then you can get really precise about it say, like, I actually want to just make sure that like, that's the only one exposed in my client side bundle and just have that. So we try to allow you to import at any point in the namespace and get tree shake ability as far as we could down that chain. Right. So, and if you don't know what tree shake ability is that we're talking about, when you bundle your client side code, it will drop any code that you're not using. It'll intelligently analyze the bundle and say, actually, they're not using this export. Just drop it from the final bundle.

      So, I also want to clarify one thing because I get this question a lot nowadays. Yes, you can import the controllers and the methods, but you can also still import by named route. So you can import that login named route and use it the same exact way. There's just two ways of attacking the same thing. So we're not getting rid of named routes and we are, we are also.

      Matt Stauffer:
      Love it.

      Joe Tannenbaum:
      embracing them and that's totally fine.

      Okay, so I'm developing this thing with Tim. We're getting this package ready. It gets into its initial release and I get this like there's this thing in my head the whole time. I'm like well yeah we have routes now but like what are you supposed to be sending to these routes? Like that's also not type safe and that feels weird because now it feels like there's...

      The gap is a little, a little tighter, but it feels like there's still a gap. So I was like, well, we could, we could analyze validation and form requests. We could totally do that and then generate TypeScript from that. And I was like, well.

      If we're doing that, we could also probably analyze inertia responses and just see what the props are. So we could do that too. And I just was like, okay, how many, how many things can we analyze? And I just, I really rabbit holed for like a day or two. And I kept, we had this Laravel demos channel.

      Matt Stauffer:
      Yeah.

      Joe Tannenbaum:
      which is if you just wanna demo something that you're working on or just get feedback, you just drop a video in there. I mean, I think there was like a week, maybe two weeks straight where I was just like, hey, now it does this. I don't know, is this anything? Okay, well it does this. And is this cool? Do we like this? And everybody's like, yeah, yeah, keep going, keep going. So basically the new version of Wayfinder.

      Matt Stauffer:
      Uh-huh. Yeah.

      Joe Tannenbaum:
      analyzes a slew of things, namely, what are your form requests supposed to look like? What is the data that the client should be sending to the server based on what the server has defined? So this is stuff like form requests and inline validation. Wayfinder now analyzes that, builds out TypeScript so you can just supply that to use form or the form component in order to understand what should be coming back.

      Then we have inertia props that's coming down. So like when you are defining, like in vue, you have defined props, you can just drop something that Wayfinder has generated into that. It's so hard to say, it's so hard to verbally describe this.

      Matt Stauffer:
      Uh huh. Yes.

      Joe Tannenbaum:
      Basically we're generating types that you can just drop, like import into your component and drop in, right? That's the final thing. Then whenever those change, they change automatically as you write new code or you change code and they get reflected on the client side automatically. What else do we have? We have your broadcast events. We have the data that your broadcast events are broadcasting. So like whatever they're including with that broadcast, we're automatically generating that. All of your vite ENV variables are now being shoved into this like global vite ENV. So when you type...

      import.meta.env. you have all of those Vite variables and their types associated right then and there. Yeah, I'm blanking on more, but we basically have like a laundry list of things that were like, well, we can analyze that. We just should, you know, so we, we're trying to, the goal is end to end type safety between PHP and JavaScript. That is the goal. That is what we're going for.

      Matt Stauffer:
      Yeah. Do you think people will be using this a lot outside of Inertia or is this primarily beneficial for Inertia apps?

      Joe Tannenbaum:
      It is beneficial for anybody who is writing a backend in Laravel and a front end in JavaScript or TypeScript, point blank.

      Matt Stauffer:
      Love it.

      Joe Tannenbaum:
      If you are returning JSON, we are analyzing that. And so you can actually just say like, know, like if you're just using fetch instead of like anything Inertia, like we will tell you what that, that method is returning and you can type against that. And then basically have auto completion and, and, and validation right, right in mind with that.

      Matt Stauffer:
      Amazing.

      Joe Tannenbaum:
      Yeah, it's been it's this is I don't know why I keep choosing really hard projects, but man, I love a hard project. It's it's it's not trivial. It's it's really there were days when I just stared into the abyss, you know, but but in like an excited way, but also like in a whoo, this is a little overwhelming at times, you know, but.

      Matt Stauffer:
      Yeah, well, I mean, it's just a lot to talk about, let alone to imagine everything that you've built. so kind of as you're kind of talking through all these, what I'm hearing is again, like simplifying this down to somebody who's just like, only understood about 40 % of the words you just said. What I heard you saying, that's not me. No, no, no, no, no, no, you're doing great. You're doing great. I'm with you. I'm putting myself. Yes.

      Joe Tannenbaum:
      Sorry. okay. I've got so much in my head that I'm trying to like distill as we're talking and I'm like, it's too much. It's too much, yeah.

      Matt Stauffer:
      It's the curse of knowledge, man. So so what I heard you say is your finding a bunch of places where there are shapes of data that are going to either come to the JavaScript or the JavaScript is going to push against.

      So for example, JavaScript is sending data. It's going to be validated a certain way. So that means the PHP is expecting a certain shape of data. Let's tell the JavaScript it's expecting that shape of data by creating a type for that. Or let's say the data is being sent from the PHP to the JavaScript. It's going to tell the JavaScript, hey, expect data in this shape versus just, hey, there's going to be an array and there might be some stuff in it, right?

      So it's like in PHP where we used to all pass associative arrays around to all our functions. And now all of a sudden we've got object oriented programming so we can create a class and the class says, Hey, you should expect these properties to be on it. You just expect these methods. And so when you pass something in that's of that class, you now can make assumptions about it versus having to check, does it have this property? Does it have this method? And similarly in JavaScript, we're getting data from PHP and it's just sort of like, hey, I hope it has this stuff. And now it's going to be like, hey, when you send something from PHP to JavaScript, it's going to expect to have these specific things. So that's kind of the first thing I'm hearing in terms of the data transfer back and forth in HTTP requests. Right. So I'm to send a message to PHP for JavaScript or vice versa. I'm going to have more data about those things are going on. I want us to talk about that for a second. Some of these are clear.

      You know validation, you know is going to define what are the parameters that were expecting to be passed and some aspects of it. But tell me a little bit more about like when we're passing that information up to the JavaScript through these types. What do they know like if I were to say I? Expect an email field and the email field has to be an email. It's required And max length is 255. What does JavaScript learn about that from the validation there?

      Joe Tannenbaum:
      Right, so that's a great point. I've come to call all of these things that are currently in JavaScript that are not automatically synced by Wayfinder, educated guesses, which can fall out of sync with your PHP code. Like anything that I'm like, well, that's an educated guess. We don't know that that's what that looks like, but let's ensure that we do via Wayfinder. So like to your point, like when we were using associative arrays, those are educated guesses until the code just borks. And then you go, I guess that was a bad guess because it fell out of sync or whatever. Okay. So what gets passed up when you do something like that? We're boiling it down to primitives.

      Matt Stauffer:
      Okay.

      Joe Tannenbaum:
      As of now, I did go down a small side quest of saying like, well, we could do some actual validation on the JavaScript Skype. I felt like that was...

      Not the strongest use case. didn't think that that felt good. I just felt like we should know what is the key and what is the type value of that key. So if you're passing an email, we know based on your validation that that's supposed to be a string. So if you're saying it's required, it's a string and max length and all that, we kind of drop, we bring in required. We say this is a required field via TypeScript. We bring in that's a string. Anything else within reason, there's a couple of things that we'll bring in, but most of the things we...

      Matt Stauffer:
      Yeah. Yeah.

      Matt Stauffer:
      And that's it, yeah.

      Joe Tannenbaum:
      we drop. If you have an in rule, like if you say like, you know, it needs to be one of these values on the PHP side, we'll specify it has to be one of those values on the TypeScript side automatically. So then then we get a little narrower than like, it has to be a string. It actually has to be like the string one, two, three or four, right? Or whatever, which is a terrible example because those are numbers.

      Matt Stauffer:
      Yeah, because it's just so simple.

      Yeah, one of these strings. Yeah.

      Joe Tannenbaum:
      But the words one, two, three or four. Yeah. So so for validation, we discard anything that doesn't boil down to like the primitive type. And then for that's pretty much true of everything. We're really get down and getting down to like primitive types. There are zero promises, but there might be a world in which we have some helper functions for validation in the future. But I, I just don't think that's the job that we're trying to accomplish.

      Matt Stauffer:
      I'm with you, so.

      Joe Tannenbaum:
      I'm really trying to say like, keep it simple, keep it streamlined. there's too much variation between the two languages to do like proper email string validation between them. don't really want to do that. Yeah. So, so primitive values is the, is the answer, right.

      Matt Stauffer:
      I'm with you. Yeah. Yeah.

      Okay.

      And so we're using form requests, we're using inline validation, it's going to tell it what are the keys and what are the types that we should expect from those keys and sometimes also what are the potential options if it's like an enum type. And so that passes that information off to JavaScript. And now we're working in JavaScript. can kind of know like my submission to that should have these things. And our IDs will kind of clue us into that. You also mentioned that data coming back from the PHP to the JavaScript will give us some kind of typing. How does it intuit those sorts of things? Is it if you're returning a form response object or how does that work?

      Joe Tannenbaum:
      Are you talking about when like for an inertia render or a JSON response? that what you're talking about?

      Matt Stauffer:
      Either. I was thinking JSON response, really, you know, I guess with inertia render, it makes sense how it knows the data. But with it, it's with the JSON response as well, right? There, you said it kind of had some typing.

      Joe Tannenbaum:
      Right, so.

      We look at the method that the route is pointing to and we basically say like, okay, what are the possible returns here? And we look at the code branching. So we're looking at all the if statements we're looking in, like all the possible. Yeah, this is not trivial.

      Matt Stauffer:
      Wow. huh. Yeah!

      Joe Tannenbaum:
      And then we, we say like, well, here are the possibilities, right? This is what this is possibly returning. So it's possibly returning. Normally you wouldn't be returning inertia and, or something else. So it's usually like you're only returning inertia or you're only returning, you know, JSON, but. That part is sort of the easier part because we're just collecting like top line return statements. But then the part that's harder is that we're saying, you're returning this inertia component three times with different data. We're going to clobber that all down and say, what fields are you always returning? Those are now required fields and will definitely be there. And what fields are you optionally returning and what are the different shapes of those values?

      So we're saying like, you know, sometimes you pass a Boolean, but also other times you pass a string. So this could be a string or a Boolean. So we're going to say like account for either of those. So we're really trying to like distill this down to something that is actually useful on the client side. And the same goes for the JSON. So we'll collect all the JSON responses and say, you know, you're definitely getting these keys and you might be getting these keys and these are the shapes of the values of those keys and we even do that down the chain. So like if you have a nested key and it's required, required, required, maybe we will do that for you. like we were really trying to get as specific as possible because there's no point in creating types if the types aren't as accurate as they can be. My goal here is to never have an any type like as much as I can. You sometimes it's unavoidable but any doesn't help you. Yeah you get the key you get the key string but you don't get the value string the way that you really should. So yeah that's kind of how the analysis is going if that makes sense.

      Matt Stauffer:
      And for those not familiar in TypeScript, when you're typing things, you're saying this particular variable represents something that's a string or that's an integer. And if you say any, it's like, it could be literally anything. We don't know what it is. And so Joe's saying, we don't want to have those. Yeah, mixed in PHP.

      Joe Tannenbaum:
      It's mixed. It's the same as saying mixed in PHP. Yeah. Yeah.

      Matt Stauffer:
      Yeah. Okay. So if I were to be excited about Wayfinder, do you imagine this being something that people bring into existing projects? Or is this more like you probably want to start from scratch with this?

      Joe Tannenbaum:
      No, you could totally bring it into existing projects and you can bring it in incrementally. So you could bring it into only new features. You could bring it into, you know, you can, you can convert things one by one as you're going. There's no, there is, you don't have to go like, right.

      Matt Stauffer:
      Mm-hmm.

      It's not magically auto-applying to things. Yeah.

      Joe Tannenbaum:
      There's no magic in it. You use what you want to use you and it'll automatically get discarded, whatever you decide not to use. So bring it into your existing projects. Yeah. What's that? Go ahead.

      Matt Stauffer:
      Yeah. And I know this is harder to do. No, go ahead. I know this is harder not being able to kind of like write code in front of them. So I appreciate your willingness to talk about this because I, know, if and for those who have not looked at, I would definitely recommend just go look at the Wayfinder readme because even though it's only routes right now, you can just see how it says import this and it's like, yes, I'm importing things from Wayfinder when I want to not just kind of blanket applying some Wayfinder conversion to my existing code.

      Joe Tannenbaum:
      Correct. And even stuff like you mentioned enums earlier and you said, know, enums, you know, what if it's, what if the form validation like is requiring an enum, right? Well, we actually are generating your enums as well. So like you can pull those in directly in the client and actually make sure you're using the correct things based on what you, what you've generated in your, in your code, in your PHP code. So if it's in your PHP and the client might be consuming it, we are really trying to get it in there.

      Matt Stauffer:
      Oh cool.

      Matt Stauffer:
      Okay.

      Joe Tannenbaum:
      And case in point, mean, somebody at Laracon literally day one before the presentation even happened, came up to me and said, like, I would love a way to get my translations into my current client side code. And I was like, we could totally do that, dude. I'm, I'm with you, man. Let's go. It's good. So it's on the list. We're going to figure it out.

      Matt Stauffer:
      We can add that, yeah. It's on the list.

      Joe Tannenbaum:
      We're going to, mean, getting them in there isn't hard. It's how you consume them as the hard part, because you don't want to load up your whole client side bundle with, every translation in your app, which gets pretty, pretty hefty, but we'll figure that out.

      Matt Stauffer:
      Yeah, with all your translations. Yeah. Well, speaking of client-side bundling, I'm assuming, but I should actually sanity check with you, that if I am making changes, let's say I rename one of my controllers or something like that, if I'm not running vite, I assume that that will temporarily break my front end. So if you're working on an app that uses Wayfinder, you should have vite running any time you're making backend changes, right?

      Joe Tannenbaum:
      Yeah, so there's a Wayfinder vite plugin that basically watches the appropriate files in your code base and runs a command behind the scenes to generate new TypeScript every time you change one of those files. Yeah, yeah.

      Matt Stauffer:
      Okay, cool. Okay.

      Joe Tannenbaum:
      So it's part of the vite process, both in the dev and build modes. Yeah.

      Matt Stauffer:
      Okay. All right. So we have talked to, I kind of talked at more depth at the form, the HTTP passing the form stuff, and you kind of gave us lists of some of these features. One thing I didn't ask you specifically is in what ways has Wayfinder changed since your announcement video at Laracon, if at all?

      Joe Tannenbaum:
      Well, I, so, you know, when you prep these talks, sometimes you do happy path and we did happy path. Like, right.

      Matt Stauffer:
      Sometimes we always do happy bath.

      Joe Tannenbaum:
      So, you know, I knew exactly what I want to do. I knew which types were being generated and it worked. It like does actually work in the way that I was presented at Laracon. When I threw it at, say like a Forge code base or a Cloud code base, which is like a, not insignificant code base.

      Matt Stauffer:
      Yeah. Yeah.

      Joe Tannenbaum:
      still worked pretty slow, pretty slow to compile and doesn't feel good in your dev cycle. So I was tapping into some PHP stand internals. I was tapping into some existing static analysis tools that are very robust. And that's why I was tapping into them, but are a little too heavy for what I'm trying to do with Wayfinder.

      Matt Stauffer:
      I was just, so it's the compile that's slow. Okay.

      Matt Stauffer:
      Yeah.

      Joe Tannenbaum:
      So the big changes that I'm building my own static analyzer, which, um, I, I,

      Matt Stauffer:
      As one does, you know.

      Joe Tannenbaum:
      I really fought not to do. And if anybody listening to this says you fool, do it this way. I will give you the biggest hug ever, ever, ever.

      Matt Stauffer:
      In a heartbeat, yeah. Yeah.

      Joe TAnnenbaum:
      But, uh, as of now I'm building, um, a static analysis tool, um, which we can then use in other projects that we have, such as like the VS code extension and some other things. So it's not, it's not really a one-off, but,

      Matt Stauffer:
      Yeah.

      Joe Tannenbaum:
      Yeah, I'm building a static analysis tool that allows it to report back what it's finding and then allow me to do something with that report.

      So I also announced a tool, a new package called Ranger at Laracon as well. And now Ranger sits between Wayfinder and the static analysis tool and says like, here's the static analysis results. Now we're gonna sort of announce prepackaged things that we're interested in up to whoever is listening. It's just turtles all the way down. But you know, yeah. So that's the big change is that, I'm building a static analysis tool against my will is the, is the big change.

      Matt Stauffer:
      Yeah. Okay, so speaking of things that people say all the time and a lot of people don't actually know what it means, I talked about TypeScript first. We're going to talk about static analysis. If I've never heard of static analysis before, what does static analysis actually mean?

      Joe Tannenbaum:
      You are analyzing a code base without running it. So you're consuming the code, you're tokenizing the code. And thankfully there are packages that I'm leaning on that do some of that heavy lifting for me in a way that is wait, I always forget. It's like Nick PHP parsers. It's the same thing. Is that, is that the one?

      Matt Stauffer:
      Php parser, yeah. Yeah. Everybody uses that as the base, because it's just so good. Yeah. Yeah.

      Joe Tannenbaum:
      Yeah. It's the same one everybody uses. It's so good. And it's, allows you to just sort of like match classes up as you find them and it makes it really consumable. So I'm standing on the shoulders of giants here, but I'm still building a static analysis tool. So I'm using that. I'm using the PHP, PHP stand doc and doc block analyzer package, which is doing a lot of heavy lifting on doing that parsing and reporting back. And then I'm gluing that together to make my own thing, but it analyzes your code without running it. That's the important part. So it's doing static analysis on your code. Yes.

      Matt Stauffer:
      Yeah. And so you're building a super light one that does only the things you need it to do, which allows it to go faster. Are there any other aspects of and I know that, you know, in theory, got it. Got it. Fingers crossed.

      Joe Tannenbaum:
      Yes. I'll say in theory, we haven't gotten to the end of this road yet. So like, there's no way I'm building something more robust than PHP stand in the time that I have, but I'm looking to get to, know, transparently I'm looking at the 90 % mark and then we'll fill in that last 10 % as time goes on and as we need to. But yeah, this is the stuff I'm interested in falls within that 90 % mark.

      Matt Stauffer:
      Yeah, and as a person who's never built a static analysis tool, I am actually very curious about how it works. I assume because you're using the PHP parser, it's all in PHP. So I'm curious about like what does optimization look like at that low of a level? And when you're talking about the optimization of like needs to be able to read through thousands to tens of thousands of files in preferably less than a second, because you don't want your build to add an extra two seconds. What kind of things are you looking at optimizing? Are you looking at

      Joe Tannenbaum:
      Yeah.

      Matt Stauffer:
      optimizing the speed of for loops? Are you trying to figure out how to exit? Like what kind of nerdery do you get to get into that maybe isn't a part of our day to day world as Laravel people who are trying to ship fast, not hyper optimize, you know, a single run, a single loop or whatever.

      Joe Tannenbaum:
      So I could fall down the optimization rabbit hole extremely hard.

      Matt Stauffer:
      I figured. Yeah.

      Joe Tannenbaum:
      I am purposely not doing that upfront because I want to get to a place where I'm confident that what I'm doing is correct. And then I'll kind of go back and do some optimizations, but. Things that I am thinking about because they just have already come up in the work that I've done is you have to have some sense of sensibly caching things that you know you've already handled, right? So like there's a little bit of like, know, this file is using this class. We've already analyzed this class. Don't reanalyze it. Just, you know, have some sort of cache there. That's kind of baseline. But then there's stuff like, you know, I would often reach for

      Matt Stauffer:
      Yeah. Yeah. Yeah.

      Joe Tannenbaum:
      collections, but I'm probably not going to because it just adds a little bit of heft and you just, you know, so now we're just doing, we're getting down to the basics. We're getting down to like core PHP and I try to keep it that way only. I also do a lot of like, does this need to be an object? Could it be something simpler than an object? There's a lot of that. Yeah, yeah.

      Matt Stauffer:
      Yeah. Yeah. I wondered if it was that because it's a bummer because like we love using things like collections and objects and you know and then when you run a loop of 10,000 and you see that obstinately that object 10,000 times or doing that 10,000 item loop in a for each versus a collection actually makes a difference especially when it's a package level where this is just one of many things that's happening right if that collection is running in my controller.

      Joe Tannenbaum:
      Yeah.

      Matt Stauffer:
      that difference in milliseconds probably doesn't matter to me, but it's running as a package that is one of 20 things that's running before he even gets to user land code. Suddenly it's like, I don't get the convenience of that because I've got to shave every microsecond, millisecond I can off.

      Joe Tannenbaum:
      Yeah, at scale it doesn't at scale you can feel it. You can feel that it's it's a little hefty, but those that's what we're doing. Yeah. Yeah.

      Matt Stauffer:
      Yeah, OK. All right. So when I asked kind of the question I asked was like, what has changed since Laracon and that was your first answer was, I got to make sure it can kind of stay fast. Are there any AST feature API kind of changes that you're making or is it more like it's probably supposed to do the same things you also for those who saw the talk, it's supposed to do all those same things, but we're just trying to make it can do it, make sure it does it.

      Joe Tannenbaum:
      Yeah, I think I added, I added the ENV stuff. I added a couple of little things that I knew. I was like, we use this on the client side. I can definitely analyze this through like, that's fine. So I added a couple of things here and there. and there will be more added once the static analyzer is built. More things will be added because I've kind of, I've got about five additional things that I can't remember. I should have read before this that I'm going to add. That's the big, it's just going to be more.

      It's going to be more, more things that it will generate. And if you're not interested in those things, we'll provide configs to say like opt out I don't even want you to generate this stuff so that if you don't care about your translations, if you don't care about, you know, named routes, whatever you can opt out and, probably increase your or decrease your dev times, I guess. Yeah. Yeah.

      Matt Stauffer:
      Yeah, it's a little faster. Yeah. Okay. You mentioned that ENV is not having kind of like poked at that after you said it, but I do want to say that it feels extremely magical to be in what feels very much not the world where we get intelligence and to be start typing and then for it to be like, yep, I know what your NV is. And it's just kind of auto. And I'm like, but I wrote that in my dot ENV file just, you know, five hours ago. How do you know this? And so.

      I just want folks to say like even if you're not familiar with TypeScript, even if you're not interested in TypeScript, getting this level of intelligence in your IDE. Sorry, let me let me go back at that again. Folks have often suggested that in order to get better IDE completions and stuff, we need to add sprinkles of, you know, what are they called? Annotations all around our PHP code, right? And I've worked with people who are like big PHP Stormheads and every line of code they write has

      Joe Tannenbaum:
      Yeah.

      Matt Stauffer:
      three lines ahead of it that's saying it's a var of this, var of that. And I've always been the guy that I'm like, I'm sorry, but I'm not willing to write code that I hate reading for the sake of an IDE. I'm just, I don't care that much.

      Joe Tannenbaum:
      Yes. I know. But.

      Matt Stauffer:
      But, but pulling in a package that doesn't make me write things differently almost at all, you know, like, yeah, importing it might be a little bit different, but sometimes importing the Wayfinder definition of something actually be faster than writing it myself. So I'm getting my coding workflows actually better because it's clear and simpler and I don't have to change it when I change the backend, but also getting all this IDE improvements for what feels like for free. I'm like, now that I can sign off on, like that's a very exciting, you know, exciting kind of improvement.

      Joe Tannenbaum:
      Yeah.

      Two things on that one from day one when I started like in earnest working on Wayfinder with Tim. I said I do not want people to change their existing PHP code to make this work.

      Matt Stauffer:
      Yes.

      Joe Tannenbaum:
      It makes me crazy to annotate something that has nothing to do with the thing that you're actually looking at or like add extra weird little dog blocks or whatever. That makes me insane. And so I was like, I'm not, that is the goal. That is the north start. We should just generate what is accurate from what is there.

      Matt Stauffer:
      Love it.

      Joe Tannenbaum:
      The second thing is after the presentation at Laracon, I had so many people come to me and say like, this is the first time I've even thought about writing TypeScript based on what you did up there. And I was like, that's the win. I was just, I could just walk away. And not that I'm a huge, not that I'm like an, like a crazy TypeScript person, but like if you just embrace it for a week and you're not even writing that many types.

      Matt Stauffer:
      Yes!

      Joe Tannenbaum:
      The IDE intelligence goes up exponentially. It's so much more and it's so useful. And especially when you're consuming packages that have really good types associated with them, you just immediately feel the difference. You're like, how did it know that? It's a lot of how did it know that? And you know, now this, I will say this, the stronger your PHP types are, and some people are already screaming, the stronger they are, the better...

      Matt Stauffer:
      Yeah. Yeah.

      Joe Tannenbaum:
      the tighter it's going to be on the Wayfinder side, right? So I'm doing static analysis and, you know, PHP only knows what PHP knows. So I'm doing the best that I can. and this static analysis also includes as much Laravel, for lack of a better word, magic as possible. I'm like, if I can't find the method I'm looking for, I'm like, is it a macro? And I'll look and if it's a macro, I'll pull the macro and like understand. So it's like really injecting, like specific to Laravel static analysis.

      Matt Stauffer:
      Mm-hmm.

      Joe Tannenbaum:
      That being said, the tighter your PHP types are, the tighter the Wayfinder types are going to be. Like I said, there's a direct correlation to like, you are saying it's this, I will generate that. No problem. Yeah. So.

      Matt Stauffer:
      Yeah, when I just actually the last question I had for you before I asked the usual, is there anything you want to cover that we didn't is, is there a way that you think that we should be writing our Laravel code that enables it to better synchronize whether through Wayfinder or anything else with the front end? And I mean, you mentioned, okay, using form requests inline validation. mean, I don't think you should be doing validation any other way, right? So, okay. But like what other things are there any ways you said we don't have to write code for this?

      Joe Tannenbaum:
      Par for the course. Yeah, yeah, yeah.

      Matt Stauffer:
      But lots of times when there's like seven different ways to do a thing in Laravel, a new tool comes out and like this new tool only works with four of the seven. So maybe start using those four. Are there any ways that are still multiple options, but where you're like, it would be more valuable if you do more of this or less of this, or is it really just what you said is basically the quality of your types is reflected?

      Joe Tannenbaum:
      I'm really trying to meet you where you're at. I'm really trying. I guess my only advice would be I would invite you not to get too clever. Like I think that's just a general good rule anyway.

      Matt Stauffer:
      Yes, agreed.

      Joe Tannenbaum:
      I think like getting too clever about your code is fun for you and bad for everybody else. I think it's, no, I mean, I think it's one of those things where if you're the only one maintaining this thing, great. Be a genius about it. I love it.

      Matt Stauffer:
      Sure, yeah. Yeah, yeah.

      Joe Tannenbaum:
      Otherwise, I think we have some good conventions, especially when you're using a framework, lean into those conventions. You don't need to invent a whole new paradigm, like just lean in. And especially if you lead in, Wayfinder will understand things better. But I'm really, really desperately, desperately trying to meet you wherever you're at, no matter how clever you're being. We'll see how it pans out, but that's, that's the goal.

      Matt Stauffer:
      Okay, so it's kind of the same story we keep telling, which is the more you stick with the Laravel kind of idiomatic way of doing it, the Laravel defaults don't kind of think that you're smarter than the framework. You're more likely to have a good time, but Joe's a good guy. He's gonna try and make it work for you either way.

      Joe Tannenbaum:
      I try man, I'm gonna try.

      Matt Stauffer:
      All right, I know that we're, I told you this was gonna be short episode and I lied. There's so much good stuff here. Is there anything that we haven't covered about Wayfinder that you wanna make sure we get a moment to talk about?

      Joe Tannenbaum:
      I don't think so. I think what was interesting to me post-talk is that people were amped about Wayfinder, but they were really amped about Ranger. And I was really surprised because I devoted two and a half minutes to it, I think. I don't even know because I was just like, this is an implementation detail. But people are amped and I'm amped that they're amped because I want to see what they build with it. So I'll have more details.

      Matt Stauffer:
      Yeah. What's Ranger for anybody who didn't see your talk?

      Joe Tannenbaum:
      So Ranger, basically under the hood runs the static analysis tool and then kind of reports back these well-defined typed objects that say like, Hey, I found a route. Hey, I found an inertia response. Hey, I found a config value. Hey, I found, you know, and it reports back things that you say that you're interested in. It won't even touch anything that you're not interested in. It'll just say, you know you, you set up these listeners, you say like on route, do something with this route and, and then you can do anything. So in Wayfinder's case, it's generating TypeScript, but you could generate, you know, open API specs. could generate, you know, Jason schema. could generate. XML markdown files, whatever you want from what is in your app. And, it's meant to be sort of this blue sky tool that says, like, I do one thing I do well.

      Matt Stauffer:
      Yeah, I tell you things about the app. What do want to do with it? Yeah.

      Joe Tannenbaum:
      What do you want to do with it? the right? What's up for you? So, yeah.

      Matt Stauffer:
      And when, when I first read through the Ranger code base, everything was like the day put it public. I noticed that there were things that I don't know if you still have them there, like has a composter dependency, has a composer dev dependency, uses a particular way of programming.

      Joe Tannenbaum:
      that's the, I think that's the roster code base. That's roster, which is, which is something Ashley put out because Rangers not public yet.

      Matt Stauffer:
      Is it really? Okay.

      Joe Tannenbaum:
      It is very not public yet because I'm still even like figuring out the API. I, I, I have the API that I I'm happy with, but I want to make sure it's like the right one overall.

      Matt Stauffer:
      Okay, that definitely explains because I was just like, it's feeling like it's diverging a lot from what I first read. So that explains why.

      Joe Tannenbaum:
      I think it's called Roster. think that's the one that Ashley put out that analyzes your composer dependencies and package dependencies. Yeah.

      Matt Stauffer:
      It's roster, I've got it pulled up. Yes. And it's the whole, it's so funny because I've mixed the two up in my head and like I was telling people at Laracon, I was just like, wow, I expected a Ranger was gonna be used more for AI stuff and now he's using it for this. And that's why, apologies to anybody I've misled over the last several months.

      Joe Tannenbaum:
      Maybe it something to us about our naming. should coordinate that and make sure we're on the same page. Yeah.

      Matt Stauffer:
      I mean, cool new package that does discovery about your app that's six letters long and starts with R and ends with ER. You know, I'm not saying you guys need to rename it. I'm just feeling not too bad about myself.

      Joe Tannenbaum:
      I know. It's an understandable mistake.

      Matt Stauffer:
      So OK, cool. So Ranger is not public, but at some point Ranger will be a tool that's public that is accessible to the rest of us. And it is primarily around discovering the state of certain things in your app and then allowing you to do. Is that on hook? Is that like?

      How does that actually, how do you build the hooks? Is it sort of like you build a definition of those hooks and then you run a command in Ranger and it processes it and then does all the hooks and then just exits?

      Joe Tannenbaum:
      There are predefined hooks that that ranger comes with. Like you can't right now, you can't extend it. You can't like do custom things with it. It's just saying like, you know, this is what ranger is willing to report about. And these are like the shapes of the things that it brings back. And then what you'd so in like Wayfinder's case that generates command, which is generating the TypeScript says like it news up ranger and it says on route.

      Matt Stauffer:
      Mm-hmm.

      Joe Tannenbaum:
      generate the type script for the route on configs, generate that on, you know, and it just kind of goes online and then it says Ranger walk and it just walks your app. Yeah. So the, ultimately after you set up your listeners, say, okay, now do it now go off you go. and Ranger will be out in beta.

      Matt Stauffer:
      Okay, so it's got a command that, yeah, okay. Got it. Okay. Ranger Walk is fun.

      Joe Tannenbaum:
      Yeah, it's fun. It's I think it's going to be very useful and I'm so excited that people are excited about it. I just wasn't expecting it. Yeah.
      But it'll be out in beta probably right at the same time that Wayfinder is, because they depend on each other. So it'll be kind of neck and neck there.

      Matt Stauffer:
      If you're listening to this podcast and you have a vision for what you're going to do with Ranger when it comes out, hit us up anywhere. Comment on the YouTube, hit us up on Twitter, BlueScry.

      Joe Tannenbaum:
      Yes, want to know.

      Matt Stauffer:
      We're just very curious to hear kind of what are your plans with it.

      Joe Tannenbaum:
      Absolutely, absolutely.

      Matt Stauffer:
      Okay. Joe, is there anything else you wanted to cover?

      Joe Tannenbaum:
      I think that's it. I think that's it.

      Matt Stauffer:
      Okay, thank you for being my first repeat guest of the season. I really appreciate you.

      Joe Tannenbaum:
      Thank you for having me.

      Matt Stauffer:
      Marathon at this point, we have 45 minutes. And we're really excited. I'm very excited to try Wayfinder. I'm excited to be fully converted. I use TypeScript a little bit, but I don't get to code that much these days. But I'm very sold on having this smart IDE auto completion, so I'm ready.

      Joe Tannenbaum:
      Awesome. I'm extremely excited about it. This is like a pain point that I could feel intimately and I'm really excited to solve it at this point.

      Matt Stauffer:
      Very cool. Well, thank you for working on the package and all your contributions and thank you for hanging out with us.

      Joe Tannenbaum:
      Thanks man, I appreciate it.

      Matt Stauffer:
      Awesome. And for the rest of you, we will see you next time.

      Creators and Guests

      Matt Stauffer
      Host
      Matt Stauffer
      CEO Tighten, where we write Laravel and more w/some of the best devs alive. "Worst twerker ever, best Dad ever" –My daughter
      Joe Tannenbaum
      Guest
      Joe Tannenbaum
      Full-stack developer at LaravelCurrently fiddling with tidyinbox.com and termsky.app
      TypeScript, Wayfinder, and Ranger with Joe Tannenbaum

      headphones Listen Anywhere

      More Options »
      Broadcast by
      He went upon the sick report at once, and for three days thereafter raved of crucified women with fair hair, of children lying dead in the ca?on, of the holes in his boot soles, and a missing aparejo, also of certain cursed citizens, and the bad quality of the canned butter. And the Indian may be trusted to know of these. Here where the jacales clustered, there was grass and wood and water that might last indefinitely. The fortifications of Nature had been added to those of Nature's man. It was a stronghold. "Doctor, he can't die. He mustn't die," said Shorty in agony. "The regiment can't spare him. He's the best soldier in it, and he's my pardner." to Miss Jerusha Briggs, at this plais, and I will pay the "I did," answered Shorty. He was carrying his Belbis beam, of course. The little metal tube didn't look like much, but it was guaranteed to stop anything short of a spaceship in its tracks, and by the very simple method of making holes. The Belbis beam would make holes in nearly anything: Alberts, people or most materials. It projected a quarter-inch beam of force in as near a straight line as Einsteinian physics would allow, and it was extremely efficient. Albin had been practicing with it for three years, twice a week. Mating, he thought. If the chain of obedience was broken would the trees refuse to obey, in their turn? Puna had said so, and it was true. And if the trees refused to obey there would be no mating.... "Wandered, you mean. Just wandered off. And—oh, I suppose a few have. Our methods aren't perfect. But they are pretty good, Johnny: look at the number of Alberts who simply stayed around." Then suddenly she began to plead: He took his place beside her, but he could not fix his mind on what they sang. In the intervals between the[Pg 153] anthems he was able to pour out instalments of his tragedy. Bessie was very brave, she lifted her eyes to his, and would not let them falter, but he felt her little coarse fingers trembling in his hand. God save the Queen!" Tilly had a spurt of anger. HoME大话西游免费版法宝用经验升一级要多少 ENTER NUMBET 0017
      www.sytp.net.cn
      www.fuxu9.com.cn
      www.scb10.com.cn
      gltzn.com.cn
      taike8.com.cn
      citie5.com.cn
      www.1to1liao.org.cn
      yejin1.net.cn
      3xf75.com.cn
      www.neitu7.net.cn
      日本女同性爱毛片 妹妹av黄色 色女人激情图 双飞做爱图 6655人体亚洲 WWW.720BB.NET WWW.LBPMK.COM WWW.GEGE0.COM WWW.9ZY.COM WWW.AKXS6.COM WWW.SE59.COM WWW.V2511.COM WWW.TE3456.COM WWW.WUYESE.COM WWW.HNYEZF.COM WWW.977X.COM WWW.465E.COM WWW.CRXZ.COM WWW.OMYTVS.COM WWW.ENET.COM.CN WWW.8FKD.COM WWW.HYWIC.COM WWW.313K.COM WWW.NI37.COM JESSCIA.STROUP WWW.MXIEZI.COM MIDE543荒木在线 偷拍自拍在线录音 欧美少妇乱淫图 怡红院更新前的主页 黄影视 裸片A片 全球免费共享视频在线 岳母丝袜乱论 mcomcomc免费A片在线播放 大型色小说 www搞处女cn 中文往往对电影 欧美sm免费无插件在线视频 亚姐妹 咪米色网站 亚洲视频国产自拍亚洲色图 怎样进黄色电影网站 华人av偷拍视频在线 亚洲色图美利坚 oo后自慰高潮网站 性爱技巧9页 色色影www38rjcom wwwribi 美国伦理母亲电影 57AV00com 超碰涩涩涩 自拍偷拍卡通动漫黑白中文 内射妹妹 快播 3344nq 福利云点播免费日本A片黄片 144人体图片 appssav25com wwwpp856cc 人妻熟女自拍在线播放 快播理论黄色片 看老婆被技师抽插 少妇舔阴茎 欧美色网胖女人 kk44kk44com 黄色淫乱片子一 澉情五月网vv99vvcom 成人丝袜视频大全集 a资源吧亚洲首页 丝袜电话 在线影院淫色熟妇 欧美成人网站555dvd 西西性爱电影 黑太阳731续集之杀人工厂 欧美丝袜整片 sexwww ddfnetwork免费 射精卡通动漫 黄色l乱伦 变态强奸片 强奸乱伦破处 欧美干老太婆 小泽玛利亚女上男下 cao320AV 快插毛片电影百百度 淫淫色色色色 撸吧全迅 操少妇双洞齐开15p 日本有什么黄直播app 动漫啪福利 大香蕉霞 1769导航 成人文学公共汽车 老婆的淫荡晚会 大鸡吧在线av 成人嘿咻嘿咻网 成年人电影毛黄片 国语对白干妈视频 老头抽插美女 亚洲超碰撸撸在线视频 神雕侠侣伦理片 wwwbibiav520com WwW683kKC0med2k 每天射十次大叔 www97kxwcom av能看的操逼 WWW48com 一本道性欲?⒌纳俑 姐姐在线爱 在电影院偷情舔逼 3366vod下载 成人玩具哥色咪色 发嫩藤 和姐夫做爱吸乳 御姐很哀伤ckplayer wwavav521com japanesex无码日本动漫 色色哥哥色 孙丽让谁干过 淫chacha 张柏芝艳门b照图片 操中年女人的肥臀骚逼 长谷川由奈写真 妺妹网日本人体人体图片 cccaobipian 亲家母狠狠撸 东莞扫黄女子图片 欧美骚妇淫色诱惑图片 很很干很很撸图片 淫乱无码网站 最大胆美女人体艺术 她噢片级 春暖花开有你性亚州 无码 颓废的国模林邈子 pptv色色电影 超爽的性爱16p 影音先锋南洋第一邪降 肏阴部 手机性爱视频综合社区 丝袜诱惑小穴 台湾妹视频 66abcd怎么不能看了 国产人妻多年3p4p激情照62p 回家开门时被人强行拖进家中强奸中的女优 亚洲激色图 医生强奸 等爱的玫瑰 petsaga 生死狙击辅助 dewsuperior 操骚逼女 少女之交配 偷拍wc欧美 欧美女与动物发生性关系视频 影音先锋影院影视 99人体艺术网com 哥哥ppp 操乱伦操骚逼小说 乱伦另类撸 撸一撸色奶奶有妓看 韩国嫩白美女小穴图片 韩有天伊宝媛 亚洲另类先锋快播 超碰肛交免费视频 五月天丁稥婷婷 人体艺术女同性恋视频 翘起鸡巴日亲娘 亚洲性爱视频网站 国产AV资源百度云盘 东亚兽皇 韩国日本偷拍自拍视频 操昏迷女逼图 骚穴黑丝口 亚洲欧美卡通动漫偷拍自拍 theporn最猛成人网站 大鸡巴干衅电影 人体艺术图片有人体艺术图片 37av免费视频 漫画淫图 浴室性片 人妻被公公操的动漫 葫芦岛性息 轻吻也飘然在线福利 www老人兽laojjcom 韩国高中生美穴 日本人体阴唇艺术摄影 兄弟交换夫妻用 20岁成人免费视频在线免费试看 韩国美女主播阿里快播 商务qq黄色片 2017伦理电影手机农夫山泉在线 68人体艺术私处 赶紧撸东北浪妇偷情小说 010酷播妹妹 HDXXX幼女 国产超级法在线 俄罗斯人与shou 成人三级片黄片毛片 四虎相关网站 夫妻交换高清图片 米雪儿麦库尔A片 干少妇丝袜小说 色久久影院app最新版 贾静雯三级片 舔b全露视频 聊城交通违章查询 爱色影天天色 美丽熟女网 香港大胆人体 丝袜骚妇丝袜腿模 我的第一次被干从清纯到淫荡的幼儿教师 色中色人体艺术电影 美国裸体俱乐部 黄色一级倨情 91retvwww91retvm91retv 玉蒲团淫女 调教母狗的网站 另类激情小说淫色人与兽 五月天涩涩爱 情欲轮奸小说 移动上不了h网 东京热大乱cd2rmvb 怎么在快播里看黄片 前田かおり 红磨坊影院 高清成人图片 开心激情影视 美女娃娃做爱 御の二代目谁有E谁有G 色五月女王来了图片 俺去橹 色七七2018综合 久悠影视 李宗瑞偷拍影院 日韩αv小视频 vv影院 蒂亚AV资源 avtt144 韩国美女与男友宾馆开房嘿呦自拍表情销魂,我一旁拍摄她男友不行换我上,嫩 午夜丁香花在线电影 青青私密视频 性交无码教学 在线看片瑟瑟爱 日橹免费在线 酒店真实高清露脸对白 亚洲 小明看看 大香蕉X影院 阿v影音在线观看 五十岚纪子在线视频 诸葛影院在线理 日日夜夜不卡另类视频 了:国产自拍 亚洲狠狠色无码视频 黄色咸网 9877黄小游戏大全手机版 新视界影院 magnet 日本AV黄图 mp4 福利大鸡吧 九州资源永久免费视频 真人啪啪啪视频AV 邪恶插阴口动态图 五福影院aⅴ凹凸av 中国内地在线av免费视频 看看十八岁的性器官视频 淫荡便器电影 亚洲VS天堂 ssn190 谷露影院手机在线0 成人A片 迅雷下载 aiaifulidaohang snis885磁力 834成人视频 手机在线电影 国产区 色青春亚洲综合 影音先锋资发布站 香港成人夜色影 221sihucim 彩乃奈奈中文字幕在线播放 h版神探夏洛克下载 丁香五月网韩国主播 xxo影院 大尺度广场舞视频 日本换妻性交视频 一本道mag magnet 免费色系视频二十多分钟 2018仙女屋19禁电影大全 色酷狠狠干 8090电影风筝 女仆资源 曰本黄色视频免费高清 好XXOO在线视频 潮喷合集丝袜无码mp4 看着我的女友变淫荡 mp4 成人看片小视频 四虎影院手机观看视频 五月丁番 巨乳无码电影 平凡夫妻性生活自拍 3p美女拍拍 91密秀官网 九九深夜福利在线免费试看 干妹妹高清在线影院 依人综合在线观看视频 水上百合中出孕妇 sss黄片 洗澡自慰在线播放 三d影院深夜不再寂寞 色站导航丁香色 迅雷无码冲田杏梨 AV走 ssni-056 胸部跳蛋视频 小泽玛利亚无码在线视频 性交视频内射白浆视频 操洒店小姐 唐朝AV中文字幕 偷拍福利萝莉 后入大屁股美女全集 亚洲高清自拍有码 吃女友的胸她娇喘 日本高清959dd 一级黄色录像带 tyod-278hd 整个福利 感谢不删好友不屏蔽之大恩院线同步电影 发给没时间去电影院的朋 今日排名第一页长片 xooⅹ430 爆乳保姆激情电影 国产自拍裸照 mp4 操日本美女视频播放 被控者完整版在线观看 色搜在线播放 深夜直播 magnet 色悠久久桃花综合网 另类小说五月天综合网 色琪琪aⅴ stringendo av仓库永久地址 ww884aaco wuxiaorui renrenmoshiping japanese AV 谭晓彤在线福利视屏 成人操逼激情视频 维他命色vvtvt av宫前幸惠在线观看 颜射大奶在线播放 透b叉叉在线自慰视频 老司机影院院写真集福利 国内自拍va偷拍视频 本庄玲在线 国产足j在线观看 播放3个98年艺校小美女买完零食回来比赛 草榴在线自拍 国产在线 幼幼在线av 校花啪啪啪影院 少女哥哥我想看那个床震作文 换妻性交真实影片 日本做爱全集 酒色成人网1314 日韩欧洲淫荡视频 7zav gouhemaoxingjiao 国产自拍操逼直播 迷奸技师 花井美纱 真性中出在线播放 萝莉还债视频内个 热热色源20在线观看 让人想不到样子清纯的妹子居然在公园色诱个老头到厕所调教舔逼喝尿吮脚趾看大爷那 骑士影院宅男福利 苹果在线免费看a片 性女传奇 干小妹妹 美女写真摄影视频 真实破处妹子被日哭了 逼里香1 正在草她老公打电话来一边草一边打 风吟鸟唱摄影师嫩模 黄色网站在线视频 欧美裸体模特展示阴部app 欧美番号库 哦快拿大鸡巴操我 mp4 黑人大干金发美女 老司机免费福利AV 捆梆绳模羽洁视频 成人视频 你懂的 操我2 1乱伦强奸图片 淫色戏院 在线超碰天天 先锋AV 现场 sexo 漫话 东方在线αv 群交视频种子 街头射头视频迅雷下载 男同志cartoonyaolp 男人的福利你懂得 免费不卡的亚洲AV 影院在线观看 乖妈姨通叔伯 av大明星97影院 55xxp。て0M 并木优 一周年 穿线资源合集 mandingo 黄可46分钟三邦车视 美女妹妹自慰视频 888kbkb 六月停婷 澳门 人人g 漂亮的小姨h小说叶凡 黄色视频青青草 伦理片工作的女人斩 图片区成人福利 欧美激情 在线观看‘’ 美女内射无码 免费直接看片的网站 窥器美女 清纯援交女偷拍 大胆美丽人体漫画 波多野结衣被内射图片 快播石狮艳照门 成人电影导航qvod 成人大尺度gif 黄色录像强奸片 欧美人体私处摄影 真实夫妻生活 人体艺术照片逼特写 意淫强奸 宅男福利屌丝 � 汤加丽巴巴拉 偸拍骚妇 解说大咪咪女生丝袜 淫荡美骚妇的激情 公媳吸乳奶妈诱惑 WWW_7PO_COM 熟女内田由衣快播 人体艺术性爱小 333kikicom 人妻凌辱 快播网 男女操逼片视频 大鸡吧肏屄里了 少妇内射潮吹 快插我的蜜穴 爱爱快播撸一撸 韩国十八大禁片种子 前黄小学校车迷奸案 欧美肥妞妇乱 亚洲色图 欧美色图 经典三级 大色体 东欧少女 无码 小说 bt 亚洲 论坛 嫩臀骚逼 乱配母导航 红楼十八春tu seseav图片 成人色视频xp 吉吉影音母乳片 岛国色色图片 大鸡鸡插小屁眼水真多 韩国女主播夏娃7部合1部影音先锋 人之初性本善 高级电工证 生活观察网 北京天安妇科医院 中国铝业中州分公司 我的美艳舅妈 志村玲子与黑人图片欣赏 李宗瑞吴亚馨未经处理 网友自拍丝袜足交视频 春暖花开性吧校园春色 日韩美女裸体自拍艺术照 什么都不用下载无毒性片视频 堀北真希无码 涩涩爱综合 人体裸舞 da骚屄 西西妹妹大胆的展阴 冰奇套图种子 www510ccam 韩国色网站 小说交换的妻子最有味 guomobaibi 波多野结快播放器下载 123操b 爱鸡巴的小穴 我轮着干了两个女学生 和多人操逼的感觉 自拍偷拍视频下载 成人裸照无马在克 东京热快播最新成人电影 人兽交视频网址 热点资讯天天网美女人体艺术鳖客网 欧美奶奶15p 黄色少妇天上人间 西西人艺美女肏穴 少妇用卫生带 主角叫小满的乱伦小说 搞女儿被老婆发现15p 亚洲包色图 偷拍江祖平美腿图片 堤莎也加torrent 色尼玛乱伦性爱电影 少妇丝袜在线狠撸 不卡影院27号早间九龙电玩捕 爱主播怎么让主播看不见你 日本av在线sss 免费大片ccc858com 河北传媒北区偷拍 日本av删除删除删 亚洲专区一本道 老汉玩肥婆 东方大鸡巴 天龙淫女传 WWWBET365COM 韩国炮友打炮自拍视频 韩国女主播高清图片全集 骚逼老婆做爱露逼视频 隔壁邻居乱伦做爱小说 极品人妻援交系列套图 人体艺EEcom 苍进空av网址 综合插插a 操妈妈屄15年 日本h彩漫 生物老师被操 性爱自慰碰碰视频 波多野结衣熟女乱伦图 超碰免费视频caopocaowwwblz1000com 日本特级女人无码 家庭乱伦幼幼操逼小说 儿童爱爱网站 幼幼圣光福利 伊伊人妻 AV日日逼 大奶子被干了快播 好吊日AV在线视频19gancom 19isecom色哥哥帝国 模特屄re 淫香五月天 调情网址 优优人体艺术爽图 成人全彩动漫 好屌妞大色网小色网 亚洲欧美制服卡通heshizfucom 老师干儿子淫秽 男生的鸡巴操草你生的蛋裤子黄色视频 五月天激情古典 空姐丝袜大乱11p 免费看欧美黄色大片网站xxx av国语版 被虐家庭女教师 人与兽乱仑 最新里番社区 yyaaVvmagnet 三级黄色添下体 伊人在线视频变身6 wwwpp6scpm 处女草草www 网友自拍seba 520最大胆人体艺术 人妻性爱淫乱 姐弟经典性交thunderftp 泽尻绘理香作品快播qvod百度影 苍井空作品下载网盘 波多野结衣逼器 婶婶的原味内内 我与姐姐乱轮小说 偷拍自拍高潮影院 AV视频色图 华人95偷拍自拍视频 东亚AV 影音先锋熟女少妇 五月天激情亚洲图片区 7777bbcom 沈阳推油 日本A片555影院 欧美36d性爱 图片区偷拍自拍15p 怡春院分站 酒色网 美女 撸撸射秘密爱 yy44bbcomcaoporn29htm 影音先锋av天堂2015 曰本骑大哥操逼自述 亚洲五十路熟女在绒 郑州换妻俱乐部偷拍 撸撸色最新网站 亚洲AV_插插射射 巨乳泽井芽衣在线无码 985bbcon pp494c慰m 人兽性爱欧美三级片 金发天国在线播放1 少妇艺术人体图片优优 9h明星合成裸体网 毛片基地美女图片 鸡巴插小美女淫穴 眼镜少妇参加老外群P聚会有5个黑鬼真正操到爆三洞已爆废 经典千人斩首页wwwiiii41com 米奇第四色骚姐姐 天使社区换成什么平台了 亚洲在线做爱 中文亚洲欧美 35vucom 开心色色自拍偷怕 快播电影日本理论片 美女高跟踩踏图片 偷拍厕所在线 成人撸多宝 在线播放富家女被干 性涩影音app 专业偷窥在线视频 久久精品视频在线看99-百度-百度 美女拷臂动态图 牛牛射在线av ymdd099磁力 校园春色系列小说合集 让你的女友高潮吧 亚洲第一AV天堂网 兰桂坊野战视频种子 做爱漫画小说图片 871kkcm 日本成人图片小说ed2k 韩日撸逼 鸡逼逼在线视频 清纯唯美在线国产亚洲色图美腿丝袜 美穴撸 性交后尾图片 大香蕉伊人萝莉 黄色日逼紧逼医院护十 天天更新欧美性爱日韩AV国内自拍偷拍电影 色色资源最新地址2017 dizhi99妹控 类似于蜜桃影院的网站 李小璐被强奸乱伦 卡戴珊三级 插进射吸爽春 黑丝诱惑亚州性夜夜射 丝袜夫人 类似巨乳淫奴的小说 美女咆轰图 WVW2499 90后美女做爱图片 干死美女电影 刘亦菲阴道毛多吗 欧美视频xxx 最新电影2014sewoyingyin 我和小舅妈的故事 色史中色 av兽 黄网视频 黄色网站电影二级影片 人体艺术toupian 我干美女老师做爱 黄色日批照动态 日本丰满熟女五十路 xxoo无插件 张悠雨房乳特写 水水美妹 原纱央莉大尺度人体 des574 儿子的面前太过美丽的妈妈 操b激情文 美女双穴被奸 福鼎市人民政府 银子变黑 侯镜如 日本逼操图片 丽江美女偷情 偸拍野站视频 做爱大全视频观看 男人添女人乳头 色女16p 女性抠穴图片集 日本女老师的小穴图带毛的 屄最黑女明星 激情漫画套图 百度搜索成人影视小说 翟凌的无码图 mm六月天 台湾美女叫床 女子学校返回途中乱搞6p淫乱大派对02 妺妹林人体艺术 最好的我们神马影院 强奸迷奸轮奸 亚州图色干哥哥 黄片处女破处流血 淫大妈影院 立花20p 舔姐姐咪咪 岩佐あゆみ吉吉语音 长谷川凉子 欧美t0upaizipai 撸小人琪琪影院 幼少女口交 影音先锋幼幼黄色视频 涩涩网影音先锋观看 性感护士15p 得撸小说 小色哥脱衣舞 五月天成人操逼小说 人与动物法国zo0 有关做爱的网页 家庭伦理小说深爱五月wwwcbcb093com 成人美女视频免费wwwlu2310com 莎拉波娃五月天丁香五月 A片毛片免费观看天天干 噜噜色影院噜噜色电影色噜噜影视噜噜色网 索取玛雅最新网址 娇妻被淫记朱茵 色小说综合导航 欧美男女性抽插动图片 我爱咪咪影视网 暴力肛交小萝莉 我淫我浪 螺女挑情四级下载 91porr 大乳大臀美女的性爱15p www点爱人体点com 人兽杂交av电影免费下载下载 美女视频免费播放啪啪百度百度 poco能搜成人片 色妹妹sex 幼童pussy 女生未成年自慰网站 wwwzzjixxxxe 洗濯屋手机在线观看 人人干全免费视频xulawyercn 黄色片做爱后入式 中国伦理电影网站大全 操操曰偷拍上传 WWW唐人电影www69rrrrcom 777sejingwang 大色网不用播放器 视讯主播先锋 kanxxx 日本女人大屄图片 父子乱轮 姐脱你看淫淫 操久国产片 成人Hh漫画 日本人体艺术窝窝妹 韩日女优大奶视频 欧式性爱满足你的欲望【2937】 三级色图网 大尺度性交电影 鬼吹灯第二部有声小说 qq电台有声小说 电台播放有声小说 yuemu春色 vagaa樱井莉亚片子 小泽玛利亚1024800 小泽玛利亚口暴 求可以看的h网 www狗酷音乐com 开心尽情五月天 怎么在快播里看黄片 色狼巴士 性生活时间 征服淫荡少妇 撸时代 额尔撸 看片 magnet 色网站4438oxox 悠悠比资源 大香焦久草是易视 一本道手机高清AⅤ在线2017 香蕉视频app1024 mlgd488云盘 在线自拍大神约酒店 成人 免费 动漫 视频在线观看 超碰在线视频进入离开 杏花社福利成人 免费 动漫 视频在线观看 成人影院和狗 日本骚黄视频 在线白丝裤袜美女 欲望太平洋在线玩 手机看国产短片福利群 谭晓彤脱黑奶罩视频 操逼福利动态影院 百度97 成人自拍淫色 Caoporn任你操 第九影院男人社区A√电影 亚洲系列爱情动作影院 手机成人免费大全 sefuliwng 福立盒子 无毒福利网址大全 桃野铃 yJ丨zZ一Tⅴ 人兽杂交操b视频 桃奶木 淫妻妹 偷拍 自拍 一本道 青娱乐精品视频一级 夜店认识的高挑女白领一起吃饭喝多了,带到酒店趁不注意安放摄像头 澳门金沙大鸡吧操逼视频 人人操 人人妻 1自拍偷拍伦 神马福利小说图片大全 亚洲 偷拍成人视频 萝莉小逼 任你操这里只有精品6 午夜福利理论yy 4480 黑人与人妻中文系列 大佬色在线观看精品 26UUU亚洲一26 国产网红自拍福利视频 蓝沢润黑人在线播放 伊人网综合网站 偷偷摸视屏在线 黄色里番在线看1 弱气乙女 浴室套图 成人影院a在线看网址jajjaatat 开发三味 6无码magnet 飘花网sdde481 五月婷婷在线看 爱泽心梨在线 XRW-498播放 1024东方 SNIS850在线观看 汤姆影av 另类亚洲图片小说在线电影 超碰视频天堂 菲菲影院 东北娇妻土豪视频 大香巨乳家政爱爱在线 大学生兼职 偷拍下载 嗲囡囡在线福利视频tv 女主播朴惠恩福利 xiengjiaoshipin wwwsaobibi5353 打飞机推荐极品高颜值网红美女主播收费房大尺度福利高清无水印打飞机推荐极品高颜 人妻小悠福利在线 王薄团在线观看 色伦理片 穿着内衣做爱操逼的视频 2018仙女屋19禁电影大全 欧美老头av www4438X2com 伊人谷姐干岳电影网 偷拍自慰国产在线视频 94色人格影院第四色 avttt天堂2004 日本狼拍屋 香港皇室伦理电影 网红雅兴视频链接 84ab午夜剧场 桃大桥未久在线 一人一碰操视频 谷露做重 李丽莎福利 青青草成人成人电影 美女视频免费视频 jvid免费视频 正在播放 迪卡侬所有视频全集迅雷 图片区亚洲另类偷拍 欧美有码性爱 gqwuma 欧美中文合集磁力 木村都那迅雷磁力链接 黄色视频555 在线 里番 纯 av列表 岛国丝袜 色欲影视狠狠插 ac无码ac天堂 234hu四虎在线 动漫男人和女人操逼 小萝莉被内射视频 小日本做爱高潮视频 想要零用钱妹妹帮素股结果爽到自行插 性爱互插阴交视频 驯服吴静娴 崩坏之人璃沙 色在线视频综合影院 三邦车在线手机伦理片 熟女AV 视频 日本妞啪啪高清 公公夏夏天强奸未婚媳妇 www5595con 国产自拍白丝 西野翔在线播放叔母 近水楼台先得月 PORN 人妻 二人的春光 麻油拓也 柳岩磁力链接 草包网在钱精彩视频 黄色舔淫视频 超级诱惑 mp4 女主角医院看男友隔着帘子被搞在哪里可以免费在线观看 538国产视频视频无线 泰迪熊rct502在线播放 废柴导航青娱乐 海量无码av play sss 操逼126 4438成人网官网 色男人色天堂旧址 少妇自拍影片 韩日午夜404影院 ntr先锋资源资源 内地av 格影院第四色先锋 春丽成年AV动漫 车模聂子雨 成人3d动漫免费视频播放器 午夜福利第一村 2素人搭讪a片 哥也高色 西川结衣先锋在钱视频 紫禁城轶事哪里能看 成电人影在线电影。欧美图片 色WWW 午夜小视院 男女作爱后插鸡 色日本ww一澳门 xinh4610高清在线播放 黄片91福利 巨乳空姐在线播放 秽色福利小视频 苍老师视频福利 波多野结衣乳交的视频 国产自拍系列 揉捏胸玉兔视频 国产美女做爱视频种子 下载 一本道java高清 78y4 空姐不愿意拍视频被男友强干到高潮的视频 开苞视频迅雷下载 苍井空在线教师2015 haosedaohang 沧州天气4438x 亚洲无码视频下载 坐盗市最新流出电信营业厅女厕TP 亚洲伦理中文字幕总站 gouhemaoxingjiao 北原夏美无码 资源 噜噜色插 中国自拍视频, 上海罗城厕所种子 国产vdio 加朵ai视频资源下载 马配xX女人毛片 美女被黑人操音乐 马贼物语在线全文阅读 精品成人在线 黄页网站变态另类视频 古装爱爱伦理 4438x香蕉伊人 大鸡巴福利 35sao费永久视频 思思久久re免费视频在线观看 黑丝少妇迅雷磁力吧 女主女王sm视频免费专区 黄色性交裸频 华人成人视频 黄色录像真人试看 黄片蜜桃软件下载 黄图男视频 黄色网 下载 狠狠爱不卡天堂网 女王SM阉割 免费露逼网站 shen4club在线观看 dajiji33 美女作妇科检查被色狼医师偷插入肉棒内射 - 线上直播区 - 5278论坛- 我爱78论坛 - 国产av短视 首页—宅男 偷拍自拍福利院 www路bbb990路com sm乐园另类视频手机版 女主播自慰漏奶 国产自拍郑州局长与情人在宾馆 非洲大香蕉高清 在线 视频 激情 最新强奸乱伦中文字幕 关于欧美做爱视频图片 嫩穴鮑女 好xoo在线视频永久免费福利视频 AV国产福利资源 看得清的美国1级毛片 遥望南方的童年ED2K ROSI视频丝袜视频 2o17免费人妻视频 全国最大的网站4438 西瓜影音 男人天生爱风流 91 后背中出在线 李宗瑞1~16在线观完整 怡红院快播大香蕉 狼友成人福利在线 漂母色香 激情小说大奶少妇 美女无码不雅视频 四房播播色播电影bt 欧美口交足交 婷婷激情撸啊撸 女优与黑人的邪恶 屁眼集中营 有没有可以直接看的黄色网站 迷奸我的表妹 嫩苞流水图 我的嫂子是女女 巨乳苍井空人体艺术日本