Bagaimana cara menambahkan font untuk membuat proyek berbasis-aplikasi?

177

Saya menggunakan create-react-app dan memilih untuk tidak melakukannya eject.

Tidak jelas ke mana font yang diimpor melalui @ font-wajah dan dimuat secara lokal harus pergi.

Yaitu, saya memuat

@font-face {
  font-family: 'Myriad Pro Regular';
  font-style: normal;
  font-weight: normal;
  src: local('Myriad Pro Regular'), url('MYRIADPRO-REGULAR.woff') format('woff');
}

Ada saran?

- EDIT

Termasuk intisari yang dimaksud Dan dalam jawabannya

  Client git:(feature/trivia-game-ui-2)  ls -l public/static/fonts
total 1168
-rwxr-xr-x@ 1 maximveksler  staff  62676 Mar 17  2014 MYRIADPRO-BOLD.woff
-rwxr-xr-x@ 1 maximveksler  staff  61500 Mar 17  2014 MYRIADPRO-BOLDCOND.woff
-rwxr-xr-x@ 1 maximveksler  staff  66024 Mar 17  2014 MYRIADPRO-BOLDCONDIT.woff
-rwxr-xr-x@ 1 maximveksler  staff  66108 Mar 17  2014 MYRIADPRO-BOLDIT.woff
-rwxr-xr-x@ 1 maximveksler  staff  60044 Mar 17  2014 MYRIADPRO-COND.woff
-rwxr-xr-x@ 1 maximveksler  staff  64656 Mar 17  2014 MYRIADPRO-CONDIT.woff
-rwxr-xr-x@ 1 maximveksler  staff  61848 Mar 17  2014 MYRIADPRO-REGULAR.woff
-rwxr-xr-x@ 1 maximveksler  staff  62448 Mar 17  2014 MYRIADPRO-SEMIBOLD.woff
-rwxr-xr-x@ 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');
}
Maxim Veksler
sumber
2
Sudahkah Anda memeriksa bagian "Menambahkan Font" di Panduan Pengguna?
Dan Abramov
2
@DanAbramov saya punya, rekomendasinya adalah untuk mengimpor font. Tetapi saya merasa tidak jelas (setidaknya tidak bagi saya) tentang bagaimana hal itu harus dilakukan dalam praktek. Sementara itu saya telah melakukan ini gist.github.com/maximveksler/5b4f80c5ded20237c3deebc82a31dcd5 dan tampaknya berfungsi (paket web memperingatkan jika tidak dapat menemukan file font) namun saya yakin itu bukan solusi optimal dan contoh atau mendokumentasikannya di sini akan membantu. ty untuk menjangkau!
Maxim Veksler
2
Aku menjawab. Pendekatan Anda terlihat salah bagi saya: %PUBLIC_URL%tidak dapat bekerja (dan tidak perlu) dalam file CSS. Juga, seperti dijelaskan dalam panduan ini, Anda harus menggunakan impor JS di hampir semua kasus, bukan folder publik.
Dan Abramov
Apakah ada utilitas / paket untuk memindai folder tertentu untuk font dan menghasilkan file skrip dengan semua variasi font? Sangat membosankan untuk menulis itu semua secara manual
helloworld

Jawaban:

290

Ada dua opsi:

Menggunakan Impor

Ini adalah opsi yang disarankan. Ini memastikan font Anda melewati pipeline build, mendapatkan hash saat kompilasi sehingga cache browser berfungsi dengan benar, dan Anda mendapatkan kesalahan kompilasi jika file hilang.

Seperti yang dijelaskan dalam "Menambahkan Gambar, Font, dan File" , Anda harus memiliki file CSS yang diimpor dari JS. Misalnya, dengan src/index.jsimpor default src/index.css:

import './index.css';

File CSS seperti ini melewati pipeline build, dan dapat merujuk font dan gambar. Misalnya, jika Anda memasukkan font src/fonts/MyFont.woff, Anda index.cssmungkin menyertakan ini:

@font-face {
  font-family: 'MyFont';
  src: local('MyFont'), url(./fonts/MyFont.woff) format('woff');
}

Perhatikan bagaimana kami menggunakan jalur relatif yang dimulai dengan ./. Ini adalah notasi khusus yang membantu pipeline build (diberdayakan oleh Webpack) menemukan file ini.

