Làm cách nào để thêm phông chữ cho các dự án dựa trên ứng dụng tạo phản ứng?


176

Tôi đang sử dụng ứng dụng tạo phản ứng và không thích eject.

Không rõ phông chữ được nhập qua @ font-face và được tải cục bộ sẽ đi đâu.

Cụ thể, tôi đang tải

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

Bất kỳ đề xuất?

-- BIÊN TẬP

Bao gồm cả ý chính mà Dan đề cập đến trong câu trả lời của mình

  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
Bạn đã kiểm tra phần "Thêm phông chữ" trong Hướng dẫn sử dụng chưa?
Dan Abramov

2
@DanAbramov tôi có, đề nghị là nhập phông chữ. Nhưng tôi cảm thấy không rõ ràng (ít nhất là với tôi) về cách nó nên được thực hiện trong thực tế. Trong thời gian đó, tôi đã thực hiện gist.github.com/maximveksler/5b4f80c5ded20237c3deebc82a31dcd5 này và nó dường như hoạt động (thông báo gói web nếu nó không thể tìm thấy tệp phông chữ) hoặc có tài liệu ở đây sẽ giúp. ty cho tiếp cận!
Maxim Veksler

2
Tôi đã trả lời. Cách tiếp cận của bạn có vẻ sai đối với tôi: %PUBLIC_URL%không thể làm việc (và không cần thiết) trong tệp CSS. Ngoài ra, như được mô tả trong hướng dẫn, bạn nên sử dụng nhập khẩu JS trong hầu hết các trường hợp, không phải thư mục chung.
Dan Abramov

Có tiện ích / gói nào để quét thư mục được chỉ định cho phông chữ và tạo tệp tập lệnh với tất cả các biến thể phông chữ không? Thật tẻ nhạt khi viết tất cả bằng tay
hellowworld

Câu trả lời:


284

Có hai lựa chọn:

Sử dụng hàng nhập khẩu

Đây là tùy chọn được đề xuất. Nó đảm bảo phông chữ của bạn đi qua đường dẫn xây dựng, nhận được băm trong quá trình biên dịch để bộ nhớ đệm trình duyệt hoạt động chính xác và bạn sẽ gặp lỗi biên dịch nếu các tệp bị thiếu.

Như được mô tả trong phần Thêm hình ảnh, phông chữ và tập tin , bạn cần phải có một tệp CSS được nhập từ JS. Ví dụ: theo mặc định src/index.jsnhập src/index.css:

import './index.css';

Một tệp CSS như thế này đi qua đường dẫn xây dựng và có thể tham chiếu các phông chữ và hình ảnh. Ví dụ: nếu bạn đặt một phông chữ vào src/fonts/MyFont.woff, bạn index.csscó thể bao gồm:

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

Lưu ý cách chúng ta sử dụng một đường dẫn tương đối bắt đầu bằng ./. Đây là một ký hiệu đặc biệt giúp đường ống xây dựng (được cung cấp bởi Webpack) khám phá tệp này.

Thông thường điều này là đủ.

Sử dụng publicthư mục

Nếu vì một lý do nào đó, bạn không thích sử dụng đường dẫn xây dựng, và thay vào đó hãy thực hiện theo cách cổ điển của Wap, bạn có thể sử dụng publicthư mục và đặt phông chữ của mình ở đó.

Nhược điểm của phương pháp này là các tệp không bị băm khi bạn biên dịch để sản xuất nên bạn sẽ phải cập nhật tên của chúng mỗi khi bạn thay đổi hoặc trình duyệt sẽ lưu trữ các phiên bản cũ.

Nếu bạn muốn làm theo cách này, hãy đặt các phông chữ ở đâu đó vào publicthư mục, ví dụ, vào public/fonts/MyFont.woff. Nếu bạn làm theo cách tiếp cận này, bạn cũng nên đặt các tệp CSS vào publicthư mục và không nhập chúng từ JS vì việc trộn các cách tiếp cận này sẽ rất khó hiểu. Vì vậy, nếu bạn vẫn muốn làm điều đó, bạn sẽ có một tệp như thế public/index.css. Bạn sẽ phải tự thêm <link>vào biểu định kiểu này từ public/index.html:

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

Và bên trong nó, bạn sẽ sử dụng ký hiệu CSS thông thường:

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

