 In the latest release of the SharePoint Framework version 1.15, Microsoft ditched TS Lint in favor of ES Lint. And while this is a big improvement and a step in the right direction, I think that Microsoft might have gone a little overboard as they added a ton of additional linting rules that we didn't have to deal with before. The point of this video is to see how to cope with some of the common ES Lint rules that you're going to likely encounter when you migrate your existing SharePoint Framework projects over to the latest version 1.15 of the SharePoint Framework. I'll show you how to understand what a linting error is telling you how to change your code or how to ignore the rule throughout your projects. But there's one more thing that I want to do during this video. As I said, I think that Microsoft went a little overboard with these rules with respect to ES Lint. And while I like ES Lint, what I don't like is that every single default project that I create now with the SharePoint Framework or any tool for that matter is now going to impose any coding rules on me that are entirely subjective. I'd prefer if the rules that they did include were scaled back and more minimal. And let me add the rules that I want to add for my organization's coding standards. Because right now, you either have to change how you like to write your code and your standard practices at your organization or you're going to have to edit every single project that you create to use these new default rules. And personally, I don't like this. So this will be how my opinionated how to use ES Lint in your SharePoint Framework projects is going to come across. Hey, I'm Andrew Connell. This episode is also available as a blog post on Voitanus.io and as a podcast on Voitanus.show. Check out the description below the video for links to these other resources. Hey, I'm Andrew. And if you're new here, subscribe to get notified of future videos for professional developers on Microsoft 365 and Microsoft Azure Topics. Let me show you what I'm going to start with here. So I've got a project that I have in my SharePoint Framework course that demonstrates how to use React hooks in a SharePoint Framework project. And so what this one's doing here, this is all written with 1.14. So what I did is I created a copy of this or created a brand new project that's going to do the same thing, but I'm doing it using the SharePoint Framework version 1.15. So what I want to show you here is let me jump over to a tool that I have that's doing a diff between the two projects. So we can see how much of a difference there is between these two projects. For the most part, there's not a whole lot. We did see things like this TS Lint JSON file. This has been deleted from 1.14. So you can see up here where it shows the 1.14 version on the left side and on the right side, that's where it's using the 1.15 version over here. So we can see that this TS Lint JSON file only exists in the 1.14 project. What we do have those, we have this new file called the eslintrc.js file. And that's going to be in the root of our project. And you can see that this is set up here to go ahead and load in some stuff on our project out of the box. So it's just setting a couple of little things. We'll come back and look at that in a second. One of the other changes that we see here that's big with this version of the, from going from 1.14 to 1.15 is you'll notice that there's nothing really much in the dependencies here because that's all really coming from the different version, from going from one version to the next version of the SharePoint framework. So a couple of little minor things change there, like a little bit of React stuff, a little bit from 1.12 to 1.14, a couple of different versions of the project there. But what is interesting here is you'll see that we have a couple changes here, specifically these three that you see that are listed. And then there's another one on line 33 where we've got a eslint config package. We've got a plug-ins for SPFX and a configuration for SPFX. Notice that two of those are coming from the Microsoft scope and one of them is coming from the Rush stack scope. Rush is a tool that Microsoft uses to handle the entire build tool chain for the SharePoint framework, but they do it for a lot of other stuff. So Microsoft has taken a dependency or the SharePoint framework team has taken a dependency on this tool called Rush that we use in the SharePoint framework. And so you're going to see a bunch of the rules are coming from rules that they define. And then furthermore, we also have this React hooks extension as well, our plug-in that's added in for eslint. So to start off really quick, what I want to do is let's come over to our project and let's go into that cswp of 1.14. And I want to make sure that I'm using the correct version of Node. In this case here, I'm using 16, so I'm going to switch it over to use version 14. I use a tool called the Node Version Manager and allows me to have different versions of Node installed. This one I know has got the right version of Node. In this case, you can see it's version 14.19.3. So what I'm going to be able to do with this is we take a look at the project. I've already downloaded all of the NPM packages. So I'm just going to say Gulp Build. And what this is going to do is it's going to build the project, but it's also going to run the entire linting process as well. So let's see what it looked like when we had TSlint on a project that didn't have any issues with it. Okay, so we can see that the TSlint task started. We see it use TSlint 5.12 and we see that it finished right here after about five seconds. No issues were reported. So we're in pretty good shape right here. We don't have to worry about too much. Now let's switch this up. Let's go back and all I did was take the exact same project, right? If I come back over here and I look at the source folder, you can see that what changes have I done to this project? Well, the only thing if we look at the TypeScript file for the web part itself, you can see that there's really nothing here. There's this read-only theme that was added by Microsoft for a lot of the theming stuff that they added. That came from 1.14, I think. And then they've also added in an onInit method that you see here as well. So those are two things that were added to 1.15 that we didn't have in the older version of the project here. But for the most part, it's basically the same thing. You can see I'm importing some references here. Those aren't listed here because I have them listed actually down here, which are mirroring these two lines. Okay, so let's now see what like the default like linting errors that we're going to see from our project. So let me jump back and go to the 1.15 version of this project. I need to also switch over to the version of node 16 that this project was built with. So latest and greatest. All right, cool. So let's start over with this and let's make sure we've got our node modules already installed for this one as well. So I'll say gulp build. Now let's see what we get from this out of the box. All right, so you can see we got a handful of errors that pop up. So if I scroll back, let's just to confirm that we're using ESLint. We can see we're starting our linting task and we're using ESLint version 8.7, which is a fairly current version. And we get a bunch of linting errors that show up, but then it shows up at the very end. It's going to list all those out as well. So if I open this up a little bit, a little bit easier to read these with the, if they're all on one line. So we got a couple of things like no explicit any. So we can't use an any type. It says we have to specify a different type. We'll look at it in a second. Consistent type assertions. Couple of things here. We also got this JSX no bind. We've got no unused variables. JSX no bind as well. No unused variables. Okay, so we got a few linting errors that we're going to have to deal with here. But I want to add in a couple of additional scenarios here that I think are common that you're going to find in your projects. So let me come back. Let me come over to my project here. Let's open this up and let's actually get it to force a few more of these linting errors to pop up. So what I'm going to do is just make this a little bit bigger. And I'm going to start by coming over here into my services. All right. So let's add a few things to our service here. So one of the things I'm going to want to do is I'm going to go ahead and add a constructor. So I'm going to say constructor and I'm going to use this access or a private access or that's going to just say some string equals hello world. Like that. So what is that doing? Well, this is a type script like shorthand. What this code is doing under the covers is creating a private member variable called some string. And it's adding that to this class. And then it's going to set the value of that inside the constructor. So this code right here is the equivalent of me writing something like private or sorry. Yeah. Private some string is a string and we'll put that in just initialize it to nothing. And then I'll say constructor arg, which is a string. And I'll say this some string equals arg. So this code right here is identical to the code right above it. This is what it's going to essentially be transpiled to. So I don't want to I'm not going to use this right now. I'm just going to go ahead and comment that out. And see like this is going to trigger some some errors that we have. So notice we're on four error line 432. So another thing that we're going to do here is let me come over to our web part. And let me add in a few things to our web part here. So some common things that you would end up wanting to do with this. Like let's say for example that you wanted to get the current title of the current site. So I'll just create a new member variable called my current site title. And then inside of that, I'm going to want to do something like after the on a knit. Let's add in a method here that's called get this is called get the site title. It's going to return back a string as a promise. It's an asynchronous method here. And so what I'm going to do is call this.context sphpclient.get. I'm going to look and get the title of the current site that I'm on. When I get that response back, it's just a raw response. So the first thing I have to do is I have to call JSON to convert the body of that to JSON that I can work with. And that's also going to be done as a promise. So I'm going to return that back as a promise. And I'm going to grab the title property out of that because that's the only property that I requested. And then to be able to use this, well, I'll do something like say this current site title equals await this.get site title like that. And to be able to use that await, I need to go through and decorate this guy with an async, right? So make life a little bit easier. I could do it with a promise as well and use like a then promise if I wanted to on this. But I'm not doing that in this case. Actually, you know what? Let's just go ahead and do that. I'll show you another. It'll actually allow me to show you something else. So get the site title and then in the then part of the promise. So this is the site title, which is going to be a string. I'll then say this dot current site title equals site title. Okay, so we're in good shape there. All right, now that we've done this, let's go back and let's see our lending error. So this time I'll just do it right inside of the terminal and our existing client. And I'll just do a gulp build. Okay, so we've got a bunch of errors that are popping up here. So let's go ahead and start looking at some of these. So first we're going to start off with is this no explicit any. So what is this? So I mission TS, I mission TS lines nine and 10. So what does that mean? Unexpected any specified different type? Well, that's going to be kind of easy for me to look at because I look at this and it shows that I've got an any type that's listed. Generally, not a great practice to do this, but sometimes you kind of need to do this. And I think that in this case here, it's really going to be up to you. What do you want to do? Well, first of all, there's a couple of things that you can do how you can address this. So one thing you can do to address this is I can turn off the linting for this file. Everything in this file by just going and adding a comment to the top of the file. And I could say ES lent dot or dash disabled. And what that will do is that will turn off linting for the entire file. So if I rerun a gulp build, we'll see that that error is going to go away from my ea for my I mission file. And sure enough, we can see that it's gone. Well, that's not really ideal. Maybe I just want to go through and get rid of it for this these these two lines right here. And so one of the things I could say is I could put in this ES lent disable. So let's say I wanted to disable just this one rule instead of everything with ES lent. And what I could do there is by saying ES lent disable and then pass in this the actual linting error that I want or linting rule that I wanted to ignore. So I could turn it off for an entire block by doing a disable and then turn it back on here by saying go ahead and turn it back on. So now if I go through and I run gulp build, it should still not show up, but we can see how we're disabling it from showing up. And we can see that as it finishes here, it's missing. It's not even showing up our I mission type script class. Okay. So that's another way we can disable it on yet another way we can disable it is that we can just disable it for a particular line. So I could do it as a disable line and do this as just a comment on this one line. So this way we should see our ES lent error for this any the any rule should only show up one time, not twice. It should show up for line 10, not not not line nine. And sure enough, you can see here that it's showing up for line 10. Okay. Well, that's great. But how do I actually fix this? So one of the ways that I can actually fix this instead of disabling this rule, one of the ways that I can fix this if I come over here, I can actually define something for these two objects. Well, the crew object, I know it has a very specific type. And what I can do is by drop in this I crew option right here and then take I crew and assign it over here because that's the correct data type that we have. But on the vehicles, I don't really know what this is. And to be able to define a type of anything, I can't use the any keyword, but a way to get around it is to say, create a new interface here of an I anything. It's going to be any name that I want it to be. And I'll just say it can have any string as a property. And that's going to also evaluate to an object. So any it can have any property that's going to evaluate to a string. And now I want to go through and set it here. What we'll see is this is this is kind of like cheating, because what this is doing is this is saying, I'm going to create an interface just to make the rule go away. But I don't know about you as I look at this, you can see our rules going away here. But I don't know about you. But as I look at this, that is a lot harder to read, at least that was a lot harder to read than these two things are. So I kind of have to leave this one up to you. Does this make sense to even go up go through with this? I don't know. I mean, that's going to be up to you. Let's look at some of these other ones here that we have. We've got one here for online five for mission service about a consistent type assertion. See where it says use as I mission instead of I mission. So what is that? Well, let me go ahead and let's grab this real quick. And let me open up my browser. Let's do a search for this consistent type assertion. That's coming from TypeScript ES Len. And so what I'm going to do is let's go take a look at what this is what this is saying. And what I can see in this rule is that it's effectively telling me that it aims to standardize the use of assertion styles across the entire code base. In other words, let's go back to our code. If I come over here to my mission service, it doesn't like the fact that I'm using these angle brackets here to define the array of objects that are inside this giant Json, this giant Json array here that I have. Instead of what it wants me to do in this case here, it doesn't want me to use angle brackets because it says, you know, hey, because React actually uses angle brackets and in TSX or JSX, probably not a good idea to use it in casting as well. So to make sure things don't get screwed up, then you should not use that style of casting. You should use that style of casting. Okay. I mean, is that that big of a deal? Well, I mean, I guess to them, to Microsoft it is or at least to the default setting that we have in an SPFX project. But I don't know, that one's going to kind of be up to you. You got to figure out if you want to do that. But you can see here we got rid of that one that was on line five. So we're getting a little bit farther down. We're doing better. We still got a boatload of yellow here that we got to work on. We got 15 warning showing up. So let's see what else we can do with this. Explicit member accessibility, the mission accessibility modifier or definition of the constructor. What does that mean? What that's telling me here is that it doesn't want my constructor to have no accessor defined. In TypeScript, I don't have to define it. I can leave it just the way it is right now. And that's assumed that it's going to be public. If I wanted it private, I got to mark it as private. But what this rule is telling me is that I really need to say be explicit in what I want to do. In my opinion, that's kind of a garbage rule because yes, you should do that. But if the language supports certain things and for different shorthand things, they do it for a reason to make my life a little bit easier. I don't know. I'm not a fan of that rule at all. I would like to disable that one. But I'll show you here. We had 15 a second ago. Where are we going to be now? We're down to 14. Okay, cool. So we got that one done. What is the next one? I expected a type annotation on 432 on another thing on 432. No parameter properties. And a name. It doesn't like my naming convention. So it really doesn't like a lot of my issues I've got here. So let's go. Let's look at those at that code. What is this telling me? Well, first of all, no parameter properties. It doesn't like the fact that I can use this little shorthand and type script to put private before an argument so it can. I don't have to write all of this code out. I don't know about you, but the code online 432 is a lot easier for me to read than it is him to go through and read on the one that I have highlighted from 434 to 437. Not a fan of this one, but okay, I'll do what you tell me to do. I'll get rid of that code and I'll switch it over to this. And then I'll say it doesn't like the way I'm defining my properties because it says a private variable or private member should always start with an underscore. That's what the thing here about the naming convention. So some string must have at least one underscore because it's private. Like, okay. I don't agree with that, but whatever. It also didn't like the fact that in this case up here where one of the errors that it was telling me is if we open it back up, it was saying type def and expected a type annotation. What does that mean? That's telling me right here when I made this declaration, even though all of us can look at this and say, well, clearly some string is a string because I'm assigning a string to it as the default value, but the rule that they've chosen to use here says, nope, you have to put a type definition on everything. So I should have written it like that. I don't know about you, but I think that's a little absurd because now I've got more stuff to read, more mental comprehension that I've got to go through. Whereas before, I think that that was sufficient to say, I know it's going to be a string, whatever. But hey, now that we're doing it like this, it's all going to work, save my changes, come back over here and run gulp build. And we should have knocked out, what, maybe three of our different warnings. So we should be down to about 11, I think, 12 or 11. What did it not like? Some string doesn't exist. Did you mean some string? Is that because, oh yes, because we changed the name of it right there to put an underscore in front of it. Okay. So we'll try it one more time. Now we're down to 12. Okay. Getting better. Now, mission service, what else doesn't it like? Oh, member accessibility again, modifier on the constructor. Oh, there you go. That's why we only have 12 and not, it's a public constructor. So that'll go down from 12 down to 11 warnings in just a minute. Okay, cool. Now the next thing we want to look at, oh, we got stuff with our web part. All right. Let's look at this. You can use very unused variables. Oh, that's easy. What is that telling me? That's telling me that, hey, you're importing something and you're defining this thing called I read only theme and you're not using it. So go ahead and get rid of it. Okay. I'm not going to use it now. So just go ahead and delete it. That's a nice one to have. Kind of keep your code a little bit cleaner. Let's see. So that one should have gone down. We should be at 11. That should be down to 10. Next thing, line 25. Naming convention again. Up should have one leading underscore. That's right. So because we marked this as a private value right here should have a leading underscore. All right. I'll get rid of that one. So that's fixed. What do we have? What else do we have here? Oh, let's actually let's clean this up. Let's run it again. We should be down under 10. Started with over 15. Going to be under 10 now. Nope. Didn't like that because somewhere we're using something called current site title. We sure are. It's right here. Okay. Let's run it again. Change changes and we will then come back. Let's run it one more time. All right. Cool. We're down to nine. We're getting there. All right. Next thing. No floating promises. A promise must be awaited with an end. End with a call to a catch. End with a call to a then with a rejection handler or be explicitly marked as ignored with the void operator. What is this complaining about? Basically what this is telling me is that, this is a promise coming back with a then and you're not doing anything to catch the error handler. This is the part of where I think ES lent and people using ES lent and lending rules. You can make your code better, but you can also not follow the spirit of what the rule is trying to get you to do and instead just try and squash the rules warnings that are popping up. So like for example, it's telling me that I don't have anything that's catching an exception that happens here. And I can make this rule go away by simply adding in a catch that does absolutely nothing. And I can prove that to you by coming over here. Remember, we have nine. We're having this thing called no floating promises. I run it again. And what you'll see now is that this catch that we just added is going to get rid of that rule. I got rid of the warning. As you can see here, but in my opinion, that's not following the spirit of what was supposed to be happening there. So some of this stuff too is kind of up to you on how you handle it. That's not a good way to handle it in my opinion. You should have had an error warning or an error handler there. Next thing up, what do we got? Line 45 is now telling me the naming convention. It doesn't like the fact that it's called get site title must have a leading underscore because it's a private. So I'll say, fine, I'll make it called get site title. So I got to go up here and change where I'm calling it. All right, so that'll fix that problem. Next one, no async await. Now, this one is really irritating to me. This method right here, where is this coming from? So no async await. Actually, let's see how this is actually showing up in the project. That's a better way to look at it. So we can see this error is coming from the default definition and it says no async await. The usage of async has overhead when using older browsers. Now, this is one that I got a big issue with and I may be mistaken, but I think that Microsoft has already, I bugged this one in the SharePoint framework dev docs issues list. And I think Microsoft has already acknowledged the fact that, yeah, we shouldn't have done this. So we've removed it. So we won't see it in a future version of the SharePoint framework. And I'm surprised we even had it. So what this one does, if I come over here and I look under the node modules, remember when we were looking at the package, all the packages, we have an ESLint plugin SPFX package. And if I look at the library for this and I look at the index.js, let's get rid of this, we can see here I've got a plugin called no async await. So okay, that's coming from the SharePoint framework ESLint So that's coming from this file here under no async await, so let's open that up. And what that one's doing here, that is now there's our no async await rule. There's the message and it says the usage of async has overhead when using older browsers and that's being defined by the rush stack ESLint plugin. Here's why I think that this rule is a bunch of bull because we're all writing TypeScript. Now if I scroll down to the very bottom here and I look at the tsconfig whenever we build our project we're targeting ES5. ES5 is from 2009. I got a separate issue with the SharePoint framework guys on why we're still building Type JavaScript for 2009 when all the modern browsers support more recent JavaScript. We don't need to do this. The only reason you need to do that is if you're building stuff for Internet Explorer. Internet Explorer is dead. Microsoft doesn't support Internet Explorer again in 365 or SharePoint Online so there's no reason to do this. I could bump this up to ES6 and get a more recent version of JavaScript but regardless the async and await keywords aren't even in ES5 or in ES6. TypeScript is going to compile those keywords down that I'm using in my TypeScript and you're never going to see async and await in your projects. I can prove this. If I come over here and say Gulp Bundle that's going to create the JavaScript bundle for my project. That's going to put that into the disk folder. We'll let this finish so we have a lot less warnings than we did a second ago. Webpack runs there's our bundle that's being generated right here and in that bundle let's do a quick check find async. Keyword async which should be at the beginning of a function. Load async that's not one that's not what I'm looking for I'm looking for async to be right between function and the name of the function so not there nope still not finding it still not finding it still not finding it and that's it that was all 11. The error that we just saw a second ago whereas let me see if I can find out where we just were. I was under node modules we're under at Microsoft plug-in lib no async away it has overhead and using older browsers we're not even putting it in the bundle which means that the async keyword isn't even making it to the browser this rule is absurd so while it may be gone in future versions of the SharePoint framework I'm going to show you how to turn this thing off completely and then we're going to see this show up again we have it showing up in a couple places there's no async await see if we have it in any other places not that I can see so how to get rid of it what I'm going to get rid of it is I'm going to copy the entire rule like this I'm going to go to my eslintrc.js file and I'm going to add in a rules collection and inside this rules collection there's a rule called no async await I'm going to set it to off so that now when I run a gulp build we now see that whole no async await thing is now gone so cool I was able to shut that off for the entire project so I've shown you how to shut off a rule for an entire project I've shown you how to shut off a rule for an entire file I've shown you how to do it for an entire block of code and I've also shown you how to do it for a specific line and disable specific rules here on my mind Microsoft should get this out of the default projects alright let's look at another one a type def what is that expecting a raw response to have a type annotation I know what that is what that's telling me online 46 and on 49 we can see in those two places if I come over here to 46 and 49 there we go it's a raw response but I'm not telling it what kind of data comes back the data that comes back is an SP HP client response so I need that value right there I need to import that add that to my list of imports like that come on here to this guy and add it like that I then also with the responses coming back from this JSON I'm getting an any coming back for me right so is that any going to be cool well I don't know because I'm not actually giving it a type annotation so that would have been line 49 right now because I just added some stuff to the import we see it's now line 52 so what I could do here is I could define a new interface that's going to define what this thing is or I could just say that this is some object that has a title property that's of type string and what that'll do is I'll actually squash that error so I'll squash that problem here so now I'm defining the type of data that I'm expecting to get back so that I can have my intelligence and you'll see here that it's now gone away now I'm back to dealing with the we'll come back to that in a second so that's another thing we have to look at those type definitions I don't think that we should have to do those I think that that should be up to us I think that maybe it could be turned off maybe it could be turned on I don't know you tell me leave a comment below and let me know if you think that this should be a default thing that we have in our projects some people are going to want it some people aren't I would default to not forcing this not imposing this on people a couple other things that we have here this one I think this one's a garbage rule that we shouldn't have to that should just be removed as well so I'm 47 in the mission react component 47 there we go okay so what this is telling me is I should not have arrow functions inside of my I'll look at this error here this is coming from a react library I'm going to copy this and go back to the browser and do a search for it no bind so why is it telling me this and it's saying that it'll create a brand new function for every single render this is bad for performance it may cause unnecessary renders blah blah blah so it tells me that I should not do things like use bind or use an arrow function instead I should do something like create the function and then call it like this this is to me this is really not not necessary using inline functions like this is perfectly fine this rule is completely outdated the reason why for this is that this rule it comes from a time when arrow functions were not as common as and people use the dot bind syntax that you see like right here we use this and that was slow a slow way of doing this that was a performance issue but that performance issue has been fixed in chrome 49 I don't know what you guys are using but this is not chrome 49 this is chrome 43 103 we're way past that we're years past that these are evergreen browsers so to me this rule is outdated we should not have to deal with this so again I'm going to go ahead and get rid of this guy by grabbing him and I'm going to go over to my linting rules and I'm going to turn this off as well if you don't believe me don't take my word for it go read this blog post from 2017 by a guy named Ryan Florence if you don't know who this guy is this is the guy that wrote the react router he's got a really good post that talks about inline functions and performance and really the gist of it comes all the way down to what he says here at the end is write your code naturally code it to the design measure your interactions to find slow pass and he explains how to do it and then he said it comes down to only optimize the code when he sees that there's slow stuff if you really believe that premature optimizations of bad practice then you won't need proof that the inline factions are fast you need to prove that what you did was slow not that what you're doing is fast you can't prove it in a negative so in this case here I don't like this rule I agree with what the react guys say this is outdated we shouldn't have to deal with this the rest of the ones that you see here this is we have the same thing with the props using arrow functions we if I go do a galt build again you'll see now that I've actually gotten rid of all of our errors except for two I think we're down to two yes these are both no unused variables and that's inside of my mission list and my react because if I go to my mission lists I have styles I'm not using those I can get rid of that and in my react I'm using the escape function or I have it imported but I'm not using it so that now when I build my project we'll see that I have no ESLint errors or warnings and ta-da everything looks good so in this video I wanted you to be able to see how to deal with some of this stuff how to figure out what's going on with some of these roles and where some of them are being defined but then in addition I wanted you to learn how to maybe either address the code problems that they're talking about or to figure out how to disable it and move on what do you think now I've created a discussion item on their issue list to debate this so I'll leave a link to it in the description below the video so please take a moment and let Microsoft know what you think either by simply reacting to the post or by leaving a comment now's the time because we might be able to get some things changed before the next SharePoint framework release what do you think about all these changes with the ESLint do you think that Microsoft went overboard too? let me know by dropping a comment below and let me know if you want to see more share videos about the SharePoint framework and if you like this video please give me a thumbs up and subscribe by smashing that big red subscribe button below the video so you'll see when I publish more videos for developers on Microsoft 365 and Microsoft Azure topics including the SharePoint framework I'll see you next time