-
Notifications
You must be signed in to change notification settings - Fork 90
State of the Site Architecture March 3 2015
This is the general architecture of the site, as of commit fe7a3ba
on March 3, 2015. If you're reading this much past that date, consider this information historical.
During last week's heartbeat, it was apparent that at least the initial release of the learning website would contain mostly static content. Jekyll was out of the running because it's based in Ruby, and Jon Buckley (jbuck) said that all the Jekyll analogues on Node are really immature. Atul had read about React.renderToString()
and thought it might be useful to experiment with a solution that consisted of pre-rendered, React-based static content that was progressively enhanced by React on the browser. Aside from all the benefits of progressive enhancement, this approach also results in a fast first-load experience.
Note, however, that this solution might not be ideal for the long-term, given the product roadmap, which appears to have some rather dynamic features.
A gulp task uses lib/index-static.jsx
to crawl through all the URLs in the site and render them, via React, as index.html
files under the dist
directory. Meanwhile, webpack generates a client-side bundle.js
file--included by every index page via a script tag--which uses React to bind events to the static markup and add dynamic functionality. Currently, the only obvious example of such dynamic functionality is the collapsible hamburger menu that appears when the browser window is narrow; however, it's also used to leverage the browser's history.pushState()
functionality if available.
-
Most React component code is run in at least two fairly different contexts: once at build time to generate a static
index.html
file, and again in the client's browser. Which context the code is currently running in can be queried through theGENERATING_STATIC_SITE
andIN_STATIC_SITE
constants in thelib/config
module (though another easy way of detecting it is to just see iftypeof(window) == 'undefined'
). -
lib/ia.jsx
contains a React component calledIa
which stands for "internal anchor". Think of it as an<a>
tag that's only used for internal site links. This serves two main purposes:- At build time, it's used to verify that every static link leads somewhere that actually exists.
- At run time, it's used on the client-side to dynamically prevent default navigation and leverage
history.pushState()
if available.
-
lib/pages.jsx
contains aPAGES
constant that maps URLs to functions that return React components. This kind of constitutes an extremely primitive router and it might be useful to migrate to something more robust in the future. It should be noted, however, that we can't lose the ability to be able to iterate through all valid routes for the static site generation phase. -
It's quite possible that writing every single page using JSX could be a total pain, and/or unapproachable by learning team members who might want to edit the site. We can always build some sort of adapter that allows us to plop, say, rendered Markdown into the content area of a page on the site, thus turning our current solution into something more akin to Jekyll.