Learning React and Gatsby by building a blog

One of the benefits of trying to learn a new toolset this way is that I run into problems, which takes me to Google, which takes me to great resources I would not have otherwise discovered.

Case in point:

I found the Chronoblog theme because I ran into issues with trying to use theme-ui with the scaffolding I had set up during the tutorial.

Chronoblog is exactly the kind of site I’m trying to build for myself, though it is a bit more basic than I had in mind. For context: I’m aiming to build a site that promotes me as a speaker, panel host, and roundtable/workshop facilitator, and which also serves as a repository for all of my work.

Considering that I was not able to get as far as I wanted to this weekend—and that the problems I’ve been having with theme-ui probably means there’s a lot of learning ahead of me yet—I thought it might be time to enter “just get it done” mode and use the Chronoblog starter to get something basic up and code my own custom site over the next few months as I properly learn React and Gatsby.

So I do the gatsby new pull from Github, run yarn, and lo! my old error is back:

spawn /mnt/src/node_modules/cwebp-bin/vendor/cwebp ENOENT

When I try and run that binary (despite the ENOENT error, it is actually physically present on the filesystem), I get the very confusing error:

/bin/sh: ./node_modules/cwebp-bin/vendor/cwebp: not found

At first I thought it might be a filesystem issue with the way stuff is virtualised on Windows, but after a bit of reading, I think the issue is Alpine. It seems that sometimes yarn will pull a binary that can execute on Alpine, and other times it’ll pull a binary that can’t. Apparently it may also be a musl vs glibc issue.

I’m still not 100% sure what causes the cwebp binary to work in my tutorial project (except that one time it broke spectularly), and not with the Chronoblog starter. However, I am in “just get it done” mode, so I decided to ditch Alpine and with it Docker on Windows, and try WSL.

“Bonus,” I think. “That means I’ll be able to use VS Code’s WSL integration.”

!jarringerrorsound-aladdingenie.robinwilliams WRONG!

I fire up WSL, install nvm, install Node.js 12, npm i -g gatsby-cli, and grab the Gatsby starter with gatsby new.

npm install runs without a problem, as does the first execution of gatsby develop. Another benefit of running in WSL rather than Docker is that the -o flag works — I can launch a development server and open a browser window at the same time. Hooray for small victories!

Then I launch VS Code from inside WSL, start making changes to the source, and the development server starts throwing up errors. The warning just before the errors has me worried:

warn Error persisting state: EACCES: permission denied, rename

Once again, I worry that this is some kind of filesystem issue on Windows, so I rename all my directories so they don’t have spaces in them. Doesn’t fix the issue.

Turns out it is a filesystem issue on Windows, but it has to do with VS Code, which apparently locks some directories when you run it from inside WSL.

See:

So I kill VS Code and use something else to make changes to the source. I’m still getting errors from the development server, but at least that warning about being unable to rename a file/directory is gone.

It turns out there must have been some kind of change in the way gatsby-config.js works between when the Gatsby Chronoblog starter was published and today.

Previously there were a bunch of parameters that you needed to define inside the plugins section of the module.exports object.

It would go:

