Rust: Use React to help simplify librustdoc's main.js

Created on 1 Nov 2019  路  5Comments  路  Source: rust-lang/rust

Hi there! Firstly I wanted to say how much I love the Rust language, you all have been doing great work. Was digging in to the code used on docs.rs, because I was interested in making some improvements. The file I found was this one: https://github.com/rust-lang/rust/blob/master/src/librustdoc/html/static/main.js

Something I noticed about this file is that it seems to have some convoluted imperative logic to do simple things, such as tracking state of collapsed items, by storing the state in the DOM. Normally this works well for one-off use cases, but it seems the file has outgrown this level of simplicity IMO.

For instance, there is some confusing handling of timeouts here: https://github.com/rust-lang/rust/blob/master/src/librustdoc/html/static/main.js#L1652 mixed in with explicit handling of window history state, which seems unrelated. The overall structure of the file seems a bit haphazard -- if someone disagrees I would be happy to defend this position. Since modern frameworks like React have well-established conventions for handling these situations, I would suggest adopting a similar framework to build this page off of. I would even be happy to produce a prototype to show how it could actually integrate with rustdoc.

For completeness, here are some pros and cons of adapting a framework like React:

Cons

  • Build system required for JSX (though Rollup https://github.com/rollup/rollup is available, which is pretty lightweight)
  • (Slightly) increased build time when running rustdoc

Pros

  • (Most likely) less code to maintain (I would estimate main.js could be cut down by at least 20%, even more if you don't count boilerplate).
  • More declarative approach to match Rust's general style.
  • More easily bring in third party solutions such as Dropdown or Modal components, which are handled on a bespoke basis right now
  • React Component style allows better code reuse
  • Established patterns for mixing persistence (settings) with actual document state (currently same as DOM state)

Anyway, was curious what the Rust community thinks of this idea. I think it could help speed up UX improvements development on rustdoc and docs.rs significantly.

Thanks for reading! - Phil

T-rustdoc

Most helpful comment

I am pretty strongly opposed -- I think we should strive to make rustdoc less like a JS app and more like a static website; React moves us farther from being a static website.

I'm not on the rustdoc team though and they may have other opinions.

All 5 comments

I am pretty strongly opposed -- I think we should strive to make rustdoc less like a JS app and more like a static website; React moves us farther from being a static website.

I'm not on the rustdoc team though and they may have other opinions.

@Mark-Simulacrum Could you expand a bit more, I am not sure what your main argument is - what is it you find unsuitable about JS apps? This is mostly about the choice of organization rather than language (which is already JS).

We don't do much DOM manipulation, and what we do should mostly be static (there are areas where we're mutating things today, for sure, but in many cases I'd rather we didn't have it, or it's not too hard to do so with frameworkless JS). When I say static I mean that it mostly just makes specific HTML, not continually updates some piece of HTML over time. React is a pretty sizeable burden -- primarily, in my eyes, in terms of complexity; for the most part, from at least my experience with JS web development several years ago, it usually starts pulling its weight if you're actively changing state on a page as events arrive from a server (or the user clicks around the page), e.g. like on a single-page web-app.

Plus, I suspect that React in our case would not work well since it -- I suspect -- is somewhat invasive, i.e., it wants to be in charge of a particular component from the start. Unfortunately, that means that we need to move the HTML to JS, and that makes no-JS use of rustdoc's output even worse than it is today. While I don't particularly want to optimize for not having JS, I don't think React (or another web framework) brings us enough wins to pay the cost of lack of JS. I'm aware of server-side rendering possibilities, but I don't think they're really viable for us -- we likely can't afford to make all Rust compiler (or even just rustdoc, I suspect) developers install a JS toolchain in order to run tests and such.

I strongly agree with @Mark-Simulacrum: we're moving as much as possible to a static renderer. JS is a plus but definitely not something we want to depend on. Also, adding a JS build system to generate documentation would be very complicated and not very nice to have since we want people to be able to document and check their crates' documentation without having anything else than the rustdoc tool and a web browser (or just a text editor).

I see, fair points. I would argue since the docs are already heavily dependent on JS, and likely will continue to be, given that there is sidebar navigation as well as collapsible sections, both of which are great UX but need some love to become even better, there is no escaping a certain level of JS.

That said, there is probably a better way than React+build system to have the progressive enhancement. It's true that short of server-side rendering ('isomorphic' apps) there is no easy way to have the business logic not fight for control with the page-loaded logic. IMO all the server-side rendering options for React aren't very good with typing anyways.

This leaves the question about how to make the JS code sustainable, though. I want to experiment with some options for having Rust be smarter about the relationship between JS and the HTML, without involving a JS build system. Closing this issue for now, would love to hear if anyone has further thoughts on this, though.

Was this page helpful?
0 / 5 - 0 ratings