如何在 Material UI 的 webpack 构建中包含 Roboto 字体?

How to include Roboto font in webpack build for Material UI?

对于基于 Material UI (React) 并使用 Webpack 构建的 progressive 网络应用程序,我如何正确地包含Roboto 字体使应用程序不依赖于 Google 服务器并且字体也可以工作 离线 ?

那么,将正确 Roboto 文件与我的应用程序捆绑在一起的简单好方法是什么?

这就是我的团队如何将 Roboto 字体包含在我们的 Webpack 项目中:

下载 Roboto 字体并在字体特定文件夹中制作 CSS 文件

  • 创建文件夹(/fonts)。
  • Font Squirrel 下载所有 Roboto 字体。转到 Webfont Kit 选项卡,然后使用默认设置按 下载 @font-face Kit 按钮。
  • 将字体移至 /fonts
  • 创建 CSS 文件 (/fonts/index.css)。我们从 this tutorial.
  • 获得了这个文件的内容

index.css:

* {
  font-family: Roboto, sans-serif;  
}

@font-face {
    font-family: 'Roboto';
    src: url('Roboto-Regular-webfont.eot');
    src: url('Roboto-Regular-webfont.eot?#iefix') format('embedded-opentype'),
         url('Roboto-Regular-webfont.woff') format('woff'),
         url('Roboto-Regular-webfont.ttf') format('truetype'),
         url('Roboto-Regular-webfont.svg#RobotoRegular') format('svg');
    font-weight: normal;
    font-style: normal;
}
 
@font-face {
    font-family: 'Roboto';
    src: url('Roboto-Italic-webfont.eot');
    src: url('Roboto-Italic-webfont.eot?#iefix') format('embedded-opentype'),
         url('Roboto-Italic-webfont.woff') format('woff'),
         url('Roboto-Italic-webfont.ttf') format('truetype'),
         url('Roboto-Italic-webfont.svg#RobotoItalic') format('svg');
    font-weight: normal;
    font-style: italic;
}
 
@font-face {
    font-family: 'Roboto';
    src: url('Roboto-Bold-webfont.eot');
    src: url('Roboto-Bold-webfont.eot?#iefix') format('embedded-opentype'),
         url('Roboto-Bold-webfont.woff') format('woff'),
         url('Roboto-Bold-webfont.ttf') format('truetype'),
         url('Roboto-Bold-webfont.svg#RobotoBold') format('svg');
    font-weight: bold;
    font-style: normal;
}
 
@font-face {
    font-family: 'Roboto';
    src: url('Roboto-BoldItalic-webfont.eot');
    src: url('Roboto-BoldItalic-webfont.eot?#iefix') format('embedded-opentype'),
         url('Roboto-BoldItalic-webfont.woff') format('woff'),
         url('Roboto-BoldItalic-webfont.ttf') format('truetype'),
         url('Roboto-BoldItalic-webfont.svg#RobotoBoldItalic') format('svg');
    font-weight: bold;
    font-style: italic;
}
 
@font-face {
    font-family: 'Roboto';
    src: url('Roboto-Thin-webfont.eot');
    src: url('Roboto-Thin-webfont.eot?#iefix') format('embedded-opentype'),
         url('Roboto-Thin-webfont.woff') format('woff'),
         url('Roboto-Thin-webfont.ttf') format('truetype'),
         url('Roboto-Thin-webfont.svg#RobotoThin') format('svg');
    font-weight: 200;
    font-style: normal;
}
 
@font-face {
    font-family: 'Roboto';
    src: url('Roboto-ThinItalic-webfont.eot');
    src: url('Roboto-ThinItalic-webfont.eot?#iefix') format('embedded-opentype'),
         url('Roboto-ThinItalic-webfont.woff') format('woff'),
         url('Roboto-ThinItalic-webfont.ttf') format('truetype'),
         url('Roboto-ThinItalic-webfont.svg#RobotoThinItalic') format('svg'); (under the Apache Software License). 
    font-weight: 200;
    font-style: italic;
}
 
@font-face {
    font-family: 'Roboto';
    src: url('Roboto-Light-webfont.eot');
    src: url('Roboto-Light-webfont.eot?#iefix') format('embedded-opentype'),
         url('Roboto-Light-webfont.woff') format('woff'),
         url('Roboto-Light-webfont.ttf') format('truetype'),
         url('Roboto-Light-webfont.svg#RobotoLight') format('svg');
    font-weight: 100;
    font-style: normal;
}
 
@font-face {
    font-family: 'Roboto';
    src: url('Roboto-LightItalic-webfont.eot');
    src: url('Roboto-LightItalic-webfont.eot?#iefix') format('embedded-opentype'),
         url('Roboto-LightItalic-webfont.woff') format('woff'),
         url('Roboto-LightItalic-webfont.ttf') format('truetype'),
         url('Roboto-LightItalic-webfont.svg#RobotoLightItalic') format('svg');
    font-weight: 100;
    font-style: italic;
}
 