plugins: [
  {
    resolve:  'gatsby-theme-chronoblog',
    options: {
      feedSearch: {
        symbol: '🔍'
      },
    }
  }

But all of that stuff apparently needs to go in the main siteMetadata object, and not the plugin parameters anymore.

The theme developers also added in a query for an altText parameter somewhere along the way which caused things to break.

Now that I’ve added that stuff into my siteMetadata, it looks like I’m in business!

2 Likes

Oh the joys of debugging. This scenario reminds me of the countless hours I spent trying to decode a binary stream I got that was received from an IoT device to a structured JSON string - in Node.js! It only had partial binary decoding support and all the packages I tried failed. So I ended up rolling my own binary interpreter with the ability to supply the struct format that it expects the output to conform to. To this day it was some of the most challenging and rewarding work I’ve done.

1 Like

Even though I write js test scripts to test websites created with react/angular and vue.js, most of what is contained in this post is barely understandable to me.

but

Like much of the tech discussions that the devs do with me in the meetings, I still find it interesting in a peripheral sort of way.

1 Like

Whenever I embark on a project like this, I always learn the weirdest things.

While searching the Font Awesome library for a brand icon for the Ghost CMS, I discovered the “GG” brand icon.

image

I did not recognise it at all, but saw that it was listed under Font Awesome’s “currency” category. Searching “gg currency” yielded this Reddit thread:

Which led to this Twitter post:

Which led to this Twitter account which seems to have just hijacked the logo for their own purposes:

https://twitter.com/SkinsanityGG

It’s like Internet archaeology!

1 Like

That is just absurd. Good find! :ok_hand::sweat_smile:

1 Like

Where is the “WHOOSH OVER MY HEAD” emoji?

4 Likes

I’m running into performance issues with the Gatsby development server when my site starts getting to over 1000 posts / bits of content.

So to try and see if it’s just a dev server thing, or something to do with Gatsby or React itself I decided to create a production build of my site for the first time.

Naturally, I ran into an error:

EMFILE: too many open files

It looks like I may need to increase the maximum number of open file descriptors allowed on the Ubuntu I’m using in WSL.

Hopefully it’s as easy as this post on Stack Overflow suggests:

Struggling to increase the limit of the maximum number of file descriptors, but I did get as high as 4000 (default is 1024). The error didn’t go away.

So I ran a yarn clean / gatsby clean and am trying to rebuild the project. It is incredibly resource intensive and quite slow.

Here’s Task Manager:

image

The process got stuck here for ages:

And now it seems stuck here:

Not sure why it’s so slow. I’ll let it run its course for now.

Update: It’s definitely not stuck, but extremely slow for whatever reason:

It took nearly 2 hours to build the website.

This… is going to be a problem.

So it built all the pages as static content, Jamstack style? With a site that is going to be quite data driven (I assume), is it not more efficient to plug in a database or backend with dynamic templates for the posts? I assume that would ease the build time considerably…

1 Like

Perhaps. Since I don’t need dynamic or user-provided content, I figured I’d avoid a database entirely to keep my attack surface small.

Gatsby does mercifully seem to have good caching, so as long as I don’t run a clean before every build, it doesn’t seem to take too long.

But yeah… depending on how this experiment pans out, my learning experience may have to extend to setting up a headless CMS of some kind to feed into a more dynamic React site rather than relying on static site generation.

Had a breakthrough yesterday regarding the build time issue. It was one of those solutions that just comes to you while in the shower.

The Gatsby theme I’m using (Chronoblog) puts a list of posts below every post. So when generating the site it doesn’t just have to build the main index of posts once… it builds it for every single page.

To test my hypothesis I “shadowed” the content_bottom.mdx file and removed the <FeedItems /> component, i.e. made it so that the bottom of every page does not contain a list of posts.

That one change reduced my build time from almost 2 hours to under 20 minutes. All 1400+ pages now build in just over 11 minutes, give or take a few unmeasured minutes.

So that resolves my initial build time question. Now I have to figure out whether the site’s initial load and responsiveness will be as slow in production as in development. Looking at Lighthouse in Chrome, 5MB is downloaded in the JavaScript bundle before the site is even displayed. There has to be a way to reduce that size, even if I do want over 3,000 pages on my site.

Well, if it’s all bundled up in a single JS file with no splitting and lazy loading, then I don’t really see any other way around a large bundle. Most bundlers like Webpack allow for splitting and lazy / on-demand loading of imports. Maybe Gatsby has a config allowing something similar? I’m not sure which bundler they use though.

The alternative is still to go headless CMS route :blush:.

1 Like

Gatsby uses Webpack, at least.

I’ll forge ahead with the grindiest part of this (going through all my work and deciding what to include) and then see whether Gatsby has some smart optimisations at build time that makes the website faster in production than on the dev server.

If it’s still slow after being deployed to Github Pages, I’ll look into it further.

Holy crap, where have I been? Reading people’s experiences while they learn new tools is always an cool experience. My bread and butter for the last 2 years has been Angular, and I’ve recently started learning and dabbling in UI/UX design because I want a better understanding of building design systems (I’ve been playing around with Figma as my tool in that regard).

4 Likes

My dude… Welcome :smiley_cat:

3 Likes

If your main issue at load is your js bundle, maybe a web worker might be a possible solution (not that I know the implementation or how they work in react exactly)? Basically process in a different thread that doesn’t block the rendering of your ui.

2 Likes