[poc] feat: docs (microservice variant)#134
[poc] feat: docs (microservice variant)#134devdumpling wants to merge 10 commits intonpmx-dev:mainfrom
Conversation
|
@devdumpling is attempting to deploy a commit to the danielroe Team on Vercel. A member of the Team first needs to authorize it. |
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
deployed, if you want to test ✅ |
There was a problem hiding this comment.
haven't ever used the community deno runtime, so TBD how well this works
happy to try it on my private vercel first and let you know, but based on their docs should be as simple as a config file like this
There was a problem hiding this comment.
Happened to be looking around, I'm assuming this is the package from @vercel-community/deno (I don't do Vercel much)? The one time I had to actually use Vercel it was with this package, which is unmaintained and it was a pretty awful experience. That project (which I no longer work on) now uses @lowlighter/vercel-deno. Simon (lowlighter) himself is pretty AFK, so I don't know how much of an improvement it is (again, haven't worked on it recently), but it might be worth considering.
- Add icon to code link for consistent alignment with other links - Docs link now uses package homepage (typically their docs) when available - Falls back to our generated API docs when no homepage exists - Remove redundant homepage link (now covered by docs)
…stead of subprocess
e1c2557 to
e30e128
Compare
Overview
This PR is one of two variants adding autogenerated documentation pages, accessible via a nice little link and routing to
/docs/{package}/v/{version}.If a package provides a
homepagein its manifest, the link will default to that. Otherwise, we attempt to generate docs viadeno docsin a microservice. More on this below.Problem
Okay, so
npmx.devcurrently shows all kinds of fun package data (metadata, READMEs, file contents, etc). But it lacks a feature I love from JSR/crates/other modern package browsers... autogenerated docs off type definitions.Generating these kind of docs is challenging for npm packages because:
.d.ts,@types/*, jsdocs, or any combinationSolution
Luckily, there's tons of prior art here. In particular, Deno and the JSR folks basically already solved this problem with deno doc.
Architecture
In development, this variant has a version that will shell out
deno doc --jsonin a subprocess. This makes it easier for local development and you can more easily test with a local installation of deno. This is what I used to build out most of this.In production, the idea is to call a Deno microservice hosted on Vercel (since vercel node.js/edge runtimes don't have Deno). For this we'd need to use the vercel community runtime (which I tried to configure here but don't have access to the vercel project, so)
see: https://github.com/vercel-community/deno
Arch Diagram
Implementation
This was quite a ride for me, as much of it is transforming the format from
deno docs --json, but there's some key points.Most of the heavy lifting is done in
/server/utils/docs/and is broken down into a few submodules:generateDocsWithDeno(pkg, version)The microservice is pretty straightforward. I'm open to opinions here. Just threw up the easiest deno implementation I could think of. Big plus for how easy it was honestly. I haven't really built a deno micro before this!
The frontend implementation simply fetches from the api endpoint (
/api/registry/docs/{pkg}/v/{version}) and renders the pre-generated HTML inv-html. I'm still learning vue/nuxt, so let me know if I'm doing anything dumb here.The UI could probably be improved / iterated on. I left that out of scope for this POC / initial implementation.
A note on
esm.shI needed to use
esm.shhere instead of our existing calls tojsDeliver. Why?In my testing, I couldn't get
jsDeliverto resolve@types/*packages for untyped packages properly and kept hitting module resolution issues with varying.js|.tsextension 😢. I'm betting there's a way to make it work, butesm.shworked on the first try, so I went with that. It also serves the typescript types natively with ax-typescript-typesheader which I use here.If we're concerned about having two underlying providers here (jsDeliver and esm.sh) I can take this back to the drawing board / iterate.
config
There's some necessary config here. Can change naming here. I don't have access to our vercel env, but we'd basically need something like the following:
DOCS_API_URL->npmx.dev vercel config-> this is the microservice URL (default in my setup ishttps://docs-api.npmx.dev/api/generate)DOCS_API_SECRET->npmx.dev vercel config-> bearer token for authAPI_SECRET->docs-api vercel config-> expected bearer tokenAlternative approaches
So in truth I don't love this approach. I mean, it's nice in a sense that it's a decoupled service. But as a rule I hate standing up infrastructure if there's a more maintainable way around it.
Hence there are two other approaches we ought to consider:
@deno/docWASM directly in Node.js server sideOption 2 may be interesting, but also comes with the steep cost of diverging from the incredible work the JSR team already put into this. If we want to build out other rust stuff here though, might make sense. We could also theoretically do more interesting stuff than is possible with just the json data we get from
deno doc --json.