Netlify
Netlify: "An all-in-one workflow that combines global deployment, continuous integration, and automatic HTTPS. And that’s just the beginning"
Netlify has been a popular static site hosting provider since around 2016 See (
- Ask HN: What free or low-cost static site hosting do you use most?
- Static website hosting: who's fastest? AWS, Google, Firebase, Netlify or GitHub?
- What is the best static website hosting provider?
);
⚔ Github Pages vs. Netlify
This site, has been hosted on Github Pages since 2013 (See 'How I Use Github Pages to Host My Blog'). I am currently satisfied with using it as a hosting option for a site of this scale. However, some more complex projects may require the more sophisticated features offered by Netlify.
These features are outlined here: 'GITHUB PAGES VS. NETLIFY: Netlify is the upgrade you're looking for':
GithubPages | Netlify | |
---|---|---|
Build Limits | 10 Builds per hour | 3 Builds per minute |
1-click Rollbacks | ❌ | ✅ |
Asset Optimizations | ❌ | ✅ |
Form Handling | ❌ | ✅ |
Deploy Previews | ❌ | ✅ |
Continuous Deployment | ❌ | ✅ |
Custom Rewrites & Redirects | ❌ | ✅ |
Compatible w/All Static Site Generators | ❌ | ✅ |
Prerendering | ❌ | ✅ |
Split Testing | ❌ | ✅ |
Lambda Functions Integration | ❌ | ✅ |
Given the potential to use these features in other projects, I decided to give Netlify a whirl 🌬.
🛳 Initial Deploy
A Step-by-Step Guide: Deploying on Netlify outlines a straightforward process for deploying a site to Netlify. This article sufficed for me, except for one small hiccup I ran into when Netlify tried to build my site.
Cannot Resolve Module
My first build spit out this error:
9:52:49 PM: Error: ./src/pages/posts.tsx
9:52:49 PM: Module not found: Error: Can't resolve '../components/content/' in '/opt/build /repo/src/pages'
9:52:49 PM: resolve '../components/content/' in '/opt/build/repo/src/pages'
Indeed my while posts.tsx
was looking for a file called ../components/content/
, the file actually was named ../components/Content/
:
$ head -n1 src/pages/posts.tsx
import Content from '../components/content/'
$ ls src/components/
AlbumArtwork FixedMenu Logo Table
AlbumMediaCard Footer MailingListHalf Tabs
BaseMeta Half MenuToggle disqus
Breadcrumbs LatestRelease OverlayMenu
*Content* Layout ResponsiveMenu
EventIndex LocationMap.tsx SocialButton
On MacOS this type of casing mismatch is acceptable. However, the netlify-build-image requiers Ubuntu which respects directory casing. This issue took me a while to identify, so its worth considering prevention options: [] Typescript: file-name-casing rule would prevent, and automatically fix these issues in the future [] Using the netlify-build-image to develop could have identified this issue more quickly
Deploy Complete!
The site is located here: https://richsoni.netlify.com/
It was that easy!
Debugging with the netlify-build-image
When researching prevention tactics for the casing mismatch error I faced, I found this library: netlify-build-image. The ability to locally build that container, and debug issues seems very valuable to me. In the past, I have wasted a lot of time by redeploying changing up to the CI server when trying to fix a build. So, I decided to check netlify-build-image out.
Setup
The instructions for netlify-build-image are fairly clear, and simple: I followed .Testing Locally, and pulled the docker image:
docker pull netlify/build
However, there was one thing that was not clear in the instructions: It was not clear that you had to clone the [netlify/build-image] repository.
I opened a Pull Request (https://github.com/netlify/build-image/pull/252) with the tool to make the instructions more clear. Hopefully they take the suggestions.
The Build
Since my build worked on Netlify, I expected to run build yarn build
in the container without any issues.
This was inded the case:
~/code/github/netlify/build-image(master)------------------------------------------------------------------------
$ ./test-tools/start-image.sh ~/code/personal/richsoni.github.io
buildbot@46702c0a6065:/$ build yarn build
...(Docker running the build)
Caching artifacts
Started saving node modules
Finished saving node modules
Started saving yarn cache
Finished saving yarn cache
Cached node version v9.11.2
Reproducing the error
One thing to note from the README for netlify-build-image is the code to be tested needs to be committed tk. I added the error back:
//./src/pages/posts.tsx
import Content from '../components/content/'
Voila, the error is reproduced:
$ ./test-tools/start-image.sh ~/code/personal/richsoni.github.io buildbot@50750cae5d63:/$ build yarn build
Cloning into '/opt/buildhome/repo'...
... Other Output
Error: ./src/pages/posts.tsx
Module not found: Error: Can't resolve '../components/content/' in '/ opt/buildhome/repo/src/pages'
...
Depending on @netlify/build-image
The netlify-build-image is published as a public npm project.
So, it can be added to a project as a devDependency
:
yarn add --dev netlify/build-image
Wrapping @netlify/build-image
I wrote two scripts to wrap this library:
$ cat script/netlify-build
#!/usr/bin/env bash
if git diff-index --quiet HEAD --; then
PROJECT_DIR=`pwd`
: ${1?"Usage: $0 First Argument must be the build command to run in the Netlify Image"}
cd node_modules/@netlify/build-image
./test-tools/test-build.sh $PROJECT_DIR 'yarn run bootstrap_and_build'
else
echo "Can only run this command with a clean git directory"
fi
$ cat script/netlify-start-image
#!/usr/bin/env bash
if git diff-index --quiet HEAD --; then
PROJECT_DIR=`pwd`
cd node_modules/@netlify/build-image
./test-tools/start-image.sh $PROJECT_DIR
else
echo "Can only run this command with a clean git directory"
fi
The way I use them is described in the package.json
:
$ cat package.json | grep 'netlify:build'
"netlify:build": "./script/netlify-build 'yarn run build'",
"netlify:start-image": "./script/netlify-start-image"
This allows me to interact with the netlify-build-image in a few different ways:
# Testing the build
$ yarn run netlify:build
=> $ ./script/netlify-build 'yarn run build'
... {OUTPUT}
✨ Done in 406.96s.
# Debugging the build
$ yarn run netlify:start-image
$> build 'yarn run build'