Biasanya ini sudah cukup.

Menggunakan publicFolder

Jika karena alasan tertentu Anda memilih untuk tidak menggunakan pipa build, dan alih-alih melakukannya dengan "cara klasik", Anda dapat menggunakan publicfolder dan meletakkan font Anda di sana.

Kelemahan dari pendekatan ini adalah bahwa file tidak mendapatkan hash ketika Anda mengkompilasi untuk produksi sehingga Anda harus memperbarui nama mereka setiap kali Anda mengubahnya, atau browser akan men-cache versi lama.

Jika Anda ingin melakukannya dengan cara ini, masukkan font di suatu tempat ke dalam publicfolder, misalnya, ke public/fonts/MyFont.woff. Jika Anda mengikuti pendekatan ini, Anda harus meletakkan file CSS ke publicfolder juga dan tidak mengimpornya dari JS karena menggabungkan pendekatan ini akan sangat membingungkan. Jadi, jika Anda masih ingin melakukannya, Anda akan memiliki file seperti public/index.css. Anda harus menambahkan secara manual <link>ke stylesheet ini dari public/index.html:

<link rel="stylesheet" href="%PUBLIC_URL%/index.css">

Dan di dalamnya, Anda akan menggunakan notasi CSS biasa:

@font-face {
  font-family: 'MyFont';
  src: local('MyFont'), url(fonts/MyFont.woff) format('woff');
}

