AngularAir - Migrating to ESLint - RIP TSLint with James Henry

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey what's going on welcome to another episode of angular air i'm your host justin and on today's episode we are going to be talking about eslint and migrating to eslint and a little bit of bye-bye to tslint so figure out what all that means and what we're dealing with let's get into our show we'll say hi to our panelists and then we will meet our guests and we'll get into the content joining us today we've got mike mike what's going on not too much tried to throw you off your game but i'll do that again i have a quick question for you is today's episode by chance brought to us by secret labs i see you got a little bit of adverts going in the back there um no no because i had to buy this chair and and that chair so um but if they want to sponsor sure we can say it is eventually but they got to give us some free product or something right but i guess we can still plug it it's a comfortable chair i like mine what about you yeah what you got one black on black yeah you can't see the logo there it is there we go all right alyssa how's it going wonderful i thought mike was mispronouncing s stream yard by saying secret lab and i was like what is he taught i was so thrown so i understand now thank you for clarifying and uh excited to be here in my boring chair so yeah there you go well that's a good point because streamyard does help us run our our show so we can plug streamyard and be very thankful that they contribute and provide us the opportunity to use their software for our show very awesome all right our guest today we finally have him here james james how's it going hey it's good to be here thank you very much i think this is my second time on but it's been definitely been a few years um and i'm very happy to be back it's great to see you guys as well um obviously in our in our current world of not having developer conferences and stuff in person it's it's been too long so it's great to be here and chat through some linting stuff for sure for sure so you want to uh fill our viewers in a bit about yourself what you got going on that sort of thing for those that might not know you yeah definitely so my name is james i am based in a hotel room which has been has been pointed out to me has a picture on the wall that reflects my screen in the background um and uh i live in the uae at the moment the united arab emirates in the middle east i moved here from toronto in canada um i was working with now all the good folks over there jeff and victor and um i still work with those guys now from this part of the world um i have been working in kind of front end land for for a long time the last few years as a consultant and also working at a digital challenger bank in the uae um but ultimately my i think my natural inclination is to build platforms and tools and empower i like when developers are my users i think i just naturally gravitate towards that use case i love building things for users in general um but i have found that this for some reason there's something extra that that kind of fires me about tooling because i i guess i'm so close to the use case i'm always the target demographic for what i'm making which can often be the case in consumer products as well of course but uh not necessarily always quite in the same way so yeah linting for me started in 20 something with uh yes insulin contributions in javascript with my angularjs code um so probably we're talking 2014 something like that and um i really got into it and i did enough contributions that they invited me onto the team for eslint and uh what i was really passionate about was actually the impending change to angular not having angularjs maybe for that much longer but i felt like there wasn't enough noise being made about the fact that having to move to angular meant typescript of course which even then i was excited about but i was like why is nobody pointing out that the linter has to change that sucks i love eslints this is crazy um so i basically never let it go and i actually my code base that i was writing in angularjs moving to angular i never actually installed cs lint i was i created the first ever tier like typescript an eslint project now at that time it didn't work very well and the support was not very good but i was determined that i was going to dog food whatever i tried nicolas sarkis the creator of eslint um he started a repo which was doing a poc around imagine if not all of eslint stuff had the same asts imagine if you could support a custom ast in the eslint world and then it wouldn't have to use its own default password all the time and he did a poc of basically a giant switch statement that used the typescript compiler to pass a piece of source have the typescript ast which we can cover asts and stuff in in more detail essentially it's a data structure that is used behind the scenes by passers which is a bit more machine readable than what we the plain text that we write when we write our code but basically typescript has a different one of these data structures compared to the past that comes with eslint by default so that's why historically you wouldn't get an automatic combination of those two ecosystems nicholas did a quick prototype of a giant switch statement which basically said if it's this node type on this data structure do this transformation if it's this node type to this transformation and it worked and he did a few node transformations and built them and and there it was and uh it wasn't something where he's he's not he's not a typescript user himself and he's not um uh yeah so basically i i locked onto this straight away and that became my sole focus within the esl context because i had this impending angular migration coming up and i knew that's what i wanted to to work um so yeah just double down on it and i've been working on that kind of problem set ever since in open source land so i created the project called typescript eslints which spun out of that initial project that initial poc and became a fully fledged kind of multi-package toolset which does the transformation of data structures behind the scenes it does uh it creates some plugins which are which are typescript specific rules that you would care about only when you have types and a load of other things related to just kind of transformations testing um and there's also a funky tslin plugin that i created which basically runs a full instance of tslin inside of eslint if you had to keep running tslint rules you could technically kind of wedge them in i wouldn't recommend it it's not very performant but it technically works nice nice so that is that is the whistle stop tour of my linting journey and uh i guess the final stop actually sorry which is why i'm here today is because typescript dslint is focused on generically like how can we support typescript in eslint as tool two tools together um angular eslint was my latest project which layers on top of typescript eslint and adds angular specific stuff because if you think about it um typescript is already a custom file type for eslint but the other important file type we deal with in angular is html and the angular compiler is what takes our html and is able to interpret our banana in a box syntax and all that kind of stuff and actually turn it into another one of these data structures behind scenes and in order to write rules which makes sense for that source code your html we need to have more tooling on top of eslint which allows that to be possible we need to wrap the angular compiler and do stuff to the output so that eslint can give us that feedback and we can write rules based on that data structure that the angular compiler creates behind the scenes and so yeah that's what we're going to cover more in depth today but specifically the angular and eslint combinations but that's that's kind of the pyramid of stacking of tools that gets us to this point nice nice now i know we want to kind of hear a little bit more about what is linting right what are we talking about here but before we do that i want to uh point out that like typescript and the involvement of typescript there you know a little bit about that right you've done some stuff around typescript and some other things right oh that was a tough question we lost him oh no james come back listen justin if you're going to scare off our guests with with your sass and your questions aj i'm sorry i'm sorry i don't know at what point you stopped hearing me i if yeah i mentioned i mentioned the fact that that you know a little bit about typescript uh but i wanted to kind of call out the fact that of your knowledge of that um and have you chance to speak on that it was actually really perfect timing you dropped right after his question and we all thought he defended you deeply so i didn't even hear a question so that worries me that i was still giving a monologue and you missed half of it so what was the last thing you heard from me okay so let me just go recap quick we want to hear about what linting is right but before we get into that i want to call out the fact that we're talking about typescript and and you james know a little bit about typescript i want to kind of see if you can share your experience with that yeah definitely um but what was the last thing you heard from me because i was speaking like non-stop for like five years i swear you pop you pause so i jumped in there with a question so yeah did i say did i say pyramid and stacking of tools did you hear that no yeah oh yeah no i think so you talked about what we're going to talk about today in terms of angular and and how all those angular and yes yeah yeah yeah okay okay that's good it was if you missed anything it was not important so that's good uh yeah so yeah we can definitely we can definitely talk about some typescript bits and pieces as well um but yeah so um i think i can share my screen and kind of walk through a few of these bits and pieces and then folks can ask some questions and um i'm not sure are we is there a is there a youtube chat for this as well and stuff like that or is it um it's like community members yeah and the youtube thing that's actually being pulled in to stream yard so in the comments panel on the i think right of your screen you should be able to see that oh great okay sorry yeah i was some yeah okay so before you jump into sharing your screen and what have you can you just uh start at the highest level and explain what is a linter and then we can explain how you call yourself a front-end man and yet you wrote all of this magic that seemingly feels back-end to alyssa yeah i guess yeah i guess the the front-end piece has always been i've i've always wanted to work on projects where there's been some kind of button or something that you can press ultimately on the on the code that i write usually that's the case there have been some exceptions in my career where i've been contributing to lower level stuff um so eslint has been an accompaniment to some projects which have had user interfaces usually um so i guess that's what i mean that for sure the the great thing about javascript and typescript is the fact that you can write it on the server and the clients and it's been my primary language for a long time i've written a little bit of go in recent years and i started with php but javascript typescript has been my main kind of language that i've been working with for a long time so um yeah i think front end just in the sense of it's been more towards that side of things but yeah it's certainly full if you're like full stack as well yeah um and yeah tooling um as long as it's tooling in that kind of world i like to say i've really enjoyed it um so uh typescript and linters in general so i actually i'm of the opinion that they're incredibly close in what they do so they're i and i write this in the typescript just didn't read me i tried to go on a bit of a journey with folks they're both tools which analyze your source code statically they're looking at the syntax you've written and they're trying to pull out information that could be useful to you now that could be syntactic information so it could just be about the characters you've written in your document or it could be semantic information something about the combination of characters that has a meaning in the context in the language um and with typescript um you can think about it basically as as a more powerful linter if you like because it performs a compilation and there's a context for that compilation with lots of files in it and how those files relate to each other how they bring in code from one another is all known to typescript and so it can give you that information about things that are more than just the syntax you write so they're both ultimately tools which pass your code from a human readable format into a machine understandable format called an ast an abstract syntax tree it's just a data structure a giant object and when it has that giant object it can do things with it so it can you can write rules both in typescript if you like kind of rules not not as not quite as pluggable but in typescript you can write checks based on that data structure and in eslint you can write rules which operate on that data structure as well and if you ever want to look at maybe i'll start showing my screen now just to help illustrate some of these things i'm talking about so it's my first time showing on stream yard hopefully it goes well uh it's warning me about all kinds of things yolo press the button share your entire screen yolo again um yeah i better share my whole screen i guess if that's cool with folks um but i'll i'll come into ast explorer.net is the is the uh the site i wanted to go on to so if you're ever wanting to get into asts a bit more uh you'll you'll have to inform me on the zoom level here i'll just type some text that right here looks good yeah i think that's good right there yeah the option the menu might become a little harder to navigate so if i go on javascript as the main kind of bucket of tooling that i care about i've got an empty code editor on the left and my data structure gets put into the right hand side so that's really cool so within javascript as a designation i can choose from different tools and you might be familiar with some of these from the javascript ecosystem we've got things coming from babel acorn is used in uh i think webpack still uses acorn for example esprit is the default parser that's built into eslint uh flow you might have heard of from facebook as an alternative to typescript for some static types uh checking stuff and typescript compiler is in here as well as well as the password that i created types with these link parser um so there's a lot of different options um so if i go on the type if i go pick the typescript compiler for example and i write some source code if i write it correctly um we'll get some syntax highlighting so i'll just do const t equals true here i have a basically a giant object i can represent it as pure json if i want so this is pure json data structure this is my ast for my program over here for my source code and the tree view is just basically a really nice thing that the creative ast explorer made so you can kind of more interactively jump around and control this data structure if you need to it's tied up to the code so if i click on a particular piece of code it will jump around to the relevant part of the of the data structure which is really nice so if i go on true here you can see it's jumped me to this true keyword initializer so this property initializer exists on the parent node which is a variable declaration our variable declaration here and um so this is a good way to learn about all of these different nodes and stuff that exist on this ast which power a lot of the tools that you know and love like these bundlers and builders like webpack and parcel etc you've got linters you've got type checkers like typescript ultimately they're all using asts behind the scenes and passes to create those asts so that's the the kind of entry of uh these data structures which power everything and if we look at angular eslint for example um i have it open in spikes for some reason my github uh assets are not loading properly in brave um if i go in here if i go into one of these packages that we produced in angular eslint if we go into the plugin so this is a classic eslint plugin that has been created by us for the community to use you'll notice if i go on a rule definition the rules operate based on returning an object which contains um keys and like keys and values obviously and the key is a selector for a node type on that ast unfortunately i picked a bad example because there's no string there what would be a good example where forward ref maybe okay so yeah so you can compose these kind of gnarly almost css selector type things but you might recognize that this is kind of like a reference to that data structure in this particular case we're looking at a call expression so we're going to be dealing with some kind of function here so i just type in no forward ref into here no forward ref now so here you can see i've got my call expression so that is already telling me this is this is this is making sense for that rule definition within my call expression i have an expression property which points to identifier like how the extent to which you memorize these data structures is obviously nobody does it intentionally sometimes you end up accidentally memorizing these things because you just work on them too much but yeah but don't don't feel too intimidated by these structures um because ultimately um you can always kind of log them out and when you're writing these rules and stuff like that asc explorer does actually provide you with an interactive way to write these rules as well i'm afraid i'm not super familiar with how that works but you can basically enable like the eslint transform in here and start writing rules directly in this user interface but i won't demo that because i wouldn't do it just this but here you can see we're trying to identify a call expression that where the callee type is identifier and the callee name is forward ref because that's being referenced here um so i i i called my function uh no forward which made no sense we're looking for no forward ref is what we're looking for the rule is called no forward ref because it's it's being banned by that rule um but here you here you can see the power that eslint gives you and this is kind of unique to eslint as well this is a difference between eslint and tslint so tslint is obviously a linter as well and it's it's also dealing with statically analyzing your code um the passing step is very very similar it's passing it into an ast but what's called the traversal step which is how do you navigate up and down that object to find different bits and pieces of it that's actually very different between the two two tools i personally am a big fan of the way it's done in eslint because you you can write these very expressive selector statements they're called so they they remind me a lot of css selectors but they're called selectors there's a library inside of eslint that runs to make to understand what this what this means and turn it into some instructions when it's iterating through that object and basically i just say eslint let me know when you hit a node on that tree that makes that that fulfills this pattern and when it does this function will be invoked and in this case the rule couldn't be simpler it's just trying to ban the use of that function so i just need to tell eslint that there was an error there was a message i need to report to the user if that even exists if it didn't exist this function would never be called because that's all i'm telling it to do is call me in this case this is as basic as lint rules get now obviously they can get a lot more complicated than that you can have rules that care about multiple different types of of points on that object and you can have lots of conditional checks within them like if this thing exists it also needs to have this this and this otherwise it's invalid etc so you can imagine how these things kind of scale up but this is the most basic example of a rule you you return this create method that eslint will call for you with a context and then from that create method you return an object that contains something to match against part of that data structure and then a function that will be invoked if that exists in your source code so that's not exactly how typescript works behind the scenes but it's kind of the same some of the same concepts apply as well yep so like when we talk about like tslint if i had a custom rule in tslint i could write some helper code that helps me navigate the tree in a similar fashion right but i would be writing that for my own rule and then sharing it among my rules whereas in eslint it comes out of the box this built-in way to make it easier so now i don't have to have that code on my end to traverse the tree i can see some stuff out of the box to do this in a much more lightweight uh and approachable manner exactly yeah so a lot of the time if you rewrite a rule that was written for ts lint in eslint a lot of the a lot of the kind of the the traversal logic disappears because yeah as you say in a ts rule you had to say visit this node on the graph or visit this node on the under the ast and you had to write the logic which traversed the ast to find the thing you cared about whereas we get to express it all nice and tersely and succinctly in this um in this selector dsl if you like um so yeah that's that's um that's how the ast becomes relevant is the rules are written not based on find this string it's not like string matching in in an overall bigger string of your source code the source code by eslint by a parser has already been turned into that ast data structure that we've seen on um astexplorer.net it's already been turned into this structure so in the case of um in the case of what we're talking about here it's typescript.eslintparser that is passing this code so this is the exact kind of data structure that will be returned this call expression we've seen the call e we've seen the type is identifier and the name is forward ref so that's exactly sorry i keep going to the wrong thing that's exactly what we've written here um so that's how it gets identified in that data structure so if you're if you want if you want to take on the challenge of writing custom rules and stuff ast explorer.net is invaluable it's such a useful tool and the guy i think is felix's name the guy that created it is has been a huge asset to the to every community as you can see so many different things are supported um one interesting thing for me on angular eslint as i mentioned that use case that we have of wanting to support html if i come in to select html from the top level drop-down within html i can choose the angular compiler as my parser to to interpret my html as you can see we've actually already added the angular sling template parser that's built on top of the angular compiler as well but the angular 1 here so if i type in something that's angular specific um like div and some kind of binding so if i do it's true with so it doesn't matter this is entirely valid because the angular compiler is still going to pass it but if we have this as valid html that the angular compiler cares about you can see that this has created an ast which it doesn't look exactly the same as the code ast that we had before but it's still kind of recognizable that there are nodes that there are objects with attributes with with props with whatever you want to call them with properties that points to other nodes that have certain characteristics that are specific to that type of node so here we're dealing with a bound attribute that's what the angular team has called it inside their ast representation that they work with and we're binding to foo so that's our name of our bound attribute so this is naturally not an area where the angular team is is necessarily supporting the use the the community as a first part like a first class use case um so for me to find out what these nodes were called and stuff i just literally had to console log every ast that came through for every bit of source code until i figured out oh this is how they do location information oh this is what this thing is called um so yeah there's no it seems kind of magical at the end but it was just go through console log go through console log maybe debug it every now and again but yeah just very much just figure it out by uh the most basic means possible and then once i figured out those pieces i could come into angular eslint and i could build a parser that's so what's what's called a custom parser for eslint because because they created this ability to provide your own parser instead of the one that comes out of the box esprit um or esprit oh we say i've only ever seen it written down um we need to have a custom parser which wraps the angular compiler and just does a few things to make the eslint system understand it so that traversal logic i mentioned so the template parser is actually kind of small which is nice it's not too much to maintain over and above the angular compiler is it zoomed in enough by the way on the github view i think a little more would be probably ideal if you could yeah cool perfect thank you cool so uh yeah so we're bringing in the key thing is this past template function from the angular compiler that's doing all the heavy lifting of actually doing that logic to say this is my source code a string of my source code give me an ast back please that's doing all that heavy lifting and then the other stuff you see in this file is basically all the stuff i've written around it to make it make sense for eslint and the key thing about this is what's called visitor keys so you might recognize some of these things from the ast we were just looking at basically because we provided a custom parser that's dealing with a custom data structure a custom ast that eslint knows nothing about we also need to teach it how to traverse that tree because it also doesn't know how to traverse any of it so if we write a nice selector for a template rule it'll be like cool i've never seen that before i'll never call your function because i don't know how to reach the selector string you've created so for us if we want to say write a rule which disallows the word foo to exist in a bound attribute in an angular template we could do that but if we tried to compose it just using the angular compiler eslint would never traverse to that location it wouldn't know how to take the top level string of this code here and he wouldn't know how to dive into this data structure so that's what a lot of this logic is doing and the visitor keys is basically a way of teaching eslint we have a thing we have a node called an ast with source and it has an ast property please traverse into that property for me we have a thing called binary please traverse into left and right we have bound attribute please traverse into value etc etc as you can see some of these nodes have multiple properties on them that we want eslint to traverse into and these different properties here can point at each other in the actual ast so if i go back to the real ast here you can see we have an element uh uh actually sorry i'll go into the um i'll go into the angular eslintified version just because it's even more straightforward to follow um so our template nodes here we have a bound attribute bound attribute has a value value is pointing at another node with a type of literal primitive and so because we've informed uh eslint how to traverse into a bound attribute that we want to uh traverse into its value we've said if you find a bound attribute please traverse into its value we've gone as far as we need to with that type of node on the ast for eslint to find all the things we care about because it's only the value of a bound attribute that you could possibly want to care about whereas with an element we need to traverse into all of these things so with our top level element we have there the div elements at the top we need to traverse into attributes okay in this case we don't have any but we've got an input we've got an input which is our bound attribute so we've told eslint when you find an element please traverse into inputs oh that input is a bound attribute please traverse into value oh that value is an ast with source when you hit ast with source please traverse into ast and so that's how you end up reaching kind of the bottom of that branch of the tree that you care about all without having eslint having to kind of truly understand that that data structure we give it what's called visitor keys to provide it with a kind of a roadmap of how to get there i like that map analogy so basically angular is creating the map and what you've done is told the eslant how to navigate that map exactly exactly it would be totally he wouldn't be able to navigate it at all he would hit the top level of the the tree and be like cool i don't recognize any of these properties on this top level object i'll stop there so you were like building this out and it would like stop there did it silently fail or did it give you some sort of fee like how did you because you were talking about if you don't have those exact keys to match it it's not going to know about it does it just go about its day and you're like none the wiser well fortunately fortunately it was basically a case of just building this this map over time as i hit the use cases so initially my visit to keys was very small because it was just a case of okay i have the use case of either creating a new rule or converting a codalyzer rule so i know i need to have a lint rule which passes these unit tests to give me these errors in these cases and so it was basically just a case of okay i have this source code for example codalyzer like minko's project codalyzer has been invaluable for um all of this is it codalyzer.com um so uh minko created this way before he joined the angular team and it's it's a collection of tslint rules which are specific to angular stuff um and these rules um already existed obviously as a project on github which meant that even though they're written for ts lintz they have a series of um if i just go on sorry i'll need to zoom in again um they have a series of unit tests obviously associated with those rules so i could grab let's say contextual decorator rule i'll zoom in a bit um i could grab these tests and i know that for this source code we're expecting a particular type of error so i can build my eslint equivalent rule knowing that i have this source code so what i would do is literally just take the source code put it into ast explorer and in this case it's source code not html but i would paste it into xt explorer so i had the ast ready uh just the pure angular compiler level and then i would come into my eslint rule and figure out okay for this bits of the angular ast which bits do i need to assert that rule failure so which one if i care about the angular class decorator injectable i need to somehow traverse in this case it's a code rule so this is less sorry this is less applicable it's more with html based uh rules i can't remember where in codalyzer there's a template there we go so yeah this is more relevant apologies uh the code one is is is the the dsl in parser use case but if we think about templates if i need to assert a behavior on an image tag here um for this uh source code i know i need to be doing something with with an element in that ast and if we go further these these are all to do with elements actually but um if we do banana in a box that's the classic one if you have you got your your brackets and your parentheses the right way around for this source code i know i need to error on this bit so what does this bit mean in the ast when i started i genuinely didn't know and so not only did i not know eslint didn't know because i hadn't told it yet by creating the visitor keys so what i would do is just copy and paste the source code put it into asd explorer oops i just saved it nevermind um copy paste the source code so come in here okay bound event cool have i got bound event in my visitor keys yet oh no i don't okay i'll add it into my visitor keys within the bound event what children here do i need to care about well handler looks important so maybe i need to traverse into handler so i'll come into bound event and i'll add handler it was literally just a case of building it up use case by use case rule by rule that i was creating until i have this structure now and this might not be fully complete or it might be the case that the angular team adds to their ast over time they might create new syntax so they might create new stuff which we can leverage and that might correspondingly require an update in the visitor keys but for now and for a while this has been the structure that we've had in master and that's that's what we've got hopefully that answered the question it was trial and error use case by use case i have a question so you basically laid all the groundwork for us to be able to write linting rules against angular templates which is awesome uh they wrote the publisher to be able to get template into ast you wrote the transforms basically to allow eslint to traverse that tree so that we can write rules based off of that yeah that's correct and you took us through this great history of what you did and it's phenomenal and thank you thank you thank you thank you for the next two day two days trick um can we pop up a level because we've got about 20 minutes left uh because i like the inner workings and how all this is all put together can we talk a little bit more about the types of rules that we can write and what this empowers absolutely um if we want if we want we can also zoom out even further and talk about how this might get executed in your angular cli projects as well um but i have one question before you do can you go back to i think your editor where you had the lint rule that you had created uh yeah i was throwing it in github i think actually um so if i go into instead of uh temp so do you want a a a template plug-in and uh sorry an html rule or the actual um lint rule that you had created that was looking for a call expression for the photograph okay yeah so that's a code rule so that's using the typescript dsln parser in here rather than the angular compiler but if i come into rules in here um so we've got no forward rest somewhere there we go so in there uh when you scroll on line 28 there is that the whole thing and you kind of glanced over this but i want to dig a little bit deeper into that where you mentioned it looks a lot like css can we talk about what's running that and therefore how we would we construct one of those on our own yeah so this is this is called a selector um and so i think i like to they're very similar to kind of css selectors you might have in um for like targeting an attribute with a particular start in in your style sheets yes beginning would kind of be like div or button as the tag name yeah exactly some properties yeah well you might you might do something for example you might gray something out on disabled attribute being set so it's the same kind of syntax that you would use in your style sheets for that yeah um so this is being interpreted by a library that runs inside of eslint and it's maintained by the eslint team i believe um and because you've asked me i now instantly can't remember what it's called is it yes is it yes query there you go yes exactly you crafty man asking me a question you know the answer to and i don't um so yeah yes free i find it very fascinating and helpful for these things um yeah so i've played with ts query um which is based off of that library so yeah exactly you continue exactly yeah so esquery has been around i'm not sure if it was created exclusively for yesterday i'm afraid i'm just not sure on the history there but yeah it's certainly it's a key enabler of this of this use case so yeah yes query is responsible for interpreting this statement and turning it into the knowledge of when the tree is being actually traversed where should we stop and where should we call somebody's function that they've defined in their rule and um yeah so that's um that's uh eslint has a few different libraries within its ecosystem that powers it it's not just one uh one package as such but um it's it's a fairly small uh overall in terms of the number of different packages that go inside of the essence itself but yeah yes query is a key one for sure because it unlocks this this power of just invoke my stuff when you when you find it i i won't traverse the tree myself and yeah so it's all open source as well as you said both esquery and ts query if you need to uh traverse the typescript ast that's exactly what so as i mentioned typescript and the esl ecosystems have different data structures that they represent the same source code with so ts query is er is the version for traversing a typescript specific ast that was produced by the typescript compiler um if you need that for any use cases you have um that's um yeah it's also available so yeah so is that is uh does that answer your question on the on the selector statements would you like me to speak a little bit about invocation and it does you answer you definitely answer the question uh my other follow-up question is with tslent essentially going away and eslint replacing that will does the es query traverse asts from typescript and also from angular or is it another tool that another query tool had to be created uh so yes query came first uh ts query was created by being inspired by esquery um and uh so yeah it's it's t-square is not not relevant for this use case because even though we're taking typescript source code the typescript eslint project that i created is responsible for taking that typescript source code and turning it into an ast that eslint better understands so we've we've actually focused on the template use case here so this is sorry it's potentially a little bit confusing the the template ast is entirely foreign to eslint it's just completely different it knows nothing about it whereas the tooling on the typescript side is actually sorry back to javascript here if i write some codes in here if i say const t equals true as i wrote before um the if i go on esprit so this is if you only had this is pure javascript code this is no typescript involved here this is the ast that eslint would produce just in vanilla js land for this source code so it has a program at the top and it has a body with a variable declaration inside variable declaration has declarations a variable declarator etc that same source code which is pure javascript if the typescript compiler passes it you can see we've actually got a different structure here we have a source file with statements and a statement is a variable statement which has a declaration list rather than declarations variable declaration list so even though it's exactly the same source code there's a different way of representing it for the tooling internally and so the typescript eslint is kind of the in between of those two uh there's two it's a bridge between the two worlds so because we could contain any kind of custom typescript code in here we have this bridge world so typescript eslintparser when you do that one you can see now we're suddenly back to looking exactly like the eslint spree one was originally we've got a program we've got body variable declaration declarations so it's the same as just esprit would have been but the big difference is if i add something here which is typescript specific it will still work whereas if i do that with this spree the default pass from eslint it's not going to like the fact that we've got a colon in there because that's not valid javascript so with typescript jslintparser what we do is we have the entirely standard what's called es3 the one that is most compatible with that ecosystem as much as we can whenever it's just javascript concerns but then when we do have a typescript specific one we add to that ast so you can see we've got this thing called the type annotation property on this identifier identifier is a standard node in javascript asts from from that ecosystem type annotation is a non-standard thing which we've added on it's written in an extension to the spec for this ecosystem and then we've invented the concept of a ts type annotation node so this is where typescript eslint parser has to add on to stuff which is so es would know by default i can traverse a program into a variable declaration into a declaration it knows all of this stuff it doesn't know anything about this part so it's more subtle in the typescript area we have to teach the eso default logic with es query to be able to do its default logic plus plus plus some extra traversal into these extra nodes that we we've added on to the ast so it's similar similar kind of problem area to solve um but it's uh it's a lot of what we did in typescript eslint is about making it as close to javascript asts as possible because then rules which have been written to work on javascript if you think about a classic rule from eslint semi do i want semicolons or not that is not really relevant whether you're doing ts or js that should work the same it's do i need a semicolon at the end of my statement or not and if we make the ast nearly identical it means that rules like semi just work and that was the big advantage and that's that's the reason why ts link was deprecated because you might be thinking this is a lot of complexity a lot of tools we're have like smashing together to make this possible the big upside and the reason why this has happened is because it unlocks the typescript ecosystem has access now to all of the community rules that were written for generic typescript sorry generic javascript concerns stuff that is not specific to typescript in the last few years tslint basically had to re-implement every single one of the rules that had already been written for eslint for javascript concerns that had nothing to do with typescript just like semi just like um stuff to do with casing if i want to if i want to have pascal case when i write certain things whatever all of those kind of rules had to be you had they had to reinvent the same exact user feedback just for the for the the typescript ast whereas in this state we can benefit from the existing rules and write new rules based on the additional information in that data structure this has been way way more intense on asts and data structures than i anticipated so apologies if um if some of it's not entirely clear um but yeah as i say i i recommend astexplorer.net even if you don't plan on writing any lint rules it might just help you understand maybe how they how they get written um if you don't mind just very quickly i'll cover the so we've covered one really important part of angular slint which is it provides a template parser so that um the angular compiler and the templates can be used in eslint it provides two plugins one for writing source code assertions based on our on our component classes for example our services that kind of stuff and one for html templates based rules against that ast we covered at length it also provides a builder because with if we with our angular cli projects if i just go in and zoom in here um this is a this is a a brand new angular cli project obviously we have tslins out of the box which means in our angular.json what's wired up is what's called a builder for ts lint so this angular dev kit build angular browser is a builder for building but we have a target in here called lint somewhere down here and this builder is angular dev kit builder angular tslint so behind the scenes this is wrapping a ts lint invocation for you and looking at your tslink config to run tslint when you run your linting process so obviously to make it work with eslint we need a new one of these in order to even execute eslint when you run ng-lint and so that's what this builder does it wraps eslint instead of tslent to make that available for you and if you follow the readme in angular island you'll learn both how to create a new workspace with only eslint and also migrate your existing tslint constructs so i have an existing repo in here as well which i created and ran with the custom angular ear slint stuff so as you can see it's removed the ts lint file for me and it's created an eslint rc.json for me the other thing it's done is it's wired up that builder for me in my uh my config somewhere lint so you can see it's wired up angular eslint builder lint and this is wrapping eslint behind the scenes so now when i run ng-lint and this gets invoked it's going to invoke that builder from angular slint instead of the the ts link one um so this was just generated using the schematics from angular eslint using that readme so that's that's how the linting actually gets invoked uh when you run ng-lint it's by it looks it up in your angularjson and figures out oh i need to run this builder and it's coming from this community project angular islint uh finally as i mentioned briefly there schematics is the other big thing that we provide so we provide a schematic to set up your repo in this way if you've got a new repo or we provide some schematics for converting an existing project um so if you're interested in learning about schematics these are obviously some open source ones you can take a look at as well really useful for changing anything about your source code or generating new source code that's what schematics are really good for um so we have if you have a few different ones the one the one of the kind of nice extensibility points we leverage is that we update the default collection of schematics behind the scenes when you run ng-generate you're invoking the default collection of schematics that exist in the angular cli and by setting it to our own collection here um what we've done is we've allowed we've allowed ourselves to kind of get in between you and the cli and so we can say if you want to generate an app in your workspace and you generate app we can say okay we'll invoke the standard app schematic so that we give you exactly what the angular cli would have given you itself but we can cleverly tweak what it's given you to add in that eslint rc.json file we can add in that builder configuration for you so that extensibility point from the angular team allows us to give you the same kind of power you get out the box with the angular cli but give you specifically what you need for eslint instead of tslint um i have a few questions um the maintenance of this repo the angular eslint repo is that something that is going to be um maintained by open source is that something that's potentially going to be adopted inside of the angular namespace or is that onshore at this time uh we we did discuss it um with the angular team uh we being me um and uh we went back and forth a little bit um the official stance as of now and i i don't think this is going to change again is that the angular team is going to view linting a bit like they view deployment so you know right now um there isn't uh the concept of a deploy target by default in the in the tool set that they generate for you but there's a load of tooling that you can ng add to your workspace the angular team has helped promote some of the kind of community deployment builders that are out there for microsoft azure the cell that kind of stuff and so linting they're going to class in the same way so from i believe the plan is from version 12 they won't generate ts lint stuff out of the box at all so we won't need to remove it for you and so you will just generate the project and then ng add and get it yes lint per the instructions in the readme and that's how it will be added so yes it will be maintained as a community project um as you mentioned there kind of the the work that went in was around facilitating people to be able to write rules and write assertions a lot of that is done um and it's yeah most almost all of that is done i would say it's just if the angular team changes something about the ast obviously some of those structures might need to change um but apart from that the main the main ongoing maintenance is just improving documentation for rules adding new rules adding new features to rules for example configuration flags um so hopefully it's not it's not too intensive as a maintenance overhead i would say okay and then i i'm just monopolizing all the question time it's okay everybody else uh my other question is because this is impactful to a lot of people do you know anything in terms of the plans of integration of this uh limb partisan of the templates to the angular language service so the angular language service doesn't need that interim step the angular language service also uses their parser so they can understand things in an ast i'm not super familiar with exactly how the any kind of assertions or checks from the language service get written to be honest i haven't looked at that project um but they wouldn't need any of the ast um transformation or the visitor key stuff they'll have their own way of applying logic to that ast once it's been created okay yeah so it's it's like it's it's just two different approaches in the same way that the typescript language service that you get your feedback your squiggly lines from ts code in evs codes doesn't also doesn't need any of the the typescript eslint stuff either it's got assertions written on the typescript bst directly that it that the team there maintains so it's just yeah this is just tooling that's required for combining the stuff with with eslint specifically yeah i would just think it would be helpful to be able to get this similar feedback of rules that maybe custom rules for both the language service at dev time versus also the build time that you're getting here as well oh yeah so so one important thing is that the like as well as the rules of the generic ecosystem we benefit from we also benefit from all the ide plugins as well so the standard vs code eslint uh extension that you get with vs codes that will show you highlighting in your templates because well you you i've got some instructions in the readme there's potentially some tweaks that you need to make to the settings um i think for vs code specifically um yes so you you need to you need to let vs code know because by default it wouldn't check your html files it assumes that eslint doesn't care about html so you just need to tell vs code in your vs code settings make eslint care about html files but apart from that everything just works in the same way so you get your red squiggly lines in the editor at author time in the way that you expect from these rules just like you would from the language service so they could they can both be running on your html files and both give you feedback for different assertions i love it and eslint supports fix as well is that correct okay so then exactly that's another generic mechanism that we get to take advantage of automatically um which is really nice yeah so i think to take that a little further and provide inspiration is that you're talking about like you know the language service and it giving you the squigglies and you say like i want to add my custom stuff around angular for my project that gives me that power inside the ide of the editors you can use eslint to do that and then you can use the fix scenario to be able to essentially have the editor be able to say you can fix this go ahead and do it and so you can get not only just identification with squigglies but also fix implementation on the fly right there as well yeah and uh to be honest on template rules there's probably some fixes that could be written so that's another thing about like maintaining this project that could be an enhancement there's probably some template rules specifically that don't yet have automated fixes for them that potentially could obviously not every single eslint rule that could ever be written has a fixer that can apply sometimes it's it's you flag it up to the developer and the developer has to make a choice you can only write a fixer when there's one solution to a to an error that comes up um and sometimes with templates it's that's the case but that would be a great contribution for a community member for example if they wanted to go in and see oh i'd love an auto fix for this i think we have one for banana in a box i was going to give that as an example but i think we do have an auto fix for banana in a box it'll swap the brackets around for you but if there's other equivalents where you use the rule and you're like i wish this fixed it it's the same thing every time that would be a great contribution to an existing rule it's just a case of we looked at the rule the rule definition it's just a case of returning a fixer um from that rule so we'll find one in here so here you go use pipe transform interface this one does have a fixer and so the way it's defined as well as reporting the error like we saw before we can provide a fixed property on the report which receives a fixer from eslint and then we can apply the fix to the source code and we've got another utility function clearly down there somewhere um but yeah so that's that's how auto fixing work is instead of just returning a message id that says trigger this error we also return a fixer in here or a fix implementation so that's how that would work nice well hey i know we're at the top of the hour so you got to go so we better wrap it up here uh but uh yeah any last comments or anything that you want to share on this or uh thank you for having me thank you for indulging me talking about stuff which most people often kind of they they breeze past oh yeah i need this thing to work with this thing just do it this uh there's a lot there's a lot of moving pieces that i kind of i find them interesting anyway and it's very interesting to uh to cover them and think about how they how these different tools fit together because half the tools i mentioned on this call that i listed in asdexplorer.net for example i'm a user of but i have never contributed to and that's a balance that always exists with all of us we're always consuming more than we're producing but it helps me appreciate how they some of them might work and how some of them probably fit together by just looking at things like ast explorer and and the nuts and bolts of linting it's yeah it's so i would say even if you don't have much interest in writing rules or anything this could be interesting for you to understand how some of the tools in your package json fit together and feel free to open any discussions or issues i've enabled discussion specifically on angular eslint now as well so if you want to talk through any of these points feel free to open a discussion on that repo and i'll get back to you on there and contributions more than welcome um docs for rules for example that already exist or fixes as we mentioned um yeah it's it's it's post v1 now we're nice and stable it's only when they'll be breaking changes that we need to adapt um but there's always more that can be done and we can we can make things better documented for everybody when we learn things and so yeah thank you very much awesome awesome well hey james thanks a ton for uh coming back on uh we always enjoy having you here i enjoy learning from you and hearing and you sharing your time and your knowledge super thankful so thanks a lot thank you very much and awesome hi everybody we need to also need a giant thank you from the entire angular community because tooling like this will just make our lives as angular developers easier yeah there were thank yous in the chat james so we appreciate you so much thank you apologies i was sharing my screen for so long i couldn't keep up with the chat hopefully i can review it after the fact awesome all right well thanks that's a wrap everyone have a good one catch you next time bye bye
Info
Channel: AngularAir
Views: 794
Rating: 5 out of 5
Keywords:
Id: ZxEnQqGeCXY
Channel Id: undefined
Length: 58min 26sec (3506 seconds)
Published: Fri Feb 05 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.