The Road to the Great Gatsbyjs

reactgatsbyjs

Last week, I pulled the trigger to switch this blog to a new face, — a single page application(SPA) powered by the great gatsbyjs. The transition features:

  • React supports fine-grained component reuse compared the traditional template.
  • GraphQL is a powerful, and more importantly, formal approach to query the data.
  • Everything is modularized, literally everything: the gatsbyjs itself, the underlying markdown transformer remark, the css process pipeline, cssnext, and of course, the awesome webpack.

It also scratches some personal itch:

  • With onCreate API, we can manage the assets in the blog post, such as the illustrations, within the same content of the process pipeline.
  • The remark compiles the markdown source file to the syntax AST, which attracts 3rd-party plugin authors to establish a prosperous ecosystem.

The road is quite rocky. It takes roughly 8 months to see the light since the first line is checked in. To be fair, the complexity of gatsby migration only account for a small fraction, I also take the advantage of the migration to revamp the UI, proof read the blog posts, and learn some new tricks in the front end engineering. Here are some highlights (or lowlights):

Functional CSS with tachyons

The CSS is arguably the worst language in the world due to the lack of the namespace. There are many attempts to address the issues: BEM, Block Element Modifier, CSS modules. I decided to take one step further to embrace the functional CSS with tachyons: the HTML element is stylized explicitly with the predefined classes, and each class is atomic without side effect. A highly stylized title will look like:

<h1 class="f2 f1-ns lh-title mb2">The Road to the Great Gatsbyjs</h1>

The challenge of the approach comes from the static content pipeline: it is tedious to stylize the HTML element in the markdown source file. The postcss-extend plugin comes to rescue: it supports @extend syntax just like sass:

.article h2 {
  @extend .f3;
}

And there is cssnext to make writing CSS stylesheets less painful.

Print-first vs. Mobile-first

The resume page refactory is probably the most frustrating UX work so far. It is supposed to be optimized for printing while tachyons has little if any support on print media responsive design. I had to extend the responsive design to the print media query, and add print-specific classes such as .pt0-print to fine-tune the layout. It is also worthy noting that major browser render slightly differently in the print media. I managed to fit the resume page into one letter page in Chrome, but throws the towel for Firefox after several hours fruitless attempts.

Tips: both Firefox and Chrome support print media emulation:

  • In Firefox, press Shift+F2 or click Tools -> Developer Toolbar, then type media emulate print.
  • In Chrome’s Developer Tools, press Cmd+Shift+P, then start typing print, click the Emulate CSS print media type

Assets management

Historically, the assets of this site were stored separately in the absolute path because WordPress did not support assets upload at that moment. With the help from gatsby-remark-images and gatsby-remark-copy-linked-files plugins, I can store the the assets close to the blog post, and reference with relative path. I encountered some issues for the image resampling, so I ended up extending the gatsby-remark-copy-linked-files functionality to all linked files with a home-brewed plugin.

Tags Support

It is surprising that the tag support is not trivial even with powerful GraphQL.

First, the GraphQL does not support the discoverability. For example, I cannot query the set of tags used in all the blog posts defined in the frontmatter.tags field. I have to aggregate in the createPages callback.

I also want to create a RSS feed for each tag, thus I can submit each topic to a relevant aggregator. I spent last couple weeks hacking it, and triaged it is not a blocking issue. I will add the feature later.

Conclusion

The gatsbyjs is the next generation static site generator. It has some best bits in the front end engineering to achieve high performance and rich features. It is such a pleasure to work with it.