Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to preload a CSS @font-face font that is bundled by webpack4+babel?

Tags:

I have a webpack4+babel bundler setup for a react web app. In a LESS file, I reference a local font. This font gets copied over to the dist folder on build and its filename is hashed. I want to be able to preload this font.

Here is my LESS file:

@font-face {     font-family: 'Test';     src: url('../fonts/test.ttf') format('truetype');     font-weight: 400; } 

I have tried the following approaches but so far with no success:

  1. Add custom import to my app's main JS file.
import(/* webpackPreload: true */ "../fonts/test.ttf"); 

Here is my .babelrc file:

{     "presets": [         "@babel/preset-env",         "@babel/preset-react"     ],     "plugins": [         "@babel/plugin-syntax-dynamic-import"     ] } 

Running webpack does not produce preload directions anywhere as far as I can see in the outputted html - I have searched through the dist folder contents and found nothing.

  1. preload-webpack-plugin

I add this to my webpack.config.js file:

plugins: [   new HtmlWebpackPlugin(),   new PreloadWebpackPlugin({     rel: 'preload',     as(entry) {       if (/\.css$/.test(entry)) return 'style';       if (/\.woff$/.test(entry)) return 'font';       if (/\.png$/.test(entry)) return 'image';       return 'script';     }   }) ] 

This creates preloads for the JS script file bundles but not for the CSS and fonts.

Any ideas on how to get this to work?

like image 614
Frank Avatar asked Mar 28 '19 12:03

Frank


People also ask

How do I add a font to Webpack?

If you have some local font files of your own, place them in a font directory within src and reference them within . style. scss using @font-face as you normally would—webpack will see that you're referencing a font file and run it through the file-loader like it did with Font Awesome and Google Fonts.


2 Answers

was able to make it work on webpack4 by installing version 3beta and using while list option:

yarn add -D [email protected]  new PreloadWebpackPlugin({         rel: 'preload',         as: 'font',         include: 'allAssets',         fileWhitelist: [/\.(woff2?|eot|ttf|otf)(\?.*)?$/i],      }), 
like image 160
Pavel Avatar answered Sep 20 '22 11:09

Pavel


Posting this since I think it might help someone in a similar position - I realize it doesn't solve the described issue.

Had the same problem - didn't need to hash my font-files but had another part of the url that was not static. A bit hackish, but solved my problem. Maybe it can help someone. In theory you can create your own hash-id and set that as the htmlWebpack-plugin variable.

In my index.html

<html>   <head>     <link rel="preload" href="<%= htmlWebpackPlugin.options.woffSrc %>" as="font" type="font/woff" crossorigin>     <link rel="preload" href="<%= htmlWebpackPlugin.options.woff2Src %>" as="font" type="font/woff2" crossorigin>      //rest of html 

webpack.prod.conf.js - updated HtmlWebpackPlugin

plugins: [   new HtmlWebpackPlugin({     ...config,     woffSrc: `https://url.to.my.page.com/${ASSETS_FOLDER}/static/assets/fonts/GilroyRegular.woff`,     woff2Src: `https://url.to.my.page.com/${ASSETS_FOLDER}/static/assets/fonts/GilroyExtraBold.woff2`   }) ] 

I reasoned that the font-files didn't need to have the hash - since that is mainly used to control cache and I won't change the font files, so I turned that of in my webpack file-loader. Please correct me if I'm wrong here.

Having the loader:

{   test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,   loader: 'url-loader',   options: {     limit: 2000,     name: utils.assetsPath('assets/fonts/[name].[ext]')   } } 

Was unable to get the preload-webpack-plugin to work due to build errors and got tired troubleshooting after 2 days.

like image 28
Solders Avatar answered Sep 22 '22 11:09

Solders