Transcript from the "API Documentation" Lesson
>> So, important to have clean git history as we do this next thing. We're gonna add API documentation on top of API Extractor. We already installed the tool that we need for this, which was @microsoft/api-documenter, and we're gonna run it now. Yarn, api-documenter markdown. That's the type of documentation we want.
[00:00:32] -i is for input, temp -o is for output, docs. And if we look at what's in this temp file or temp folder, there's our API report, the markdown that we looked at. And look at this json. This is some meta information here describing modifiers. All right, here's a package, chat standard lib, and here's an entry point, here's a class, and it's called deferred, here's a description of the class.
[00:01:07] So, if you wanted to write your own documentation, you could read this file, it's a very nice organized way of sort of articulating what's in that rollup. So, let's press enter and see what the markdown version of this looks like. We should have a new docs folder. There it is.
[00:01:29] And I'm going to open up index.md. We'll preview this, just so we can see it real well. And you see here, we first got a list of packages. So, this is telling you maybe in a large project you have many libraries, and this could be your entry point for them.
[00:01:46] If we go into that, here are my classes, here's deferred. This is coming right from my code comments. Here's my stringify error function with a clear description that this is a beta thing, like it's a beta function. But if we click on that, it will give us the type decoration and here are the parameters.
[00:02:04] This is the return type. And you can use JS.comments or the same kinds of comments you're likely using to describe your code as you do today. And this sort of gets spit out for free as part of your build. Nice little banner up here that even says it's a beta preview, maybe subject to change.
[00:02:26] I'm somewhere in that big config file, there's a way to even customize this message. So, what I like about this is we can kinda string it all together and make it so, when you're making a code change, the docs kind of update automatically as part of your build.
[00:02:42] When you open a pull request, you get the change to the public API surface, the change to the docs, the code change, all coming in at once. And that lets you, in a large team, have great conversations around like all right. You made a public API change. Did you think about what's going to break?
[00:03:01] Who consumes this? In what way did we change this? Is it a backwards compatible change, or are we gonna have to update some things somewhere? And then the docs are there as well where you can say, okay, well, so how are we explaining this change to users? Like you're exposing a new class here, what should it look like?
[00:03:19] But it's a much more holistic thing to review than just like a couple lines of TypeScript code that are being altered. And because it's marked down especially if you use GitHub. Markdown diffs have great support even when it's like rendered, you'll get a little gutter like indication that like this, this is the diff here.
[00:03:40] So, I like the kinds of code review discussions that happen when all of this is sort of stitched together. Let's add some new NPM scripts. I've been getting some help from class to make sure that I'm not forgetting to build before I run my API docs and things like that.
[00:03:59] So, let's build three new scripts. One's gonna be API report, and that's gonna be yarn, api-extractor run. We're not gonna have --local, and I will show you why in a moment. Next, api-docs. And here, we're gonna have the same command that I just ran. Right there at the bottom.
[00:04:39] Exactly the same as what we just ran. And finally, build-with-docs. And here we're just gonna to do yarn build, yarn api-report, yarn api-docs. So, it's gonna do the build for us, which will give us that updated index.dts. It's gonna run api-extractor which will analyse our library, and it'll give us those nice rollup files.
[00:05:13] And it'll put the json file into the temp folder, which this json file is the input for the API documentation tool. And then finally, it'll generate all of the markdown there. So with that, I'm gonna make one more commit. And we're gonna do a sample code change. And then we're gonna run this command and see what happens.
[00:05:40] We would see in a pull request if someone were going to make a change, and we'll make a really tiny little change, where in the stringifyError function, which is an index.ts. We're just gonna make this optional argument required. Just delete the question mark, save it. Yarn, build-with-docs. It's doing the build, doing api-extraction, it's rendering new markdown docs.
[00:06:16] We got a little warning here. And this is what you would see as a developer. So, I told you we'd discuss like, what is the --local argument for api-extractor mean, and the fact that we dropped it means it's not gonna automatically update that ETC markdown file. This one here.
[00:06:39] This hasn't changed. Look at my gutter on the right. No indication of git changes here. But in the temp folder, this is sort of like a staging area, and note that we don't have a question mark here. This is not checked into git, so we're not seeing a git diff of any kind here.
[00:06:58] But if we compare the two, that one has no question mark, this one absolutely has a question mark. And we're being prompted, if we really wanna make this change. To copy the temp, the file and temp into the ETC folder. That's really what --local does. So, where might this behavior be useful?
[00:07:19] You might have in CI something that would run this command, and at this point it would fail. You would say, you have a code change that is not represented in the API surface report. There is a misalignment there. Sometimes you want that to fail. This would be what would catch a case where someone just made the code change and then opened a pull request, and it's they didn't run the api-extractor and they didn't run api-documenter.
[00:07:51] And that's valuable, that's why I leave --local off here so that you'd make sure that this command finishes successfully. It's failed. Well, sorry, there's you would configure this being a failing error you can, in the config set it up to fail, but that's why omitting --local would be of benefit here.
[00:08:14] So, we'll just do the manual step here. Okay? And now we can run this again. You probably don't have to run it again this time, because it didn't actually fail, it just showed a warning. But there's a lot of tunability in terms of what's a warning and what's an error.
[00:08:37] And we can look at this is what the PR would look like this these are the files that were touched so here of course we have the code change, right? There's the removal of the question mark this second argument is no longer optional. Here is how the API surface report change, so this would be where you'd look you know maybe there are a bunch of different changes in this PR, and maybe only one of them actually affects the public API surface of this library.
[00:09:03] And as a code reviewer, you would look at this and you would say, okay, if I can see exactly how consumers of this library will be affected, this is a breaking change now. Anyone who depends on not needing to pass that second argument, they're gonna need to update their code now.
[00:09:19] So, let's talk about that. Maybe that's what we wanna do, but who knows? And then finally, there's the update to the markdown file, documenting this function. This is a nice complete code change here, docs API surface report and the change itself. I'm gonna make a quick commit. And congrats, we have a small working library.
[00:10:17] We even took a little side journey and looked at how we could have a nice like watch command using concurrently TypeScript --watch, and just in watch mode. And then at the end here, we talked about API surface change detection. And a nice, simple API documentation tool, which if you're, if you're in a situation like what we have here, and you're not really like publishing docs to a website or something, you certainly could, but this is nice to just like having GitHub as internal documentation for an app.
[00:10:51] And you can change where the docs are written to so they're all in one place, and they can sort of be browsed together. But this is a great solution for an app team that just wants encapsulation around different components of their app as opposed to sort of an open-source library, where you're publishing these docs.
[00:11:12] I use it for that too, but sometimes people want a little more style and some docs that look a little bit more interesting. These are super simple. They come straight from TypeScript's type information. And I really love sort of the alpha-beta DTS rollups, which let you evolve things in place, knowing how you're gonna affect various different types of consumers.