The Road to the Great Gatsbyjs
react gatsbyjsLast 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.