@font-face {
    font-family: 'Roboto';
    src: url('Roboto-Medium-webfont.eot');
    src: url('Roboto-Medium-webfont.eot?#iefix') format('embedded-opentype'),
         url('Roboto-Medium-webfont.woff') format('woff'),
         url('Roboto-Medium-webfont.ttf') format('truetype'),
         url('Roboto-Medium-webfont.svg#RobotoMedium') format('svg');
    font-weight: 300;
    font-style: normal;
}
 
@font-face {
    font-family: 'Roboto';
    src: url('Roboto-MediumItalic-webfont.eot');
    src: url('Roboto-MediumItalic-webfont.eot?#iefix') format('embedded-opentype'),
         url('Roboto-MediumItalic-webfont.woff') format('woff'),
         url('Roboto-MediumItalic-webfont.ttf') format('truetype'),
         url('Roboto-MediumItalic-webfont.svg#RobotoMediumItalic') format('svg');
    font-weight: 300;
    font-style: italic;
}

使用 file-loader webpack 模块加载字体文件,以便 webpack 可以识别它们

webpack.conf.js:

loaders: [
  ..., {
    test: /\.(woff|woff2|eot|ttf|svg)$/,
    loader: 'file-loader',
    options: { name: '[name].[ext]', outputPath: 'fonts/', }
  },
  ...
]

在app主入口导入字体css文件

App.js:

import './fonts/index.css';

就是这样。您的应用程序的默认字体现在应该是 Roboto。

编辑:Material-UI 实际使用哪些 Roboto 字体?

这个问题的一部分是确定要包含在项目中的 正确 Roboto 字体,因为整个 Roboto 字体几乎是 5MB。

README, the instructions for including Roboto point to: fonts.google.com/?selection.family=Roboto:300,400,500. Here, 300 = Roboto-Light, 400 = Roboto-Regular, and 500 = Roboto-Medium. These correspond to the font weights defined in the typography.js file. While these three font weights account for usage in almost the entirety of the library, there is one reference to Regular-Bold in DateDisplay.js。如果您不使用 DatePicker,您应该可以安全地忽略它。除了 GitHub 降价样式之外,项目中的任何地方都没有使用斜体字体样式。

此信息在撰写本文时准确无误,但将来可能会发生变化。

如果应用程序是使用 create-react-app 启动的,它没有 [可见的] webpack 配置文件。在这种情况下,您可以执行以下操作:

  1. 在 /public
  2. 中创建 /fonts 目录
  3. 创建 /public/fonts/fonts.css,定义 @font-faces

    @font-face { font-family: 'inglobal'; font-weight: normal; font-style: normal; src: url('./OperatorMono.ttf'); }

  4. 复制字体文件

  5. 添加 <link rel="stylesheet" href="%PUBLIC_URL%/fonts/fonts.css"> 到 /public/index.html 的

  6. 欢呼!

5/b。如果出于任何原因,它仍然不起作用,请将字体的扩展名更改为 .css(也在 src 处:url('./OperatorMono.css'))

您也可以像本期中记录的那样进行操作: https://github.com/callemall/material-ui/issues/6256

npm install typeface-roboto --save

然后,在您的 index.js:

import 'typeface-roboto'

适用于 webpack/create-react-app。

如果您确实使用了 Angular,其中 import 'typeface-roboto' 并不理想且简单,您可以使用与此处建议的方法略有不同。

首先,按照其他人的描述安装这个不错的 npm 包:

npm install typeface-roboto --save

然后将其添加到您的 angular.json:

"styles": [
  "node_modules/typeface-roboto/index.css",
  [...],
  "src/styles.css"
],

我尝试使用 npm 安装 typeface-roboto 但它没有用。此外,使用来自 material ui 的 CDN 无效。但是,使用 npm 安装 webfontloader 是可行的。这是解决方案, 首先,

npm install webfontloader --save

然后,从您的 entry.js 文件中的 webfontloader 导入 WebFont,例如 App.js 或 index.js

import WebFont from "webfontloader";
WebFont.load({google: {families: ["Roboto:300,400,500"]}});

对于简洁的 Material-UI / 创建 React App PWA,不需要所有变体 - 您只需要:

yarn add @fontsource/roboto

index.js

import "@fontsource/roboto/latin-400.css";
import "@fontsource/roboto/latin-500.css";

theme.js(可选但使它看起来清晰干净)

overrides: {
  MuiCssBaseline: {
   html: {
    "-webkit-font-smoothing": "antialiased",
    "-moz-osx-font-smoothing": "grayscale",
    height: "100%",
    width: "100%"
  }
 }
}

您的字体将被捆绑并立即可用online/offline

Demo