Posted 2 months ago. Visible to the public.

Using local fonts with Webpack / Webpacker

When we want to use our own (or bought) fonts in an application with Webpack(er), we have two options. We can

  • put the fonts directly into your Webpack's assets folder or
  • write an npm package with an own sass file that can be imported from the Webpack manifest.

Load fonts from your assets folder

The first option turns out to be straightforward: Import the stylesheets in the index.js of the pack you're using:

Copy
// webpack_source_path/application/index.js import './stylesheets/reset' import './stylesheets/main' // loads the fonts in let stylesheetsContext = require.context('./stylesheets/blocks', true, /\.sass$/) for(let key of stylesheetsContext.keys()) { stylesheetsContext(key) }
Copy
// webpack_source_path/application/stylesheets/main.sass @import 'font_faces' html font-family: MyFont, Arial
Copy
// webpack_source_path/application/stylesheets/_font_faces.sass @font-face font-family: 'MyFont' src: url('../fonts/my_font.ttf')

Webpack will replace ../fonts/my_font.ttf with the compiled filepath (something like media/application/fonts/my_font-f99f9d50a569dbcf72e3084ef1a43208.ttf) and you're good.

Load fonts as an npm package

The second option is handy when you're dealing with fonts that are not maintained by yourself but neither are available on npm. In our case, we purchased a font that had hashed filenames for each font version (normal, bold, …). You don't want to mess around with assets you don't maintain, so renaming them is not a good option. Neither is inserting cryptic filenames to your code a good manner, it can affect readability in a terrible way.
The better option is to bundle your local font into an npm package and to add a dependency in your project's package.json file which loads this bundled font:

Copy
// ./package.json { "name": "my_project", "private": true, "dependencies": { "@rails/webpacker": "^3.0.2", "bought-font": "file:vendor/asset-libs/bought-font" }, "devDependencies": { "webpack-dev-server": "^2.9.5" } }

Note the path's prefix file: in the dependency of 'bought-font', which tells Webpack to not search npm for a matching package, but to look for a local directory.
The directory you are pointing to should also contain a package.json file so Webpack can interpret the folder as an npm package.

Copy
// vendor/asset-libs/bought-font/package.json { "name": "bought-font", "version": "1.0.0", "description": "", "main": "index.scss", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "author": "Salesman of trust", "license": "LICENSE", "private": true }

Webpack will now handle the font as a package and you can import the shipped scss/sass/css file, which contains the font-faces, in your pack's manifest and just use the defined fonts in your application:

Copy
//webpack_source_path/application/index.js import 'bought-font/index.scss'

By refactoring problematic code and creating automated tests, makandra can vastly improve the maintainability of your Rails application.

Owner of this card:

Avatar
Jakob Scholz
Last edit:
about 1 month ago
by Jakob Scholz
Keywords:
webpack, webpacker
About this deck:
We are makandra and do test-driven, agile Ruby on Rails software development.
License for source code
Posted by Jakob Scholz to makandra dev
This website uses cookies to improve usability and analyze traffic.
Accept or learn more