Как добавить шрифты к проектам, основанным на создании-реагировании?
Я использую create-response-app и предпочитаю не eject
.
Непонятно, куда должны идти шрифты, импортированные через @font-face и загруженные локально.
А именно, я загружаю
@font-face {
font-family: 'Myriad Pro Regular';
font-style: normal;
font-weight: normal;
src: local('Myriad Pro Regular'), url('MYRIADPRO-REGULAR.woff') format('woff');
}
Есть предложения?
- РЕДАКТИРОВАТЬ
Включая суть, на которую ссылается Дэн в своем ответе
➜ Client git:(feature/trivia-game-ui-2) ✗ ls -l public/static/fonts
total 1168
[email protected] 1 maximveksler staff 62676 Mar 17 2014 MYRIADPRO-BOLD.woff
[email protected] 1 maximveksler staff 61500 Mar 17 2014 MYRIADPRO-BOLDCOND.woff
[email protected] 1 maximveksler staff 66024 Mar 17 2014 MYRIADPRO-BOLDCONDIT.woff
[email protected] 1 maximveksler staff 66108 Mar 17 2014 MYRIADPRO-BOLDIT.woff
[email protected] 1 maximveksler staff 60044 Mar 17 2014 MYRIADPRO-COND.woff
[email protected] 1 maximveksler staff 64656 Mar 17 2014 MYRIADPRO-CONDIT.woff
[email protected] 1 maximveksler staff 61848 Mar 17 2014 MYRIADPRO-REGULAR.woff
[email protected] 1 maximveksler staff 62448 Mar 17 2014 MYRIADPRO-SEMIBOLD.woff
[email protected] 1 maximveksler staff 66232 Mar 17 2014 MYRIADPRO-SEMIBOLDIT.woff
➜ Client git:(feature/trivia-game-ui-2) ✗ cat src/containers/GameModule.css
.GameModule {
padding: 15px;
}
@font-face {
font-family: 'Myriad Pro Regular';
font-style: normal;
font-weight: normal;
src: local('Myriad Pro Regular'), url('%PUBLIC_URL%/static/fonts/MYRIADPRO-REGULAR.woff') format('woff');
}
@font-face {
font-family: 'Myriad Pro Condensed';
font-style: normal;
font-weight: normal;
src: local('Myriad Pro Condensed'), url('%PUBLIC_URL%/static/fonts/MYRIADPRO-COND.woff') format('woff');
}
@font-face {
font-family: 'Myriad Pro Semibold Italic';
font-style: normal;
font-weight: normal;
src: local('Myriad Pro Semibold Italic'), url('%PUBLIC_URL%/static/fonts/MYRIADPRO-SEMIBOLDIT.woff') format('woff');
}
@font-face {
font-family: 'Myriad Pro Semibold';
font-style: normal;
font-weight: normal;
src: local('Myriad Pro Semibold'), url('%PUBLIC_URL%/static/fonts/MYRIADPRO-SEMIBOLD.woff') format('woff');
}
@font-face {
font-family: 'Myriad Pro Condensed Italic';
font-style: normal;
font-weight: normal;
src: local('Myriad Pro Condensed Italic'), url('%PUBLIC_URL%/static/fonts/MYRIADPRO-CONDIT.woff') format('woff');
}
@font-face {
font-family: 'Myriad Pro Bold Italic';
font-style: normal;
font-weight: normal;
src: local('Myriad Pro Bold Italic'), url('%PUBLIC_URL%/static/fonts/MYRIADPRO-BOLDIT.woff') format('woff');
}
@font-face {
font-family: 'Myriad Pro Bold Condensed Italic';
font-style: normal;
font-weight: normal;
src: local('Myriad Pro Bold Condensed Italic'), url('%PUBLIC_URL%/static/fonts/MYRIADPRO-BOLDCONDIT.woff') format('woff');
}
@font-face {
font-family: 'Myriad Pro Bold Condensed';
font-style: normal;
font-weight: normal;
src: local('Myriad Pro Bold Condensed'), url('%PUBLIC_URL%/static/fonts/MYRIADPRO-BOLDCOND.woff') format('woff');
}
@font-face {
font-family: 'Myriad Pro Bold';
font-style: normal;
font-weight: normal;
src: local('Myriad Pro Bold'), url('%PUBLIC_URL%/static/fonts/MYRIADPRO-BOLD.woff') format('woff');
}
Ответы
Ответ 1
Есть два варианта:
Использование импорта
Это предлагаемый вариант. Это гарантирует, что ваши шрифты проходят через конвейер сборки, получают хэши во время компиляции, чтобы кэширование в браузере работало правильно, и чтобы вы получали ошибки компиляции, если файлы отсутствуют.
Как описано в "Добавление изображений, шрифтов и файлов", вам необходимо импортировать файл CSS из JS. Например, по умолчанию src/index.js
импортирует src/index.css
:
import './index.css';
CSS файл, подобный этому, проходит через конвейер сборки и может ссылаться на шрифты и изображения. Например, если вы поместите шрифт в src/fonts/MyFont.woff
, ваш index.css
может включать в себя следующее:
@font-face {
font-family: 'MyFont';
src: local('MyFont'), url(./fonts/MyFont.woff) format('woff');
}
Обратите внимание, как использовался относительный путь, начинающийся с ./
. Это специальная запись, которая помогает конвейеру сборки (на основе Webpack) обнаружить этот файл.
Обычно этого должно быть достаточно.
Использование папки public
Если по какой-либо причине вы предпочитаете не использовать конвейер сборки, а вместо этого делаете это "классическим способом", вы можете использовать папку public
и поместить туда свои шрифты.
Недостатком этого подхода является то, что файлы не получают хэши при компиляции для производства, поэтому вам придется обновлять их имена каждый раз, когда вы меняете их, иначе браузеры будут кэшировать старые версии.
Если вы хотите сделать это таким образом, поместите шрифты куда-нибудь в папку public
, например, в public/fonts/MyFont.woff
. Если вы следуете этому подходу, вы должны также поместить CSS файлы в папку public
и не импортировать их из JS, потому что смешивание этих подходов будет очень запутанным. Так что, если вы все еще хотите это сделать, у вас будет файл типа public/index.css
. Вам нужно будет вручную добавить <link>
к этой таблице стилей из public/index.html
:
<link rel="stylesheet" href="%PUBLIC_URL%/index.css">
И внутри вы бы использовали обычную нотацию CSS:
@font-face {
font-family: 'MyFont';
src: local('MyFont'), url(fonts/MyFont.woff) format('woff');
}
Обратите внимание, как я использую fonts/MyFont.woff
в качестве пути. Это связано с тем, что index.css
находится в папке public
, поэтому он будет обслуживаться по общедоступному пути (обычно это корневой каталог сервера, но если вы развернете на GitHub Pages и установите для своего поля homepage
значение http://myuser.github.io/myproject
, оно будет быть поданным из /myproject
). Однако fonts
также находятся в папке public
, поэтому они будут обслуживаться из fonts
относительно (либо http://mywebsite.com/fonts
, либо http://myuser.github.io/myproject/fonts
). Поэтому мы используем относительный путь.
Обратите внимание, что поскольку в этом примере мы избегали конвейера сборки, он не проверяет, существует ли файл на самом деле. Вот почему я не рекомендую такой подход. Другая проблема заключается в том, что наш файл index.css
не минимизируется и не получает хэш. Так что для конечных пользователей это будет медленнее, и вы рискуете, что браузеры кешируют старые версии файла.
Какой способ использовать?
Перейти с первым методом ("Использование импорта"). Я описал только второй, поскольку именно это вы и пытались сделать (судя по вашему комментарию), но у него много проблем, и он должен быть последним средством, когда вы решаете какую-то проблему.
Ответ 2
Вот несколько способов сделать это:
1. Импорт шрифта
Например, для использования Roboto установите пакет с помощью
yarn add typeface-roboto
или
npm install typeface-roboto --save
В index.js:
import "typeface-roboto";
Существуют пакеты npm для множества шрифтов с открытым исходным кодом и большинства шрифтов Google. Вы можете увидеть все шрифты здесь. Все пакеты из этого проекта.
2. Для шрифтов, размещенных у третьих лиц
Например, шрифты Google, вы можете перейти на fonts.google.com, где вы можете найти ссылки, которые вы можете поместить в свой public/index.html
![screenshot of fonts.google.com]()
Это будет как
<link href="https://fonts.googleapis.com/css?family=Montserrat" rel="stylesheet">
или
<style>
@import url('https://fonts.googleapis.com/css?family=Montserrat');
</style>
3. Использование пакета web-font-loader
Установите пакет с помощью
yarn add webfontloader
или
npm install webfontloader --save
В src/index.js
вы можете импортировать его и указать необходимые шрифты
import WebFont from 'webfontloader';
WebFont.load({
google: {
families: ['Titillium Web:300,400,700', 'sans-serif']
}
});
Ответ 3
Вы можете использовать модуль WebFont, который значительно упрощает процесс.
render(){
webfont.load({
custom: {
families: ['MyFont'],
urls: ['/fonts/MyFont.woff']
}
});
return (
<div style={your style} >
your text!
</div>
);
}
Ответ 4
- Перейти к Google Fonts https://fonts.google.com/
- Выберите свой шрифт, как показано на рисунке ниже:
![enter image description here]()
- Скопируйте, а затем вставьте этот URL в новую вкладку, вы получите код CSS для добавления этого шрифта. В этом случае, если вы идете в
https://fonts.googleapis.com/css?family=Spicy+Rice
Он откроется так:
![enter image description here]()
4. Скопируйте и вставьте этот код в ваш style.css и просто начните использовать этот шрифт следующим образом:
<Typography
variant="h1"
gutterBottom
style={{ fontFamily: "Spicy Rice", color: "pink" }}
>
React Rock
</Typography>
Результат:
![enter image description here]()
Ответ 5
Я делал такие ошибки.
@import "https://fonts.googleapis.com/css?family=Open+Sans:300,300i,400,400i,600,600i,700,700i&subset=cyrillic,cyrillic-ext,latin-ext";
@import "https://use.fontawesome.com/releases/v5.3.1/css/all.css";
Это работает правильно таким образом
@import url(https://fonts.googleapis.com/css?family=Open+Sans:300,300i,400,400i,600,600i,700,700i&subset=cyrillic,cyrillic-ext,latin-ext);
@import url(https://use.fontawesome.com/releases/v5.3.1/css/all.css);
Ответ 6
Я потратил все утро на решение аналогичной проблемы после того, как попал в этот вопрос. Я использовал первое решение Дана в ответе выше в качестве отправной точки.
Проблема
У меня есть разработчик (это на моей локальной машине), подготовка и производственная среда. Мои промежуточные и производственные среды находятся на одном сервере.
Приложение развернуто в промежуточной версии через acmeserver/~staging/note-taking-app
, а рабочая версия находится в acmeserver/note-taking-app
(обвините ИТ).
Все медиафайлы, такие как шрифты, прекрасно загружались в dev (то есть, react-scripts start
).
Однако когда я создавал и загружал промежуточные и производственные сборки, в то время как файлы .css
и .js
загружались правильно, шрифтов не было. Скомпилированный файл .css
выглядел правильно, но http-запрос браузера получал очень неправильный путь (показано ниже).
Скомпилированный файл main.fc70b10f.chunk.css
:
@font-face {
font-family: SairaStencilOne-Regular;
src: url(note-taking-app/static/media/SairaStencilOne-Regular.ca2c4b9f.ttf) ("truetype");
}
Запрос http браузера показан ниже. Обратите внимание, как он добавляется в /static/css/
, когда файл шрифта просто находится в /static/media/
, а также дублирует папку назначения. Я исключил конфиг сервера, являющийся виновником.
Referer
тоже частично виноват.
GET /~staging/note-taking-app/static/css/note-taking-app/static/media/SairaStencilOne-Regular.ca2c4b9f.ttf HTTP/1.1
Host: acmeserver
Origin: http://acmeserver
Referer: http://acmeserver/~staging/note-taking-app/static/css/main.fc70b10f.chunk.css
В файле package.json
свойство homepage
установлено на ./note-taking-app
. Это было причиной проблемы.
{
"name": "note-taking-app",
"version": "0.1.0",
"private": true,
"homepage": "./note-taking-app",
"scripts": {
"start": "env-cmd -e development react-scripts start",
"build": "react-scripts build",
"build:staging": "env-cmd -e staging npm run build",
"build:production": "env-cmd -e production npm run build",
"test": "react-scripts test",
"eject": "react-scripts eject"
}
//...
}
Решение
Это было долго, но решение состоит в том, чтобы:
- изменить переменную
PUBLIC_URL
env в зависимости от среды
- удалить свойство
homepage
из файла package.json
Ниже мой файл .env-cmdrc
. Я использую .env-cmdrc
поверх обычного .env
, потому что он хранит все вместе в одном файле.
{
"development": {
"PUBLIC_URL": "",
"REACT_APP_API": "http://acmeserver/~staging/note-taking-app/api"
},
"staging": {
"PUBLIC_URL": "/~staging/note-taking-app",
"REACT_APP_API": "http://acmeserver/~staging/note-taking-app/api"
},
"production": {
"PUBLIC_URL": "/note-taking-app",
"REACT_APP_API": "http://acmeserver/note-taking-app/api"
}
}
Маршрутизация через react-router-dom
тоже работает нормально - просто используйте переменную PUBLIC_URL
env в качестве свойства basename
.
import React from "react";
import { BrowserRouter } from "react-router-dom";
const createRouter = RootComponent => (
<BrowserRouter basename={process.env.PUBLIC_URL}>
<RootComponent />
</BrowserRouter>
);
export { createRouter };
Конфигурация сервера настроена на маршрутизацию всех запросов в файл ./index.html
.
Наконец, вот как выглядит скомпилированный файл main.fc70b10f.chunk.css
после того, как обсуждаемые изменения были реализованы.
@font-face {
font-family: SairaStencilOne-Regular;
src: url(/~staging/note-taking-app/static/media/SairaStencilOne-Regular.ca2c4b9f.ttf)
format("truetype");
}
Материал для чтения