Production-Grade TypeScript API Extractor Setup
Transcript from the "API Extractor Setup" Lesson
>> So on GitHub, now that I've created a repo, you're now able to find the work I've done so far on this sort of Mike's TypeScript boilerplate project. So if you wanna go to GitHub and check that out, then make sure I actually push that. It's possible I didn't push my code, we'll see.
[00:00:35] It's there now, in any case. So if you didn't follow my instructions perfectly, or if you ran into some problems, now you can check out exactly the code that you saw me write. And if you're watching this, you're watching this on the video, just make sure you look at the readme carefully, because I'm gonna make sure that it's very clear which branch, or commit, or tag you can look to for each each part of this process.
[00:01:08] And where we are right now is we have linting, TypeScript doing the building, and we have tests running with Jest. So we're gonna add one more thing, and it is probably something that you haven't seen before. Just a moment, I gotta pick something up. So we're gonna add an API documentation tool.
[00:02:09] It's about 80% of the way to the bottom, and it's called API. It's called API Surface Report and Docs. Look for that heading, API Surface Report and Docs. So where we're gonna begin is we have to install two new packages, yarn add microsoft/api-extractor and microsoft/api-documenter. These are two CLIs, each of which serves a very specific purpose.
[00:02:49] And I like that these are separate tools, because they leave you with options, in terms of maybe you just wanna adopt one or the other, or both. But the choice is yours. So first, we're gonna focus on API extractor. And the job of this tool is to look at our declaration files, and analyze them, produce a report on our public API surface, and produce a JSON file that can be used to make docs.
[00:03:25] So it's all about analyzing our project, and producing stuff that describes our library. That stuff could be a markdown file. That's an API report. A dtsRollup, which is kinda like a roll up.js, if you've ever used that, right, a bunch of things all combined into a single file, and then a JSON file.
[00:03:47] So you've got three different forms of similar information. We are going to follow this theme today of getting that first basic config file from these CLIs themselves. So this one is yarn api-extractor init. Careful you don't do double dash in it like we've done with some other tools.
[00:04:09] And a couple things have happened. Actually, just one at this point here. We have a JSON file. Here are your red squiggles. Remember I told you about comments not really being part of JSON? Well, we can change the language mode in VS Code and say JSON with comments, and look, everything's gone.
[00:04:30] Now, there's a way to set this up in your settings if you care to do so, I'm not gonna get into that too much. We just need to make a few changes here. So you're gonna look for mainEntryPointFilePath. So API extractor expects your library to have a single entry point where all of the imports come from.
[00:04:55] So a good example would be react, right? You're not importing things from react/component. Everything's just coming from react. There's this one module. Everything comes from that. So that is the opinion That comes with API extractor. That you should build things that way. And I feel like that's a good idea, because it let's you have very deliberate public API surface.
[00:05:17] So it's go to look at project folder which is the root of my kit repo./lib/index.d.ts. And I want dist instead of lib. So we're gonna make that one little change there. And then there are a couple other things we're gonna do. We're gonna look for our dtsRollup, and whether that's enabled or not.
[00:05:50] Here's my API report doc model. All right, dtsRollup, looks like this is already enabled, it's set to true. If you see little carrot m in the notes as line endings, just ignore those. That is a mistake. It's like line feed, it's like lf instead of crlf, like carrot return versus line feed.
[00:06:15] Anyway, that's not something that you should type here. Just make sure that this is set to enabled. Next, we're gonna look for untrimmedFilePath, here it is. And what we're doing here is we're describing different versions of our API surface that we can make available to people. This is super cool.
[00:06:36] This is where we get the ability to say, I have a new method available on a class, but it's in beta test. It doesn't have the same SemVer guarantees as my stable release, right? So here are the types for beta, and here are the types for stable. So we need an untrimmedFilePath, because that represents our entire API surface untrimmed.
[00:07:02] Nothing's been trimmed away. So just make sure you're careful about commas, because with these comments, the commas can get lost. So if you see red squiggles here, it's probably because of that you see here it doesn't like that comma, but we're gonna keep going. So we've got our untrimmedFilePath.
[00:07:23] We're gonna comment. We're gonna enable the beta trimmed file path, and it is fine to just sort of leave this as is. Actually, I wanna make one little change up here to align with the notes for untrimmed, because it is everything, I wanna add private to the end.
[00:07:43] This might be something that you would consume for testing your code. It might include private APIs that you wouldn't want appearing in an autocomplete for users. So untrimmed, everything's in the dist folder, right, untrimmed, and so it's private. This is our beta. So beta ends with beta, so this one's already good.
[00:08:07] And then we've got public. And let's make this one. Let's get rid of the public here. So I've just added my own little opinion here. I feel the default thing that people should look for should just be your package name .d.ts, right? Cuz if they don't know anything about API Extractor, then they don't need to worry about these conventions.
[00:08:31] And I feel like it's more important to indicate what is private, what you shouldn't use, as opposed to indicating public, that you should use it. Cuz it's a little bit more explicit of a signal this is private, you shouldn't use it. So I wanna mark the private, as opposed to letting people deduce that it's private, if that makes sense.
[00:08:57] All right, so I'm gonna save, which, should remove that trailing comma for me, save, and it does. Otherwise, you can delete it yourself. And we are done with this file for now. All right, we need to do one more thing before we try API Extractor, and that's make a folder called etc.
[00:09:16] This is where your API report is gonna live. And the folder must exist before you try and run this command. Now it's time to take it for a spin, yarn api-extractor run, and then --local. So that's what we ran. And we can see on the left a couple things happened.
[00:09:43] So first, new declaration files appeared. So we've got private. We have beta. They all look kinda the same at this point. This one's missing something here. This is my public API surface. It only has AVG. But if I look at beta, look at this. So because some three, this function was marked as beta, it's not part of my public API surface yet.
[00:10:19] Somebody could opt into this, but they would have to take an extra step to use this beta feature, which is exactly what you want for a beta test. You want people to be able to, by default, get the stable experience. And if they're doing what they should be doing with the beta, which is just evaluating it, not using it in production, not using it at scale, that's what makes a beta test.
[00:10:44] Well, then they have to make a little change, and it's pretty simple for a consumer of this library to make this change.