Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to distribute fonts or other static assets with a React component library built using Webpack?

I am trying to include some fonts with a component library that I will distribute as an UMD bundle generated with Webpack and installed as an NPM module; the components make use of those fonts. The problem is that URLs pointing to the fonts in the generated bundle are incorrect and result in 404s when the application that uses the library is run.

For example, resolve-url-loader will output a URL of "/myfont.woff". But of course, that file is not actually available at that URL in the application unless the application that uses it does some configuration to copy that file and serve it at the expected path.

Is there a way to automatically make these fonts available (i.e., font-face: 'My Font' will work) when an application imports a component from my library, minimizing amount of configuration needed in the application that uses it?

For large files, I don't want to use url-loader and Base 64-encode them and I can't use a CDN.

like image 328
xli Avatar asked Nov 06 '17 21:11

xli


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.

Is Storybook a component library?

The story of Storybook, a tool that can help combine your design, development, and customer teams. The story of Storybook, a tool that can help combine your design, development, and customer teams.


2 Answers

I think the easiest way is to provide a .css file where your assets are being used through relative url(...) statements. Then, having something like

...
{
  test: /\.css$/,
  use: ['style-loader', 'css-loader'],
},
{
  test: /\.(eot|svg|ttf|woff|woff2|png|jpg)$/,
  use: ['file-loader'],
},
...

in their webpack.config.js and your .css file imported in their code, they will be able to use the assets by automatic transferring them to their output public directory (URLs should be also automatically adjusted in the result CSS bundle).

You might take a look, for instance, to Onsen UI library, that offers to embed their assets and styles through these files:

import 'onsenui/css/onsenui.css';
import 'onsenui/css/onsen-css-components.css';

Here is an example of how they use fonts through relative URLs there:

@font-face {
  font-family: 'Material-Design-Iconic-Font';
  src: url('../fonts/Material-Design-Iconic-Font.woff2') format('woff2'), url('../fonts/Material-Design-Iconic-Font.woff') format('woff'), url('../fonts/Material-Design-Iconic-Font.ttf') format('truetype');
  font-weight: normal;
  font-style: normal;
}
like image 167
Dmitry Druganov Avatar answered Sep 16 '22 15:09

Dmitry Druganov


You need some loaders to do that task . to fix large file size issue i use file loaders.

      { test: /\.eot(\?v=\d+.\d+.\d+)?$/, loader: 'file-loader?name=assests/fonts/[name].[ext]' },
      { test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/, loader: 'file-loader?mimetype=application/font-woff&name=assests/fonts/[name].[ext]' },
      { test: /\.[ot]tf(\?v=\d+.\d+.\d+)?$/, loader: 'file-loader?mimetype=application/octet-stream&name=assests/fonts/[name].[ext]' },
      { test: /\.svg(\?v=\d+.\d+.\d+)?$/, loader: 'file-loader?mimetype=image/svg+xml&name=assests/fonts/[name].[ext]' },
      { test: /\.(jpe?g|png|gif|ico)$/i, loader: 'file-loader?name=assests/images/[name].[ext]' },

finally use import statements to import the css files of the fonts

import from ./assets/fonts/abc.css

but make sure you have webpack css loaders setup

like image 44
hannad rehman Avatar answered Sep 20 '22 15:09

hannad rehman