Come aggiungere caratteri per creare progetti basati su app-reagire?


177

Sto usando creare-reagire-app e preferisco non farlo eject.

Non è chiaro dove dovrebbero andare i caratteri importati tramite @ font-face e caricati localmente.

Vale a dire, sto caricando

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

Eventuali suggerimenti?

-- MODIFICARE

Compreso l'essenza a cui Dan si riferisce nella sua risposta

  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');
}

2
Hai controllato la sezione "Aggiunta di caratteri" nella sua Guida per l'utente?
Dan Abramov,

2
@DanAbramov ho, la raccomandazione è di importare il carattere. Ma sento che non è chiaro (almeno non per me) su come dovrebbe essere fatto in pratica. Nel frattempo ho fatto questo gist.github.com/maximveksler/5b4f80c5ded20237c3deebc82a31dcd5 e sembra funzionare (avvisi del web pack se non riesce a trovare un file di font) ma sono sicuro che non sia la soluzione ottimale e un esempio o averlo documentato qui sarebbe di aiuto. per averci contattato!
Maxim Veksler,

2
Ho risposto. Il tuo approccio mi sembra sbagliato: %PUBLIC_URL%non può funzionare (ed è inutile) in un file CSS. Inoltre, come descritto nella guida, dovresti utilizzare le importazioni JS in quasi tutti i casi, non nella cartella pubblica.
Dan Abramov,

Esiste qualche utilità / pacchetto per scansionare la cartella specificata per i caratteri e generare il file di script con tutte le varianti di carattere? È noioso scriverlo tutto manualmente
helloworld il

Risposte:


290

Esistono due opzioni:

Usando le importazioni

Questa è l'opzione suggerita. Assicura che i tuoi caratteri passino attraverso la pipeline di compilazione, ottengano hash durante la compilazione in modo che la cache del browser funzioni correttamente e che si ottengano errori di compilazione se i file mancano.

Come descritto in "Aggiunta di immagini, caratteri e file" , è necessario che un file CSS sia importato da JS. Ad esempio, per impostazione predefinita le src/index.jsimportazioni src/index.css:

import './index.css';

Un file CSS come questo passa attraverso la pipeline di compilazione e può fare riferimento a caratteri e immagini. Ad esempio, se inserisci un carattere src/fonts/MyFont.woff, index.csspotresti includere questo:

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

Si noti come stiamo utilizzando un percorso relativo che inizia con ./. Questa è una notazione speciale che aiuta la pipeline di compilazione (fornita da Webpack) a scoprire questo file.

Normalmente questo dovrebbe essere sufficiente.

Utilizzando la publiccartella

Se per qualche motivo preferisci non usare la pipeline di compilazione e invece farlo nel “modo classico”, puoi usare la publiccartella e inserire i tuoi caratteri lì.

Il rovescio della medaglia di questo approccio è che i file non ottengono hash quando si compila per la produzione, quindi dovrai aggiornare i loro nomi ogni volta che li cambi, o i browser memorizzeranno nella cache le vecchie versioni.

Se vuoi farlo in questo modo, inserisci i caratteri da qualche parte nella publiccartella, ad esempio, in public/fonts/MyFont.woff. Se segui questo approccio, dovresti mettere anche i file CSS nella publiccartella e non importarli da JS perché mescolare questi approcci sarà molto confuso. Quindi, se vuoi ancora farlo, avresti un file simile public/index.css. Dovresti aggiungere manualmente <link>questo foglio di stile da public/index.html:

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

E al suo interno, useresti la normale notazione CSS:

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

Nota come sto usando fonts/MyFont.woffil percorso. Questo perché si index.csstrova nella publiccartella, quindi verrà servito dal percorso pubblico (di solito è la radice del server, ma se si distribuisce su GitHub Pages e si imposta il homepagecampo su http://myuser.github.io/myproject, verrà servito da /myproject). Tuttavia fontssono anche nella publiccartella, quindi saranno serviti fontsrelativamente (o http://mywebsite.com/fontso http://myuser.github.io/myproject/fonts). Pertanto utilizziamo il percorso relativo.

Si noti che poiché in questo esempio si evita la pipeline di compilazione, non si verifica che il file esista effettivamente. Questo è il motivo per cui non consiglio questo approccio. Un altro problema è che il nostro index.cssfile non viene minimizzato e non ha un hash. Quindi sarà più lento per gli utenti finali e rischierai che i browser memorizzino nella cache le versioni precedenti del file.

 Quale modo di usare?

Vai con il primo metodo ("Utilizzo delle importazioni"). Ho descritto solo il secondo poiché è quello che hai tentato di fare (a giudicare dal tuo commento), ma ha molti problemi e dovrebbe essere l'ultima risorsa solo quando stai risolvendo un problema.


5
un esempio nei documenti sarebbe utile, ero anche un po 'confuso
Tom,

2
Ho scoperto che in realtà ho dovuto usare l'URL ./fonts/Myfont.woff e non ./Myfont.woff
th3morg

57
Se qualcuno sta aggiungendo un ttfcarattere, dovresti dare truetypeinvece ttfcome parametro al format* .
milkersarac,

3
@milkersarac sei il migliore!
João Vilaça,

19
Se stai usando @milkersarac, devi otfmetterlo opentype.
Karl Taylor,

46

Ecco alcuni modi per farlo:

1. Importazione del carattere

Ad esempio, per usare Roboto, installare il pacchetto usando

yarn add typeface-roboto

o

npm install typeface-roboto --save

In index.js:

import "typeface-roboto";

Esistono pacchetti npm per molti caratteri open source e la maggior parte dei caratteri Google. Puoi vedere tutti i caratteri qui . Tutti i pacchetti provengono da quel progetto .

2. Per i caratteri ospitati da terze parti

Ad esempio i caratteri Google, puoi andare su fonts.google.com dove puoi trovare i collegamenti che puoi inserire nel tuopublic/index.html

screenshot di fonts.google.com

Sarà come

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

o

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

3. Scaricare il carattere e aggiungerlo nel codice sorgente.

Scarica il font. Ad esempio, per google fonts, puoi andare su fonts.google.com . Fare clic sul pulsante di download per scaricare il carattere.

Sposta il carattere nella fontsdirectory nella tua srcdirectory

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

Ora, in App.css, aggiungi questo

@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');
}

