Skip to content
This repository has been archived by the owner on Mar 5, 2020. It is now read-only.

State of the Site Architecture March 3 2015

Atul Varma edited this page Mar 3, 2015 · 4 revisions

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.

Motivation

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.

How It Works

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.

Other Notable Things

  • 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 the GENERATING_STATIC_SITE and IN_STATIC_SITE constants in the lib/config module (though another easy way of detecting it is to just see if typeof(window) == 'undefined').

  • lib/ia.jsx contains a React component called Ia 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:

    1. At build time, it's used to verify that every static link leads somewhere that actually exists.
    2. 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 a PAGES 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.