Creating an Open Source JavaScript Library on Github

Exercise: Adding Babel Register & Istanbul

Kent C. Dodds

Kent C. Dodds

Professional Trainer
Creating an Open Source JavaScript Library on Github

Check out a free preview of the full Creating an Open Source JavaScript Library on Github course

The "Exercise: Adding Babel Register & Istanbul" Lesson is part of the full, Creating an Open Source JavaScript Library on Github course featured in this preview video. Here's what you'd learn in this lesson:

In this exercise, Kent adds babel-register and babel-plugin-istanbul to the project. After configuring these to modules, he uses the NODE_ENV to indicate which environment is being used for each script so the correct plugins will be loaded. Since the NODE_ENV variable only works on OSX, Kent adds the cross-env module which allows it to be set cross platform. The solution to this exercise is on the FEM/07.1-transpile-tests branch.


Transcript from the "Exercise: Adding Babel Register & Istanbul" Lesson

>> [MUSIC]

>> Kent C Dodds: Let's just start out with, normally you'd npm install this, but we'll just put babel-register in here. And the version that you all have installed is 6.11.6, the latest version. And we're also going to have babel plugin-instanbul. And the latest version, I think we have the latest version, 1.0.3.

Yeah, doesn't matter what order these are in. I think it's the wrong order, but whatever. And so then, what we're going to do in our NYC config is we're going to say, hey, we don't want you to instrument anything. Instrument, instrument. So we're gonna say instrument is false and then I'll be perfectly honest I'm not sure why we need this next property but we do for this to work.

It's sourceMap is false. I think it just, source maps do some funny things with, or like covering your code, so that's what we're doing there. And then we're gonna add yet another property called Require. And this will tell NYC hey before you spawn off this mocha CUI I want you to require this thing and have it do something.

Just like modify the global state, which is exactly what we're gonna do with that, we'll register. So we want to require the babel-register module that we just installed, and so then babel-register can hijack the require function, and then anything that uses require will have that code transpiled on the fly.

And then finally, we're going to add a plugin here.
>> Kent C Dodds: And that plug in is the istanbul plug in that we just installed. So that will plug in istanbul, we can just shorten it to istanbul. So with that, if you run NPMT to run your test you should get results.

>> Kent C Dodds: Raise your hand as soon as you get to that.
>> Kent C Dodds: And let me just move this out of the way.
>> Kent C Dodds: So you've got your plugins here in the babel config. Plugins is istanbul, it's an array. You've got a couple online folks who've got it. Instrument is false, sourceMap is false, require, babel-register.

Anybody here got it yet?
>> Kent C Dodds: Awesome, air five.
>> [SOUND]
>> Audience: Woohoo!
>> Kent C Dodds: Okay, sweet. An air five to you online people, good job. Okay, so now we have a problem. Let's go ahead and run our build.
>> Kent C Dodds: And open up our index. And you're gonna see something kinda frightening.

It is, yeah, doing a bunch of crazy stuff. Remember that variable thing that I was telling you about. Yeah, this is the stuff that it's doing. Yeah, that looks nothing like what I showed you but it's the basic, the same basic idea. It's saying, okay, take some variable, some property off that variable, and increment that by one.

So, we don't want to actually distribute this to our users, of course. That would be kind of rude. Yeah. And it's too much stuff. It would not be very performant. So, what we're going to do is we want to differentiate between our test environment and our normal environment and babel has the ability to let you key off of the environment variable, node env.

You can also use babel env as well. But these are just environment variables that you set to get babel to behave a little bit differently. And so first we'll configure babel to behave differently given like a certain environment. And we do that in our package.json under the babel object with the env property as an object.

And then the inside of that where you want to specify our differences when we're in the test environment, so as an object inside of the env object we'll specify test, and that's where we put our test only configuration. So those of you who are the web pack workshop yesterday this looks familiar.

So then to make babel do something with this we need to, sorry let me just so you can take a look at it really quick. To make babel do something with this, we do need to set that environment variable before we run the test. The way that we can do that is actually platform specific.

So we're gonna get something that'll make it so that we don't have to be platform specific, but I'll just show you what it looks like normally and that is in our test command we'll say so this for Mac only if you're on Windows just hold off on a site if you do know how to like set environment variables with Windows you can try this for that.

Well, we will say node to ENV equals test. And now if I run NPM build or NPM run build then I look at my index and everything looks hunky dory. And if I run NPMT for running the test, then everything passes just fine. So I'm getting the best of both worlds, they're both working.

Any questions so far? So, like I said, if you're on Windows, doing this will not work and I battled with this for quite some time until I finally wrote something called cross-env. That's all you need to do. Of course, you'll need to install it, which you already have, but by adding cross-env in front of there, this will work on Windows and Mac and Linux and hopefully everywhere.

That's the idea. So you do it as if it's a Linux machine, but cross-env will detect your platform and set the environment variable for you.
>> Kent C Dodds: So then if we run npm t, we should still get passing tests.
>> Kent C Dodds: Yep.
>> Kent C Dodds: Okay, and that's it actually. Does anyone have any questions?

Okay. I'm going to let people ask questions here. I wish that I had a polling thing, because if I did, I would poll you all and ask you if you want to spend any time migrating this to ES6 that's not exactly like part of the workshop, or something that I think is important for your learning of making a library.

But if enough of you want to have some time to do that, then I can wait for five or ten minutes. Anybody wanna just kind of move on? You can learn the ES6 somewhere else. Yeah. That's kind of what I was thinking, too. Okay. Cool. Learning ES6 somewhere else.

For now we're just gonna use this magical git checkout thing. So actually I'm gonna just reference this.
>> Student: Can I ask you a question about the
>> Student: The instrumentation that you showed us there.
>> Kent C Dodds: Yeah.
>> Student: It looked like there were only a few lines that were instrumented.

Did it actually try to un-instrument it during the, what happened to that there was-
>> Kent C Dodds: Yeah, yeah, let me answer that question, yeah, I understand what you mean. So here actually let's go back to exactly what you're talking about. Yeah, we'll do that, it will be easiest to just say NODE_ENV=test and then npm run build.

So with that, we have this function that does who even knows what. And then we have our code right here where it's instrumenting this line by saying okay, you got a require statement here and you need to make sure that this assignment runs. This main export line needs to run.

We also did have the import statement up here. This is generated code. So there is somewhere in here where that import statement is verified to run. So we are instrumenting every interesting thing. Maybe I could put a couple if statements in here, but I think you get the idea.

If we open up that coverage report though, lcov-report/index.html. Then we're going to see that there are actually only three lines that have instrumentation reported. I'm guessing that probably the reason that this import statement is not being reported is likely because your program wouldn't run at all if that wasn't correct.

That's my guess. I don't know how you would instrument an ES6 import because it's static. And so your program won't even run. That's my guess. But that'd be definitely an issue to file and ask about on NYC. But yeah, there is not a whole lot in here, not many lines in here to even instrument anyway.

That's why you don't see too much. Great question. Okay, so let's just get back to this thing. Wait, no, it is. Yeah, actually I didn't change anything. So we'll get diff with the next branch just to see what we've. Whoops, just copy this guy.
>> Kent C Dodds: Okay, I'm lost.

Forget it. We'll just check out the next branch. [LAUGH]

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