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:
// 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) }
// webpack_source_path/application/stylesheets/main.sass
@import 'font_faces'
html
font-family: MyFont, Arial
// 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:
// ./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.
// 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:
//webpack_source_path/application/index.js
import 'bought-font/index.scss'