Code Transformation and Linting with ASTs

Examples of Abstract Syntax Trees

Kent C. Dodds

Kent C. Dodds

Professional Trainer
Code Transformation and Linting with ASTs

Check out a free preview of the full Code Transformation and Linting with ASTs course

The "Examples of Abstract Syntax Trees" Lesson is part of the full, Code Transformation and Linting with ASTs course featured in this preview video. Here's what you'd learn in this lesson:

Kent discusses the importance of Abstract Syntax Trees (AST) by examining examples where they are used: plugins for Babel and ESLint as well as within Codemods.


Transcript from the "Examples of Abstract Syntax Trees" Lesson

>> Kent C. Dodds: Let's go ahead and get started. I have this talk that I'm basically just going to give you a beginners guide to ASTs, because you're beginners, or my assumption is that you're coming here as beginners. Most of you, based off the feedback server, that's the case. And so, yeah, this will be useful to give us all context around why we should care about ASTs.

So how many people here use Babel? Okay, it's awesome, you can use the latest version of JavaScript but still ship to the older browsers. It's pretty sweet. So Babel uses ASTs to accomplish this. And Babel is a tool that can take some code, turn it into an AST and then traverse that AST to make manipulations to it and it has plugins to do that and we'll be writing some plugins to do that but the ones that we're all familiar with are the ones that transpile all the latest version of JavaScript to what we can use today.

And Babel can be used to create all kinds of different plugins, as well. So I've got a couple of examples, some of my favorites. This babel-plugin-lodash is super awesome. So here, let's look at this code first. If you care about the size of your bundle that you're sending to users, like this is in a client side application or something, then you probably don't want to ascend the entire lodash module to the browser cuz it's pretty enormous.

And so what you can do instead is you can kinda cherry pick off the methods, the specific methods, that you need in your application. By just lodash/map or lodash/get and then you'll only get that method and its dependencies, so it's significantly smaller, but nobody wants to write code like this.

This is not very fun to do all this cherry picking, and let's say you're using six or seven lodash methods. You have to import them all, it's just not a great thing to do, and what happens when some developer unwittingly imports all of low dash. You'd have to have like a lentor or something to make sure that doesn't happen.

So instead, there's this plug-in where you can write your code like this, however the normal way you'd want to and then will transpile it down to this. So one of the key things about Babel is that like Babel plugins generally is try to make the development experience better without reducing the user experience.

Or sometimes even enhancing the user experience. And so, in this case, it actually like would enhance the users experience because you wouldn't accidentally send low dash and the Babel plugin for low dash just kinda does that for you automatically it's great. And if you're not using it, I recommend that you do, it's really, really good.

Then this one is awesome, the babel-plugin-module-alias. So how many people have written imports or require statements with a bunch of dots like this before? Yeah, it's a pain, and most of the time it's not a huge deal, but if you have this utils file or folder that you're using everywhere, what really stinks is when you move a big group of files from one place to another and you have to update all the require statements or imports, and that is, yeah, no fun.

And so what this allows you to do is specify aliases for directories so you can say, hey, this utils directory right here, I wanna alias it to open caret, utils, close caret, or whatever. Less than, greater than. And then anytime Babel comes across an import that uses that, it's going to update it with the correct full path.

Or the relative path, and everything else works just fine. So that's also quite handy, and just as kind of a fun tip, instead of utils, when you're making these things, name this directory something like to be published. Something that you're going to open source eventually, because one of the reasons that, or one of the really nice things about publishing packages to NPM is now you can install it in your node modules and you don't have to do this relative path stuff at all.

And so this kinda gets you halfway there by giving you those alliases. Again, this is enhancing the developer experience without reducing the user's experience, which is pretty great. And then this one is definitely a must if you're doing React, especially now with the way PropTypes have changed. But in production mode React.PropTypes.string and all of this stuff, it actually doesn't do anything in production mode.

And so all of this text is pretty much useless when you're in production. And so this plugin will remove it from your code, and so you're not sending those extra bytes for that extra code. And also the memory allocation for the PropTypes object, all that just goes away, because it's something that you just don't need at all.

Again, enhancing the developer experience, and actually enhancing the user experience, as well. So, it's great, any questions or comments about Babel plugins? Okay, cool. So ESLint is super, so ESLint, there's this plugin for ESLint. So, sorry, take a state back. ESLint is a linter for JavaScript and what that means is, it will tell you when there's a problem with your JavaScript, whether that be stylistic or actual potential bug in your program.

And this ESLint ships with a whole bunch of rules to help you with that, but it's very pluggable. And one of my favorite plugin's is this eslint plugin import. And this is integration with my editor, I use Atom. And I have this import for getLogger. And I got this red line and my editor is saying, hey, you have a linting error on that line.

The linting error is coming from this ESLint plugin. It says, hey, I'm looking for this get logger module but I can't find it anywhere. And normally you would only discover that at runtime, but ESLint can tell you that statically before anything runs. And it's using ASTs to do that.

Then there are a whole bunch of other plugins, too. There's one that helps you make sure you're doing promises correctly. Some helpful things for React, whether it's the React stuff or actual, hey, you shouldn't be using a ref as a string, because that's something we shouldn't be doing anymore.

All kinds of that stuff. There's the security one that's definitely recommend you give it a look. Make sure that you're using JavaScript in a secure way. And this accessibility one, like, don't forget your Alt on an image for in your JSX. So all of these things are using ASTs to do their job.

And they do it remarkably well. It's very cool. And then, finally, codemods. Who here has heard of the term codemod? Okay, so codemods are basically super awesome find and replace. So I don't care how good your regex skills are, you will not do as good as a codemod for most things.

So there are a whole bunch of codemods out there. Basically the idea behind a codemod is I need to take my code, and I need to forever change it to be this new thing. So I'm migrating to the Jest testing framework from Ava or from Mocha or from Jasmine.

So I need to take all my tests and change them so that they still work the same, but they're just using the APIs from the new framework. Same thing with Ava. The eact team creates codemods to automatically update all of Facebook's 30,000 components that they have, or something like that.

As well as the entire community. So with React version 15.5, they just deprecated PropTypes and put that in a separate package, same with Create Class. And they released a codemod, which magically upgrades all of your code. So you're using new APIs, which is pretty sweet. And then there's this 5to6-codemod if you're like, okay, I'm done with ES5.

I wanna use ES6 and this will upgrade stuff and even can take the prototype pattern and change it to classes. It's pretty cool.

Learn Straight from the Experts Who Shape the Modern Web

  • In-depth Courses
  • Industry Leading Experts
  • Learning Paths
  • Live Interactive Workshops
Get Unlimited Access Now