BurkovBA.github.io is online!
December 14, 2017 3 min read
I've been procrastinating over my blog for almost a year. Initially I wrote it in Angular in early 2017 and re-wrote everything in React in the last couple of weeks. At last, following Github's "ship early - ship often" motto, I shipped it today. Probably the most challenging aspect of the whole work was to make Github pages play nice with React SPA - I'll tell you how in this post.
My blog makes use of a pretty minimalistic toolchain by modern standards:
- React 16
- React Router v4
- Codebase scaffolded in spirit of this post from Medium (no create-react-app or Yeoman)
- No state management like Redux/Flux/MobX
- Scripts in EcmaScript 6 transpiled with Babel (no Flow or Typescript)
- Styles in SASS, copy-pasted from a nice Homer theme for Bootstrap 3
- NPM package.json for dependencies, no Yarn (or Bower obviously)
- NPM scripts to build it all (no Gulp/Grunt)
- Webpack 2 to bundle it all (with devServer for local development)
- Github pages to "host" and serve it
Project needs to be served in 2 environments. In development it needs to be rebuilt upon every change (or, to be precise, each part of it that ) and served from local machine with WebpackDevServer. In production it is served with with Github pages web server.
This causes several problems.
How to serve
index.html not from project root, but from
My webpack setup works as follows: all the source files are located in
/src folder, while files generated
from them go to
/dist. Those initially included
/dist/index.html, generated from a template
/src/index.html by HtmlWebpackPlugin.
Thing is, Github pages won't serve
index.html from subdirectory and there's no way to customize its location
for per-user or per-organisation sites (although, per-repository sites can serve files from
folder). Also project github pages can serve files from branches other than master, e.g.
but again this is not an option for per-user or per-organiation sites.
Thus my first solution was to create a proxy
/index.html file in root folder of repository that
<html> <head> <meta http-equiv="refresh" content="0; url=https://BurkovBA.github.io/dist/index.html" /> </head> </html>
However, this solution is not optimal: if somebody wanted to share a url, such as BurkovBA.github.io/blog/2017-12-14-1, they'll get 404 error.
Hence, in production I configured HtmlWebpackPlugin to put the built
index.html into the root
folder instead of
/dist, but that required additional tweaks of WebpackDevServer, which expected
it in dist. Thus I had to create a conditional build and set configuration variables in webpack.
How to run different webpack configurations for production and development?
Webpack 2 can consume environment variables from command line, in the form of arguments
use them to conditionally switch some webpack configuration settings in production/development in npm scripts.
How to make Github serve direct links to SPA pages (e.g. BurkovBA.github.io/blog/2017-12-14-1)?
Ok, this still doesn't solve the problem of direct links. I found a brilliant solution on Github by Rafael Pedicini.
It works as follows: when you request some url of your SPA, which doesn't correspond to any file in your repository, Github server returns 404 error.
Here's the catch: you can customize your
404.html page! So, you create a custom 404 error with
a script. That script parses url that you passed, transforms path components into URL params (aka GET params) and
index.html. For instance,
p parameter back into a proper URL and initializes React SPA.