Per il ttfformato, devi menzionare format('truetype'). Per woff,format('woff')

Ora puoi usare il carattere in classe.

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

4. Utilizzo del pacchetto web-font-loader

Installa il pacchetto usando

yarn add webfontloader

o

npm install webfontloader --save

In src/index.js, è possibile importare questo e specificare i caratteri necessari

import WebFont from 'webfontloader';

WebFont.load({
   google: {
     families: ['Titillium Web:300,400,700', 'sans-serif']
   }
});

2
--save è predefinito con npm 5 (2017)
NattyC

Grazie per il commento @Natalie, sono contento che npm abbia apportato questa modifica.
sudo bangbang,

@sudobangbang Grazie, la soluzione n. 3 ha funzionato per me. Tuttavia, c'è un modo per non mettere la fontscartella sotto src, ma sotto public? L'ho provato, ma sembra che non sia permesso ...
Yossi Vainshtein,

@YossiVainshtein, non credo. Mentre stai usando i caratteri in App.css, dovrebbe anche essere compilato con esso.
sudo bangbang,

For ttf format, you have to mention format('truetype'). For woff, format('woff')fatto per me! grazie!
Joseph Briggs,

7
  1. Vai a Google Fonts https://fonts.google.com/
  2. Seleziona il tuo carattere come mostrato nell'immagine qui sotto:

inserisci qui la descrizione dell'immagine

  1. Copia e incolla l'URL in una nuova scheda otterrai il codice CSS per aggiungere quel carattere. In questo caso, se vai a

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

Si aprirà così:

inserisci qui la descrizione dell'immagine

4, Copia e incolla quel codice nel tuo style.css e inizia semplicemente a usare quel font in questo modo:

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

Risultato:

inserisci qui la descrizione dell'immagine


1
In molti casi (ad es. Reti aziendali), l'accesso al CDN esterno è bloccato dal firewall e questo metodo, sebbene corretto, potrebbe non funzionare. Abbiamo più VLAN nella nostra organizzazione e, tranne l'IT e pochi altri, tutte le VLAN bloccano l'accesso esterno alla CDN, il che significa che anche la CDN del contenuto di Google viene bloccata. Ci sono stato, l'ho fatto.
AnBisw

2

È possibile utilizzare il modulo WebFont , che semplifica notevolmente il processo.

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

0

Stavo facendo errori come questo.

@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";

Funziona correttamente in questo modo

@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);

0

Ho trascorso l'intera mattinata a risolvere un problema simile dopo essere atterrato su questa domanda dello stack. Ho usato la prima soluzione di Dan nella risposta sopra come punto di partenza.

Problema

Ho uno sviluppatore (questo è sul mio computer locale), una gestione temporanea e un ambiente di produzione. I miei ambienti di gestione temporanea e di produzione vivono sullo stesso server.

L'app viene distribuita nella gestione temporanea tramite acmeserver/~staging/note-taking-appe la versione di produzione rimane attiva acmeserver/note-taking-app(incolpare l'IT).

Tutti i file multimediali come i font si stavano caricando perfettamente su dev (cioè, react-scripts start).

Tuttavia, quando ho creato e caricato staging e build di produzione, mentre i file .csse .jsvenivano caricati correttamente, i font non lo erano. Il .cssfile compilato sembrava avere un percorso corretto ma la richiesta http del browser stava ottenendo un percorso molto sbagliato (mostrato sotto).

Il main.fc70b10f.chunk.cssfile compilato :

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

La richiesta http del browser è mostrata di seguito. Nota come si sta aggiungendo /static/css/quando il file del font risiede appena /static/media/oltre a duplicare la cartella di destinazione. Ho escluso che la configurazione del server fosse il colpevole.

Anche in Refererparte è colpa.

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

Il package.jsonfile aveva la homepageproprietà impostata su ./note-taking-app. Questo stava causando il problema.

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

Soluzione

Era molto lungo, ma la soluzione è:

  1. cambia la PUBLIC_URLvariabile env a seconda dell'ambiente
  2. rimuovere la homepageproprietà dal package.jsonfile

Di seguito è il mio .env-cmdrcfile. Uso .env-cmdrcregolarmente .envperché mantiene tutto insieme in un unico 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"
  }
}

Anche il routing via react-router-domfunziona bene - usa semplicemente la PUBLIC_URLvariabile env come basenameproprietà.

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

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

export { createRouter };

La configurazione del server è impostata per instradare tutte le richieste al ./index.htmlfile.

Infine, ecco main.fc70b10f.chunk.csscome appare il file compilato dopo l'implementazione delle modifiche discusse.

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

Materiale di lettura

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.