Code Transformation and Linting with ASTs

Challenge 10: Upgrade Patterns

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 "Challenge 10: Upgrade Patterns" 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:

In this challenge, students update code to swap out jQuery with vanilla JavaScript.


Transcript from the "Challenge 10: Upgrade Patterns" Lesson

>> Speaker 1: The transform we're gonna do I think is kind of fun. So has anybody heard of It's pretty cool. So when this came out, it's like, I didn't realize, I only support IE10, and I didn't realize that some of these things were just one liners, it's just exactly the same.

And this is IE8+. I could just be doing this all the time instead of the selecting thing. So what our plugin is going to do is take a legacy code base that's doing all this stuff and automatically upgrade it to Not Use jQuery for simple things like this.

So we've got exercises. It'll all be the same plug-in, but we have exercises for hide/show, add class, and I think that's it. The last exercise adds a little bit of complexity because for most of the exercises, it's just this pattern. If it looks like this, then change it to this.

The last exercise allows you to say var, what just happened, myEl = $(el). And then trace where myEl is being used and update those references. So if we get to that point, then that'll be the last one. But if not it's not a huge deal so. Okay, cool, do you wanna look at it?

Yes. [LAUGH] So this, whoa, to go to that or go to that exercise, it's going to be npm start exercise.codemod.0.
>> Speaker 1: And this one is also using snapshots, so it's pretty much the same thing as what we had with our other Babel plug-in. Yeah, really the only difference between what we're doing here and what we did with our last exercises is the use case.

This one is intended to be run once. Our last one was intended to run every time you'd compile your program.
>> Speaker 1: Yeah, so then we go ahead and start. And we'll get a failure. Supposed to fix it. Let me just make sure that there wasn't anything else I needed to tell you.

Yeah, I need to demo something for you. So yeah, I'll demo it you instead of having you doing it the harder way. That'll be good. So I've got this right here I'm gonna copy. We're gonna go back to Babel v6. And just going to say const Hello, end template and we will do instead of this will do a variable declaration, there we go.

Okay, cool. So why is that not going away? Okay, so what our transform is doing is it's taking any variable declaration and changing it to this. So not really useful, but it uses a feature that I think you should probably know about. And that is babel.template. Now I should tell you that I talked with Logan on the Babel team, and he really wants to pull template off of Babel Core and just have it as a separate package.

And I begged him not to because if he did that we couldn't use it in our AST explorer. So we'll see if that ends up happening. But if you can't get template off of Babel, that's what happened and you'll just have to get it in the separate package.

It is already distributed as a separate package. So what this is doing, though, this template thing, is sometimes constructing the ast like we did like t.VariableDeclaration. Yeah, t.VariableDeclaration takes a kind, and then an array of VariableDeclaratives, and VariableDeclaratives takes like all this construction is awesome, but is not super awesome.

So what this does is you provide a template string, something that you want your code to actually look like. And you pass it to template, and that's gonna give you back, here, we'll call this a callExpressionBuilder =, or, actually, sorry. This is the callExpressionBuilder.
>> Speaker 1: There we go, just to make it a little bit more clear what's going on.

So we call the template with our templateString, and that gives us a call expression builder, or it gives us a builder for that .AST. And then we call that with an object, and it replaces any matching instance of our data with a template. So it's not using double curly braces like you would see in Mustache or Angular or something.

It's just straight up replace. Couple of things to know is you can't just do straight up strings here. That's not gonna work. It needs to be actual nodes that you're replacing things with. So we're gonna grant an identifier and another identifier and then numeric literals here for our arguments.

But these could also be any type of node, so string, literal, or whatever you want it to be. So yeah, the templateString stuff, or the babel.template is pretty cool. And I use it in my solution for this exercise, so it might be something to look at. If you want to reference this, that example is in other/schedule.

We're at the bottom, right here. So I've got my file really big at the bottom, right, so other/ and it's around line 115.

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