如何通过 Webpack 管道在 React 应用程序中正确加载 .otf/.ttf 字体?
How to correctly load .otf/.tff fonts in a React app via a Webpack pipeline?
我在实现这件事时遇到了麻烦,我一直遵循的各种指南可能已经过时或者我搞砸了。我知道这是一个常见的问题,我玩过很棒的字体,通过 scss 等加载它......但它没有用,而且我发现它过于复杂,下面的方法也应该起作用并且更直接。
webpack 错误(在底部)是由 css-loader
引发的,它不是 file-loader
或 url-loader
(我都试过了),所以我怀疑问题出在css-loader
正在尝试 import/find 通过 .otf 字体文件但不能。
如果有人知道,那真的很有帮助。我需要打包字体文件,以便我的应用程序可以 运行 离线。
这是我的文件结构:
./webkacp.config.js
./src/
./fonts/AvenirLTStd-Roman.otf
./index.css
./index.jsx
这是我的 webpack.config.js:
var HtmlWebpackPlugin = require('html-webpack-plugin');
const path = require('path');
module.exports = {
mode: 'development',
module: {
rules: [
{
test: /\.jsx?$/,
loader: 'babel-loader'
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader'],
},
{
test: /\.(woff|woff2|eot|ttf|otf)$/,
use: [
{
loader: 'file-loader',
options: {
name: '[name].[ext]',
outputPath: 'fonts/'
}
}
],
},
{
test: /\.(png|svg|jpg|gif)$/,
use: [
{
loader: 'file-loader',
options: {
name: '[name].[ext]',
outputPath: 'images/'
}
}
],
}
]
},
resolve: {
extensions: ['.js', '.jsx'],
alias: {
'@': path.resolve(__dirname, 'src/'),
}
},
plugins: [new HtmlWebpackPlugin({
template: './src/index.html'
})],
devServer: {
historyApiFallback: true
},
externals: {
// global app config object
config: JSON.stringify({
apiUrl: 'http://127.0.0.1:4000'
})
}
}
这是我的 index.css:
@font-face {
font-family: "MyFont";
src: url("./fonts/AvenirLTStd-Roman.otf") format("otf");
/* Add other formats as you see fit */
}
html, body {
font-family: 'MyFont', sans-serif;
}
这是我的 index.jsx:
import React from 'react';
import { render } from 'react-dom';
import { App } from './App';
import 'bootstrap/dist/css/bootstrap.min.css';
import '@/index.css';
render(
<App />,
document.getElementById('app')
);
最后,这是 webpack 错误:
ERROR in ./src/index.css (./node_modules/css-loader/dist/cjs.js!./src/index.css)
Module not found: Error: Can't resolve './fonts/AvenirLTStd-Roman.otf' in '/var/sphyrna/csdpac-services/images/csdpac-unified/frontend/src'
@ ./src/index.css (./node_modules/css-loader/dist/cjs.js!./src/index.css) 4:36-76
@ ./src/index.css
@ ./src/index.jsx
知道了。
需要进行两项更改:
- 跳过 css-loader 中的 url,这样它就不会尝试 import/resolve 文件。
- 删除我的 css 中的 san-serif。
现在有效。希望这可以帮助别人。 None 的在线指南提到跳过 url。
这是我的更新 css:
@font-face {
font-family: "MyFont";
src: url("./fonts/AvenirLTStd-Roman.otf") format("otf");
/* Add other formats as you see fit */
}
html, body {
font-family: 'MyFont';
}
Webpack.config.js:
var HtmlWebpackPlugin = require('html-webpack-plugin');
const path = require('path');
module.exports = {
mode: 'development',
module: {
rules: [
{
test: /\.jsx?$/,
loader: 'babel-loader'
},
{
test: /\.css$/,
use: [
{
loader: 'style-loader'
},
{
loader: 'css-loader',
options: {url:false}
}
]
},
{
test: /\.(woff|woff2|eot|ttf|otf)$/,
use: [
{
loader: 'url-loader',
options: {
name: '[name].[ext]',
outputPath: 'fonts/'
}
}
],
},
{
test: /\.(png|svg|jpg|gif)$/,
use: [
{
loader: 'file-loader',
options: {
name: '[name].[ext]',
outputPath: 'images/'
}
}
],
}
]
},
resolve: {
extensions: ['.js', '.jsx'],
alias: {
'@': path.resolve(__dirname, 'src/'),
}
},
plugins: [new HtmlWebpackPlugin({
template: './src/index.html'
})],
devServer: {
historyApiFallback: true
},
externals: {
// global app config object
config: JSON.stringify({
apiUrl: 'http://127.0.0.1:4000'
})
}
}
我在实现这件事时遇到了麻烦,我一直遵循的各种指南可能已经过时或者我搞砸了。我知道这是一个常见的问题,我玩过很棒的字体,通过 scss 等加载它......但它没有用,而且我发现它过于复杂,下面的方法也应该起作用并且更直接。
webpack 错误(在底部)是由 css-loader
引发的,它不是 file-loader
或 url-loader
(我都试过了),所以我怀疑问题出在css-loader
正在尝试 import/find 通过 .otf 字体文件但不能。
如果有人知道,那真的很有帮助。我需要打包字体文件,以便我的应用程序可以 运行 离线。
这是我的文件结构:
./webkacp.config.js
./src/
./fonts/AvenirLTStd-Roman.otf
./index.css
./index.jsx
这是我的 webpack.config.js:
var HtmlWebpackPlugin = require('html-webpack-plugin');
const path = require('path');
module.exports = {
mode: 'development',
module: {
rules: [
{
test: /\.jsx?$/,
loader: 'babel-loader'
},
{
test: /\.css$/,
use: ['style-loader', 'css-loader'],
},
{
test: /\.(woff|woff2|eot|ttf|otf)$/,
use: [
{
loader: 'file-loader',
options: {
name: '[name].[ext]',
outputPath: 'fonts/'
}
}
],
},
{
test: /\.(png|svg|jpg|gif)$/,
use: [
{
loader: 'file-loader',
options: {
name: '[name].[ext]',
outputPath: 'images/'
}
}
],
}
]
},
resolve: {
extensions: ['.js', '.jsx'],
alias: {
'@': path.resolve(__dirname, 'src/'),
}
},
plugins: [new HtmlWebpackPlugin({
template: './src/index.html'
})],
devServer: {
historyApiFallback: true
},
externals: {
// global app config object
config: JSON.stringify({
apiUrl: 'http://127.0.0.1:4000'
})
}
}
这是我的 index.css:
@font-face {
font-family: "MyFont";
src: url("./fonts/AvenirLTStd-Roman.otf") format("otf");
/* Add other formats as you see fit */
}
html, body {
font-family: 'MyFont', sans-serif;
}
这是我的 index.jsx:
import React from 'react';
import { render } from 'react-dom';
import { App } from './App';
import 'bootstrap/dist/css/bootstrap.min.css';
import '@/index.css';
render(
<App />,
document.getElementById('app')
);
最后,这是 webpack 错误:
ERROR in ./src/index.css (./node_modules/css-loader/dist/cjs.js!./src/index.css)
Module not found: Error: Can't resolve './fonts/AvenirLTStd-Roman.otf' in '/var/sphyrna/csdpac-services/images/csdpac-unified/frontend/src'
@ ./src/index.css (./node_modules/css-loader/dist/cjs.js!./src/index.css) 4:36-76
@ ./src/index.css
@ ./src/index.jsx
知道了。
需要进行两项更改:
- 跳过 css-loader 中的 url,这样它就不会尝试 import/resolve 文件。
- 删除我的 css 中的 san-serif。
现在有效。希望这可以帮助别人。 None 的在线指南提到跳过 url。
这是我的更新 css:
@font-face {
font-family: "MyFont";
src: url("./fonts/AvenirLTStd-Roman.otf") format("otf");
/* Add other formats as you see fit */
}
html, body {
font-family: 'MyFont';
}
Webpack.config.js:
var HtmlWebpackPlugin = require('html-webpack-plugin');
const path = require('path');
module.exports = {
mode: 'development',
module: {
rules: [
{
test: /\.jsx?$/,
loader: 'babel-loader'
},
{
test: /\.css$/,
use: [
{
loader: 'style-loader'
},
{
loader: 'css-loader',
options: {url:false}
}
]
},
{
test: /\.(woff|woff2|eot|ttf|otf)$/,
use: [
{
loader: 'url-loader',
options: {
name: '[name].[ext]',
outputPath: 'fonts/'
}
}
],
},
{
test: /\.(png|svg|jpg|gif)$/,
use: [
{
loader: 'file-loader',
options: {
name: '[name].[ext]',
outputPath: 'images/'
}
}
],
}
]
},
resolve: {
extensions: ['.js', '.jsx'],
alias: {
'@': path.resolve(__dirname, 'src/'),
}
},
plugins: [new HtmlWebpackPlugin({
template: './src/index.html'
})],
devServer: {
historyApiFallback: true
},
externals: {
// global app config object
config: JSON.stringify({
apiUrl: 'http://127.0.0.1:4000'
})
}
}