Lưu ý cách tôi đang sử dụng fonts/MyFont.wofflàm đường dẫn. Điều này là do index.csstrong publicthư mục nên nó sẽ được phục vụ từ đường dẫn công khai (thường là root máy chủ, nhưng nếu bạn triển khai đến GitHub Pages và đặt homepagetrường của bạn thành http://myuser.github.io/myproject, nó sẽ được phục vụ từ đó /myproject). Tuy nhiên fontscũng có trong publicthư mục, vì vậy chúng sẽ được phục vụ từ fontstương đối (hoặc http://mywebsite.com/fontshoặc http://myuser.github.io/myproject/fonts). Do đó chúng tôi sử dụng đường dẫn tương đối.

Lưu ý rằng vì chúng tôi đang tránh đường ống xây dựng trong ví dụ này, nên nó không xác minh rằng tệp thực sự tồn tại. Đây là lý do tại sao tôi không đề xuất phương pháp này. Một vấn đề khác là index.csstệp của chúng tôi không được thu nhỏ và không nhận được hàm băm. Vì vậy, nó sẽ chậm hơn đối với người dùng cuối và bạn có nguy cơ trình duyệt lưu các phiên bản cũ của tệp.

 Cách sử dụng nào?

Đi với phương thức đầu tiên (Sử dụng Nhập khẩu nhập khẩu). Tôi chỉ mô tả cái thứ hai vì đó là những gì bạn đã cố gắng làm (đánh giá bằng nhận xét của bạn), nhưng nó có nhiều vấn đề và chỉ nên là giải pháp cuối cùng khi bạn đang giải quyết một số vấn đề.


5
một ví dụ trong các tài liệu sẽ hữu ích, tôi cũng hơi bối rối
Tom

2
Tôi thấy rằng tôi thực sự phải sử dụng url ./fonts/Myfont.woff chứ không phải ./Myfont.woff
th3morg

56
Nếu ai đó đang thêm ttfphông chữ, bạn nên cung cấp truetypethay vì ttflàm tham số cho format* .
vắt sữa

3
@milkersarac bạn giỏi nhất!
João Vilaça

19
Theo dõi @milkersarac nếu bạn đang sử dụng, otfbạn cần đặt opentype.
Karl Taylor

45

Dưới đây là một số cách để làm điều này:

1. Nhập phông chữ

Ví dụ: để sử dụng Roboto, hãy cài đặt gói bằng

yarn add typeface-roboto

hoặc là

npm install typeface-roboto --save

Trong index.js:

import "typeface-roboto";

Có các gói npm cho rất nhiều phông chữ nguồn mở và hầu hết các phông chữ của Google. Bạn có thể thấy tất cả các phông chữ ở đây . Tất cả các gói là từ dự án đó .

2. Đối với phông chữ được lưu trữ bởi bên thứ ba

Ví dụ: phông chữ của Google, bạn có thể truy cập Font.google.com nơi bạn có thể tìm thấy các liên kết mà bạn có thể đặt trongpublic/index.html

ảnh chụp màn hình của Font.google.com

Nó sẽ giống như

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

hoặc là

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

3. Tải xuống phông chữ và thêm nó vào mã nguồn của bạn.

Tải về phông chữ. Ví dụ: đối với phông chữ google, bạn có thể truy cập Font.google.com . Nhấp vào nút tải xuống để tải xuống phông chữ.

Di chuyển phông chữ vào fontsthư mục trong srcthư mục của bạn

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

Bây giờ, trong App.css, thêm điều này

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

Đối với ttfđịnh dạng, bạn phải đề cập đến format('truetype'). Đối với woff,format('woff')

Bây giờ bạn có thể sử dụng phông chữ trong các lớp.

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

4. Sử dụng gói trình tải phông chữ

Cài đặt gói bằng cách sử dụng

yarn add webfontloader

hoặc là

npm install webfontloader --save

Trong src/index.js, bạn có thể nhập cái này và chỉ định các phông chữ cần thiết

import WebFont from 'webfontloader';

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

2
--save được mặc định với npm 5 (2017)
NattyC

Cảm ơn bạn đã nhận xét @Nirthie, tôi rất vui vì npm đã thực hiện thay đổi đó.
sudo bangbang

@sudobangbang Cảm ơn, giải pháp số 3 đã làm việc cho tôi. Tuy nhiên - có cách nào để không đặt fontsthư mục bên dưới src, mà publicthay vào đó không? Tôi đã thử nó, nhưng dường như không được phép ...
Yossi Vainshtein

@YossiVainshtein, tôi không nghĩ vậy. Khi bạn đang sử dụng các phông chữ trong App.css, nó cũng sẽ được biên dịch cùng với nó.
sudo bangbang

For ttf format, you have to mention format('truetype'). For woff, format('woff')đã làm điều đó cho tôi! cảm ơn bạn!
Joseph Briggs

6
  1. Truy cập Google Fonts https://fonts.google.com/
  2. Chọn phông chữ của bạn như được mô tả trong hình dưới đây:

nhập mô tả hình ảnh ở đây

  1. Sao chép và sau đó dán url đó vào tab mới, bạn sẽ nhận được mã css để thêm phông chữ đó. Trong trường hợp này nếu bạn đi đến

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

Nó sẽ mở như thế này:

nhập mô tả hình ảnh ở đây

4, Sao chép và dán mã đó vào style.css của bạn và chỉ cần bắt đầu sử dụng phông chữ như thế này:

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

Kết quả:

nhập mô tả hình ảnh ở đây


1
Trong nhiều trường hợp (ví dụ: mạng công ty), quyền truy cập vào CDN bên ngoài bị chặn bởi tường lửa và phương pháp này, mặc dù đúng, có thể không hoạt động. Chúng tôi có nhiều Vlan trong tổ chức của mình và ngoại trừ CNTT và một số Vlan khác, tất cả các Vlan chặn truy cập CDN bên ngoài, điều đó cũng có nghĩa là CDN nội dung của Google cũng bị chặn. Đã từng trải qua rồi.
AnBisw

2

Bạn có thể sử dụng mô-đun WebFont , giúp đơn giản hóa quá trình này.

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

0

Tôi đã phạm sai lầm như thế này.

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

Nó hoạt động đúng theo cách này

@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

Tôi đã dành cả buổi sáng để giải quyết một vấn đề tương tự sau khi đáp ứng câu hỏi về ngăn xếp này. Tôi đã sử dụng giải pháp đầu tiên của Dan trong câu trả lời ở trên làm điểm xuất phát.

Vấn đề

Tôi có một dev (cái này ở trên máy cục bộ của tôi), dàn dựng và môi trường sản xuất. Môi trường dàn dựng và sản xuất của tôi sống trên cùng một máy chủ.

Ứng dụng này được triển khai để dàn dựng thông qua acmeserver/~staging/note-taking-appvà phiên bản sản xuất nằm ở acmeserver/note-taking-app(đổ lỗi cho CNTT).

Tất cả các tệp phương tiện như phông chữ đang tải hoàn toàn tốt trên dev (tức là react-scripts start).

Tuy nhiên, khi tôi tạo và tải lên các bản dựng dàn dựng và sản xuất, trong khi các tệp .css.jstệp đang tải đúng cách, phông chữ thì không. Tệp đã biên dịch .csscó đường dẫn chính xác nhưng yêu cầu http của trình duyệt đã nhận được một số đường dẫn rất sai (hiển thị bên dưới).

Các main.fc70b10f.chunk.csstập tin biên dịch :

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

Yêu cầu http của trình duyệt được hiển thị bên dưới. Lưu ý cách nó được thêm vào /static/css/khi tệp phông chữ chỉ tồn tại /static/media/cũng như sao chép thư mục đích. Tôi loại trừ cấu hình máy chủ là thủ phạm.

Một Refererphần là lỗi.

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

Các package.jsontập tin đã được đặt thuộc homepagetính ./note-taking-app. Điều này đã gây ra vấn đề.

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

Giải pháp

Điều đó đã kéo dài - nhưng giải pháp là:

  1. thay đổi PUBLIC_URLbiến env tùy theo môi trường
  2. xóa homepagetài sản khỏi package.jsontập tin

Dưới đây là .env-cmdrctập tin của tôi . Tôi sử dụng .env-cmdrcthường xuyên .envvì nó giữ mọi thứ trong một tập tin.

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

Định tuyến thông qua react-router-domhoạt động tốt quá - chỉ cần sử dụng PUBLIC_URLbiến env làm basenametài sản.

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

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

export { createRouter };

Cấu hình máy chủ được đặt để định tuyến tất cả các yêu cầu đến ./index.htmltệp.

Cuối cùng, đây là những gì main.fc70b10f.chunk.csstệp được biên dịch trông giống như sau khi các thay đổi được thảo luận được thực hiện.

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

Đọc tài liệu

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.