Code Transformation and Linting with ASTs Examples of Abstract Syntax Trees
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.
[00:01:06] 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.
[00:01:36] 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.
[00:01:58] 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.
[00:02:19] 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.
[00:02:44] 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.
[00:03:07] 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.
[00:03:36] 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.
[00:04:00] 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.
[00:04:30] 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.
[00:05:01] 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.
[00:05:57] 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.
[00:06:21] 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.
[00:06:41] 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.
[00:07:20] 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.
[00:07:45] 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.
[00:08:02] 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.
[00:08:21] 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.
[00:08:43] 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.