Perhatikan bagaimana saya menggunakan fonts/MyFont.woffsebagai jalur. Ini karena index.cssada di publicfolder sehingga akan disajikan dari jalur publik (biasanya itu root server, tetapi jika Anda menyebarkan ke Halaman GitHub dan mengatur homepagebidang Anda http://myuser.github.io/myproject, itu akan dilayani dari /myproject). Namun fontsjuga ada di publicfolder, sehingga mereka akan dilayani dari yang fontsrelatif (salah satu http://mywebsite.com/fontsatau http://myuser.github.io/myproject/fonts). Karena itu kami menggunakan jalur relatif.

Perhatikan bahwa karena kita menghindari pipeline build dalam contoh ini, itu tidak memverifikasi bahwa file tersebut benar-benar ada. Inilah mengapa saya tidak merekomendasikan pendekatan ini. Masalah lain adalah index.cssfile kita tidak di-minify dan tidak di-hash. Jadi itu akan menjadi lebih lambat bagi pengguna akhir, dan Anda berisiko peramban melakukan caching versi lama file tersebut.

 Cara yang Digunakan?

Pergilah dengan metode pertama ("Menggunakan Impor"). Saya hanya menggambarkan yang kedua karena itulah yang Anda coba lakukan (menilai dengan komentar Anda), tetapi itu memiliki banyak masalah dan seharusnya hanya menjadi pilihan terakhir ketika Anda sedang menangani beberapa masalah.

Dan Abramov
sumber
5
contoh dalam dokumen akan berguna, saya juga sedikit bingung
Tom
2
Saya menemukan bahwa saya benar-benar harus menggunakan url ./fonts/Myfont.woff dan bukan ./Myfont.woff
th3morg
57
Jika seseorang menambahkan ttffont, Anda harus memberi truetypealih-alih ttfsebagai parameter ke format* .
milkersarac
3
@milkersarac kaulah yang terbaik!
João Vilaça
19
Mengikuti @milkersarac jika Anda menggunakan otfAnda harus memasukkan opentype.
Karl Taylor
46

Berikut ini beberapa cara untuk melakukan ini:

1. Mengimpor font

Misalnya, untuk menggunakan Roboto, instal paket menggunakan

yarn add typeface-roboto

atau

npm install typeface-roboto --save

Di index.js:

import "typeface-roboto";

Ada paket npm untuk banyak font sumber terbuka dan sebagian besar font Google. Anda dapat melihat semua font di sini . Semua paket berasal dari proyek itu .

2. Untuk font yang diselenggarakan oleh pihak ketiga

Misalnya font Google, Anda dapat membuka fonts.google.com di mana Anda dapat menemukan tautan yang dapat Anda masukkan ke dalampublic/index.html

tangkapan layar fonts.google.com

Itu akan seperti

<link href="https://fonts.googleapis.com/css?family=Montserrat" rel="stylesheet">

atau

<style>
    @import url('https://fonts.googleapis.com/css?family=Montserrat');
</style>

3. Mengunduh font dan menambahkannya dalam kode sumber Anda.

Unduh fontnya. Misalnya, untuk font google, Anda dapat mengunjungi fonts.google.com . Klik tombol unduh untuk mengunduh font.

Pindahkan font ke fontsdirektori di srcdirektori Anda

src
|
`----fonts
|      |
|      `-Lato/Lato-Black.ttf
|       -Lato/Lato-BlackItalic.ttf
|       -Lato/Lato-Bold.ttf
|       -Lato/Lato-BoldItalic.ttf
|       -Lato/Lato-Italic.ttf
|       -Lato/Lato-Light.ttf
|       -Lato/Lato-LightItalic.ttf
|       -Lato/Lato-Regular.ttf
|       -Lato/Lato-Thin.ttf
|       -Lato/Lato-ThinItalic.ttf
|
`----App.css

Sekarang, masuk App.css, tambahkan ini

@font-face {
  font-family: 'Lato';
  src: local('Lato'), url(./fonts/Lato-Regular.otf) format('opentype');
}

@font-face {
    font-family: 'Lato';
    font-weight: 900;
    src: local('Lato'), url(./fonts/Lato-Bold.otf) format('opentype');
}

@font-face {
    font-family: 'Lato';
    font-weight: 900;
    src: local('Lato'), url(./fonts/Lato-Black.otf) format('opentype');
}

Untuk ttfformat, Anda harus menyebutkan format('truetype'). Untuk woff,format('woff')

Sekarang Anda dapat menggunakan font di kelas.

.modal-title {
    font-family: Lato, Arial, serif;
    font-weight: black;
}

4. Menggunakan paket web-font-loader

Instal paket menggunakan

yarn add webfontloader

atau

npm install webfontloader --save

Di src/index.js, Anda dapat mengimpor ini dan menentukan font yang diperlukan

import WebFont from 'webfontloader';

WebFont.load({
   google: {
     families: ['Titillium Web:300,400,700', 'sans-serif']
   }
});
sudo bangbang
sumber
2
--save adalah default dengan npm 5 (2017)
NattyC
Terima kasih atas komentar @ Natalie, saya senang bahwa npm membuat perubahan itu.
sudo bangbang
@sudobangbang Terima kasih, solusi # 3 bekerja untuk saya. Namun - apakah ada cara untuk tidak meletakkan fontsfolder di bawah src, tetapi publicsebaliknya? Saya mencobanya, tetapi tampaknya tidak diizinkan ...
Yossi Vainshtein
@YossiVainshtein, kurasa tidak. Saat Anda menggunakan font di App.css, font itu juga harus dikompilasi.
sudo bangbang
For ttf format, you have to mention format('truetype'). For woff, format('woff')melakukannya untukku! Terima kasih!
Joseph Briggs
7
  1. Buka Google Fonts https://fonts.google.com/
  2. Pilih font Anda seperti yang digambarkan dalam gambar di bawah ini:

masukkan deskripsi gambar di sini

  1. Salin dan tempelkan url itu di tab baru Anda akan mendapatkan kode css untuk menambahkan font itu. Dalam hal ini jika Anda pergi ke

https://fonts.googleapis.com/css?family=Spicy+Rice

Ini akan terbuka seperti ini:

masukkan deskripsi gambar di sini

4, Salin dan tempel kode itu di style.css Anda dan mulai gunakan font itu seperti ini:

      <Typography
          variant="h1"
          gutterBottom
          style={{ fontFamily: "Spicy Rice", color: "pink" }}
        >
          React Rock
        </Typography>

Hasil:

masukkan deskripsi gambar di sini

Hitesh Sahu
sumber
1
Dalam banyak kasus (mis: jaringan perusahaan), akses ke CDN eksternal diblokir oleh firewall dan metode ini, meskipun benar, mungkin tidak berfungsi. Kami memiliki beberapa VLAN di organisasi kami dan kecuali IT dan beberapa lainnya semua VLAN memblokir akses CDN eksternal yang juga berarti CDN konten Google juga diblokir. Pernah ke sana, melakukan itu.
AnBisw
2

Anda dapat menggunakan modul WebFont , yang sangat menyederhanakan prosesnya.

render(){
  webfont.load({
     custom: {
       families: ['MyFont'],
       urls: ['/fonts/MyFont.woff']
     }
  });
  return (
    <div style={your style} >
      your text!
    </div>
  );
}
Delfino
sumber
0

Saya melakukan kesalahan seperti ini.

@import "https://fonts.googleapis.com/css?family=Open+Sans:300,300i,400,400i,600,600i,700,700i&amp;subset=cyrillic,cyrillic-ext,latin-ext";
@import "https://use.fontawesome.com/releases/v5.3.1/css/all.css";

Ini berfungsi dengan baik dengan cara ini

@import url(https://fonts.googleapis.com/css?family=Open+Sans:300,300i,400,400i,600,600i,700,700i&amp;subset=cyrillic,cyrillic-ext,latin-ext);
@import url(https://use.fontawesome.com/releases/v5.3.1/css/all.css);
Yasin UYSAL
sumber
0

Saya menghabiskan seluruh pagi memecahkan masalah yang sama setelah mendarat di pertanyaan tumpukan ini. Saya menggunakan solusi pertama Dan di jawaban di atas sebagai titik tolak.

Masalah

Saya memiliki dev (ini di mesin lokal saya), pementasan, dan lingkungan produksi. Lingkungan pementasan dan produksi saya tinggal di server yang sama.

Aplikasi ini digunakan untuk pementasan melalui acmeserver/~staging/note-taking-appdan versi produksi tinggal di acmeserver/note-taking-app(salahkan IT).

Semua file media seperti font memuat dengan baik-baik saja di dev (yaitu, react-scripts start).

Namun, ketika saya membuat dan mengunggah pementasan dan produksi, sementara file .cssdan .jsmemuat dengan benar, font tidak. Dikompilasi.css tampaknya memiliki jalur yang benar tetapi permintaan http browser mendapatkan beberapa jalur yang sangat salah (ditampilkan di bawah).

File yang dikompilasi main.fc70b10f.chunk.css:

@font-face {
  font-family: SairaStencilOne-Regular;
  src: url(note-taking-app/static/media/SairaStencilOne-Regular.ca2c4b9f.ttf) ("truetype");
}

Permintaan http browser ditunjukkan di bawah ini. Perhatikan bagaimana hal itu ditambahkan /static/css/ketika file font hanya tinggal /static/media/dan juga menduplikasi folder tujuan. Saya mengesampingkan konfigurasi server menjadi pelakunya.

The Referersebagian bersalah juga.

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

The package.jsonberkas memiliki homepageset properti untuk ./note-taking-app. Ini yang menyebabkan masalah.

{
  "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"
  }
  //...
}

Larutan

Itu sudah lama bertele-tele - tetapi solusinya adalah:

  1. mengubah PUBLIC_URL variabel env tergantung pada lingkungan
  2. hapus homepageproperti dari package.jsonfile

Di bawah ini adalah .env-cmdrcfile saya . Saya menggunakan .env-cmdrclebih dari biasa .envkarena menyimpan semuanya bersama dalam satu file.

{
  "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"
  }
}

Routing via react-router-domworks fine too - cukup gunakan PUBLIC_URLvariabel env sebagai basenameproperti.

import React from "react";
import { BrowserRouter } from "react-router-dom";

const createRouter = RootComponent => (
  <BrowserRouter basename={process.env.PUBLIC_URL}>
    <RootComponent />
  </BrowserRouter>
);

export { createRouter };

Konfigurasi server diatur untuk merutekan semua permintaan ke ./index.htmlfile.

Akhirnya, inilah main.fc70b10f.chunk.csstampilan file yang dikompilasi setelah perubahan yang dibahas diimplementasikan.

@font-face {
  font-family: SairaStencilOne-Regular;
  src: url(/~staging/note-taking-app/static/media/SairaStencilOne-Regular.ca2c4b9f.ttf)
    format("truetype");
}

Bahan bacaan

puiu
sumber