如何在 Material UI 的 webpack 构建中包含 Roboto 字体?
Posted
技术标签:
【中文标题】如何在 Material UI 的 webpack 构建中包含 Roboto 字体?【英文标题】:How to include Roboto font in webpack build for Material UI? 【发布时间】:2017-03-15 16:04:00 【问题描述】:对于基于 Material UI (React) 并使用 Webpack 构建的 progressive Web 应用程序,我如何正确包含 Roboto 字体以便应用程序执行不依赖于谷歌服务器和字体也可以离线 ?
installation page 只是引用了Google fonts page,但这显然会强制从 Google 服务器下载字体。
类似的 Material UI Issue 存在关于 Roboto 字体,但仍依赖 Google 提供字体文件。
我找到了 NPM package providing the Roboto font files,但我不确定如何包含这些文件,因为提供了很多样式和字体格式,并且 我不知道 Material UI 真正需要什么样式强>。此外,仅通过 @import 导入这些字体系列似乎有 performance issues。
那么,将 right Roboto 文件与我的应用程序捆绑在一起的简单而好的解决方案是什么?
【问题讨论】:
查看这个以获得简单的解决方案 - ***.com/a/61554849/984471 【参考方案1】:对于简洁的 Material-UI / Create 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%"
您的字体将被捆绑并立即在线/离线使用
Demo
【讨论】:
【参考方案2】:这就是我的团队在我们的 Webpack 项目中包含 Roboto 字体的方式:
下载 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 能够识别它们
npm install --save file-loader
(https://www.npmjs.com/package/file-loader)
在你的 webpack 配置中,像这样使用加载器:
webpack.conf.js:
loaders: [
...,
test: /\.(woff|woff2|eot|ttf|svg)$/,
loader: 'file-loader',
options: name: '[name].[ext]', outputPath: 'fonts/',
,
...
]
在应用主入口导入字体css文件
App.js:
import './fonts/index.css';
就是这样。您的应用程序的默认字体现在应该是 Roboto。
编辑:Material-UI 实际使用哪些 Roboto 字体?
这个问题的一部分是确定要包含在项目中的 正确 Roboto 字体,因为整个 Roboto 字体几乎是 5MB。
在README 中,包含Roboto 的说明指向:fonts.google.com/?selection.family=Roboto:300,400,500。在这里,300 = Roboto-Light,400 = Roboto-Regular,500 = Roboto-Medium。这些对应于typography.js file 中定义的字体粗细。虽然这三种字体粗细几乎占整个库的使用情况,但在 DateDisplay.js 中有一个对 Regular-Bold 的引用。如果你不使用 DatePicker,你应该可以安全地忽略它。除了 GitHub markdown 样式之外,项目中的任何地方都没有使用斜体字体样式。
此信息在撰写本文时是准确的,但将来可能会发生变化。
【讨论】:
谢谢。是的,这有效。但问题是,我正在创建一个PWA,这意味着 all 资产会被下载和缓存。仅字体文件就总计 4,5 兆字节。我猜(希望)MUI 并不真正需要所有样式(薄、轻、中、...) - 但如何找出...? 啊,我现在看到了这个问题。我不知道除了 Roboto-Regular 之外您还需要任何其他字体。这取决于是否有任何组件使用font-weight
或font-style
样式。今晚我将尝试验证这一点。无论如何,我找到了an article about lazy loading fonts for performance gain。你能预先加载 Roboto-Regular 并稍后延迟加载其他变体吗?
有趣的文章。但是,由于这是一个 PWA,我需要让所有字体文件都可以离线使用(这意味着必须下载它们)。我想没有其他方法可以删除不需要的样式(从而确定哪些是不必要的)
现在将“loader: 'file?name=fonts/[name].[ext]'”行替换为 loader:" 'file-loader?name=fonts/[name].[ext] ]' "
您能否将我们需要访问该网站的 fontsquirrel 添加到您的 tut 中,然后转到 Webfont kit
选项卡,然后使用默认设置按 Download @font-face kit
按钮?这似乎并不明显。此外,对于最后一个 webpack,您需要提供:` test: /\.(woff|woff2|eot|ttf|svg)$/, loader: 'file-loader', options: name: '[name] .[ext]', outputPath: 'fonts/', , ,` 否则效果很好。【参考方案3】:
我尝试使用 npm 安装 typeface-roboto,但没有成功。此外,使用材料 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"]);
【讨论】:
解决无数其他问题的唯一解决方案。导入必须在入口点 javascript 文件中【参考方案4】:如果您确实使用 Angular,而 import 'typeface-roboto'
并不理想和简单,您可能会使用与此处建议的方式稍有不同。
首先,按照其他人的描述安装这个不错的 npm 包:
npm install typeface-roboto --save
然后将其添加到您的angular.json
:
"styles": [
"node_modules/typeface-roboto/index.css",
[...],
"src/styles.css"
],
【讨论】:
致投反对票的人:您能否解释一下为什么您投反对票而不是点击“投反对票”?【参考方案5】:您也可以像此问题中记录的那样进行操作: https://github.com/callemall/material-ui/issues/6256
npm install typeface-roboto --save
然后,在你的 index.js 中:
import 'typeface-roboto'
适用于 webpack/create-react-app。
【讨论】:
也适用于 Gatsby! 那是因为上述项目提供了开箱即用的字体支持。 OP 询问如何在“弹出”或手动 webpack 模式下设置字体 @kimomat 您能否提示如何使用import typeface-roboto
指定要导入的确切字体?例如,如果我只想要 300 和 400 种字体。
据我所知,这个 npm 包包括所有字体粗细。查看 git 存储库:github.com/KyleAMathews/typefaces/blob/master/packages/roboto/…
这是否意味着应用中的所有文本都将采用roboto字体,还是还有更多工作要做?【参考方案6】:
如果应用程序是使用 create-react-app 启动的,它没有 [可见的] webpack 配置文件。在这种情况下,您可以执行以下操作:
-
在 /public 中创建 /fonts 目录
创建/public/fonts/fonts.css,定义@font-faces
@font-face
font-family: 'inglobal';
font-weight: normal;
font-style: normal;
src: url('./OperatorMono.ttf');
复制字体文件
添加
<link rel="stylesheet" href="%PUBLIC_URL%/fonts/fonts.css">
到/public/index.html的
万岁!
5/b。如果出于任何原因,它仍然不起作用,请将字体的扩展名更改为 .css(也在 src: url('./OperatorMono.css') )
【讨论】:
我不是 Webpack 方面的专家,但我认为你不应该添加加载 CSS 的 HTML 标签,webpack 会处理它作为优化的一部分,所以我认为你正在绕过网页包。 是的,绕过是重点,因为你不能修改 webpack 配置文件——除非它被不可逆转地弹出。以上是关于如何在 Material UI 的 webpack 构建中包含 Roboto 字体?的主要内容,如果未能解决你的问题,请参考以下文章
TypeError: (0 , _material_ui_core__WEBPACK_IMPORTED_MODULE_3__.makeStyles) 不是函数
react__WEBPACK_IMPORTED_MODULE_0___default.a.useContext 不是函数——在 Material UI 中使用自动完成时
从库导入的 React 组件的 Material-Ui 主题化问题
ReactJS + Material-UI:如何在每个 TableRow 中使用 Material-UI 的 FlatButton 和 Dialog?