Upgrading from Font Awesome 5 to 6
Let's say the company you work for has self hosted Font Awesome (FA) version 5 on their web app and you wish to upgrade to version 6. How would you go about that ensuring that you've covered all your bases? Here are the steps that I did followed by one gotcha I learned post-upgrade where customers saw squares instead of icons! Take these as general tips or guidelines since it may not work in your situation; customize to fit/solve your scenario.
Read FA's changelogs for any breaking changes. For example, I noticed that version 6 does not support IE 10 or 11. So if your users still use IE 11, you may have to think twice about upgrading.
- Notice that v.6 is backward compatible with v.5
Any icons that had their name changed in Version 6 will work and render as expected when referenced by their old name
- Notice that v.6 is backward compatible with v.5
I needed some way to capture all the FA icons in one page -- that way I don't have to test every single page in the app just to find out if there's something wrong with the icon. Wouldn't it be great to have all the icons on just one page? But to do so, I would need some way to collect all the hundreds of icons used in the app. Thinking back to days of linux terminal commands, I remembered that either grep, awk or sed would probably help me find those icons. After a bit of research, I typed the following terminal command:
grep "fa-" -r src > fa.txt
Grep is a command that takes a directory as input. In my case I wanted grep to start searching in my ./src directory but also search every subfolder within that. That's what the
-r
flag does; it searches recursively. I then told grep to find every single instance where FA icons were used. Since all FA icons begin with "fa-", that's what I used as the keyword to search. By default grep will output to the terminal all lines of code where the keyword was found. However, in my case I decided to redirect the output into a text file instead, thus,> fa.txt
Now that I have a list of all lines of code in the web app that contains "fa-", I wanted to narrow it down further to only "fa-" words. How can I eliminate all the other words contained in that same line of code where "fa-" was found? After a bit of trial/error and research, I typed:
grep -E -o '(fa-\w+-*\w+-*\w+-*\w+-*)' fa.txt | sort -n | uniq > fa2.txt
The above command takes that list in fa.txt, extracts only "fa-" words that have at most 4 hyphens in its name (noticed I used -E in order to use a regular expression), sort it, extracts only unique values, and put it all in another list I called fa2.txt
In my code editor, I did a global search in the web app for all "fa-" instances and I visually compared the search results with the compiled list in fa2.txt to ensure correctness and completeness.
- this is where I found the need to adjust my regular expression to account for a possibility of 4 hyphens in the FA icon name
- some icons may need to be removed because it's not a font, but rather an effect like
fa-spin
orfa-2x
; but save these effects for later - you may discover that some icons were coded that don't actually exist!
I then created a hidden playground page in our app (using React) that displayed a table of all the icons that I collected in fa2.txt (stuck the whole list in an array and mapped over it to display the table). The left column was the name of each icon. The other columns were all the relevant FA effects that I collected/saved from fa2.txt such as: far, fas, fa-spin etc.
I video recorded my screen as I did a global search in my code editor for all reference to the word 'awesome' -- this is so I can later view the original state of files, like package.json or webpack.config.js, to see if references to font awesome have been changed.
Following FA's documentation "Upgrade from Version 5 When Self-Hosting", I first located and removed any version files from my project
- Deleted .build/dist/fontawesome/
- Initially I ran
npm uninstall @fortawesome/fontawesome-pro@5.15.2
but noticed this command didn't work. How did I know? package.json still showed @FortAwesome listed under dependencies. Hmm perhaps I should skip the version number? - Ran
npm uninstall @fortawesome/fontawesome-pro
- the above command worked! package.json removed it as a dependency
- package-lock.json also removed all font awesome references
- checked under node_modules/, it removed all directories under @FortAwesome, but left @FortAwesome existing as an empty directory. Should I delete that empty directory?
- deleted @fortawesome/ (empty directory anyways)
- refreshed my icons list table, as expected, no more icons are showing
Install version 6
- Ran
npm install --save @fortawesome/fontawesome-pro
- Worked! package.json now shows
"@fortawesome/fontawesome-pro": "^6.1.1"
- package-lock.json now shows references to it as well. When I compare with my previous video recording, all v.5 references have been replaced with v.6
- /build/dist doesn't have fontawesome yet, as expected since webpack has yet to compile it there
- compared video recording to current state of ./node_modules/@fortawesome/
- Checked webpack.config.js and all old existing references to fontawesome still applies to new v6 - so no change necessary (hint: this was the source of my 'gotcha' later regarding cache-busting)
- Ran
Let's try it out. ran
npm start
- ./built/dist now has fontawesome folder. When compared with my video recording, old css/ and webfonts/ folders have been updated. Again, only .ttf and .woff2 font type files exist (older .eot, .svg and .woff files no longer exist but wasn't a problem in my case since we never used those files)
- refreshed my table list of icons -- all fonts showed
- But other places in my webapp where icons should have showed only showed squares. I ran
npm start
again but that didn't fix it. - Realized I still had to update all font-family references. Changed all font-family references in 13 .less files from Font Awesome 5 Pro to Font Awesome 6 Pro; Refreshed, all webapp icons now showed
Compare video recording to index.html references -- no changes needed, all references to .woff2 and .min.css files already point to updated (but unchanged) filenames in dist/fontawesome
Compared .storybook/preview-head.html. Old code had a link tag with an href to v.5 along with the integrity hash. Where do I get the newly updated v.6 link tag? I eventually updated storybook to use v.6 using the imported styles method instead.
Final comparison of video recording to now -- all checks out. Noticed semver on old package.json/package-lock.json said "5.15.2", whereas new version has caret "^6.1.1". Fortunately, my linter said I should remove caret so I changed it to "6.1.1"
Summary
After updating font awesome to version 6, there were some more back and forth with Product/Design as they checked all icons in our webapp for consistency and correctness. It was finally deployed! All was well... until a few hours later my manager said that users were experiencing square icons! Now if they refreshed, then they saw the updated icons.
Urgent Fix
My manager said it had something to do with the cache and we had to clear it. I didn't know how to do that. Fortunately my memory vaguely remembered a podcast regarding this situation. Instinctively I wanted to change either the filename of the FA css file or change 1 character in the url query string. I found an article that verified my proposed solution. In webpack.config.js, the problem was our cache-busting algorithm didn't change our url query string because the v.6 file names/directories stayed the same. So I appended a single character - '6' to the end of the cache string, and after verifying that fix on staging, we deployed the fix a half hour later.
Lesson to be learned
When updating font awesome, or any css related files, remember to check your webpack config to see if it cache-busts. If not, users' browsers will attempt to use the cached v.5 instead of the newer v.6