使用 Webpack 和 font-face 加载字体
Posted
技术标签:
【中文标题】使用 Webpack 和 font-face 加载字体【英文标题】:Load fonts with Webpack and font-face 【发布时间】:2018-01-11 09:28:03 【问题描述】:我正在尝试使用 @font-face
在我的 CSS 文件中加载字体,但字体永远不会加载。这是我的目录结构。
然后在webpack.config.js
我有加载器来获取字体。
var path = require('path');
var webpack = require('webpack');
module.exports =
devtool: 'eval',
entry: [
"./index.js"
],
output:
path: __dirname+"/build",
filename: "main.js"
,
plugins: [
new webpack.NoErrorsPlugin(),
new webpack.HotModuleReplacementPlugin(),
new webpack.NoErrorsPlugin()
],
resolve:
extensions: ['', '.js', '.jsx']
,
module:
loaders: [
test: /\.js$/, loaders: ['react-hot', 'babel-loader'], exclude: /node_modules/ ,
test: /\.jsx?$/, loaders: ['react-hot', 'babel-loader'], exclude: /node_modules/ ,
test: /\.svg$/, loader: "raw" ,
test: /\.css$/, loader: "style-loader!css-loader" ,
test: /\.(eot|svg|ttf|woff|woff2)$/, loader: 'file?name=src/css/[name].[ext]'
]
;
在我的 CSS 文件中,我有这个:
@font-face
font-family: 'Darkenstone';
src: url('./Darkenstone.woff') format('woff');
body
background-color: green;
font-size: 24px;
font-family: 'Darkenstone';
最后,我在 index.js
中调用我的 CSS 文件:
import './src/css/master.css';
一切正常,但从不加载字体。
【问题讨论】:
【参考方案1】:在尝试了很多东西之后,下一个加载器完成了工作。我使用了 url-loader 而不是文件加载器。您需要安装 url-loader。
test: /\.(png|woff|woff2|eot|ttf|svg)$/, loader: 'url-loader?limit=100000'
【讨论】:
内联 Base64 不是一个好主意,因为可以更有效地缓存外部资源。此外,它在移动设备上的解释速度要慢 30%,这是一个巨大的差异。 在解决这个错误几个小时后,你救了我的命! 如果您使用的是 Webpack 5 及更高版本,这不再是答案。请参阅@arbob 的答案,其中包含“资产/资源”。【参考方案2】:使用 webpack 4 这就是为我解决问题的方法(差异):
test: /\.svg$/,
use: ['svg-loader']
,
test: /\.(eot|woff|woff2|svg|ttf)([\?]?.*)$/,
use: ['file-loader']
test: /\.(png|woff|woff2|eot|ttf|svg)$/, use: ['url-loader?limit=100000']
我不得不删除 svg-loader
和 file-loader
以支持 url-loader
我的app.scss
文件如下所示:
$fa-font-path: '~font-awesome/fonts';
@import '~font-awesome/scss/font-awesome';
$icon-font-path: "~bootstrap-sass/assets/fonts/bootstrap/";
@import '~bootstrap-sass/assets/stylesheets/bootstrap';
在我的app.js
中,我导入了app.scss
:
import './app.scss';
因此,更改后,我的 webpack 配置如下所示:
const path = require('path');
const htmlWebpackPlugin = require('html-webpack-plugin');
const webpackConfig = require('./webpack.config');
module.exports =
entry:
app: './client/app/app.js'
,
devtool: 'source-map',
mode: 'development',
plugins: [
new HtmlWebpackPlugin(
title: 'Development',
template: 'client/index.html'
)
],
output:
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist')
,
module:
rules: [
test: /\.(sa|sc|c)ss$/,
use: [
'style-loader',
'css-loader',
'sass-loader',
],
,
test: /\.(png|woff|woff2|eot|ttf|svg)$/, use: ['url-loader?limit=100000']
]
;
【讨论】:
【参考方案3】:根据Webpack's Documentation,您需要更新您的webpack.config.js
以处理字体文件。查看最后一个加载程序,即
test: /\.(woff|woff2|eot|ttf|otf)$/i,
type: 'asset/resource',
我们将为 webpack 包含各种文件格式。最终的webpack.config.js
文件将如下所示。
const path = require('path');
module.exports =
entry: './src/index.js',
output:
filename: 'bundle.js',
path: path.resolve(__dirname, 'dist'),
,
module:
rules: [
test: /\.css$/i,
use: ['style-loader', 'css-loader'],
,
test: /\.(png|svg|jpg|jpeg|gif)$/i,
type: 'asset/resource',
,
test: /\.(woff|woff2|eot|ttf|otf)$/i,
type: 'asset/resource',
,
],
,
;
然后,您必须将字体导入您的条目文件。在这种情况下./src/index.js
。配置好加载器并设置好字体后,您可以通过@font-face
声明合并它们。本地 url(...)
指令将被 webpack 拾取,就像它处理图像一样。
【讨论】:
请仅链接答案即使它回答了问题也没有用。请将链接的相关部分添加到您的答案中 这是从 Webpack 5 开始的正确答案。任何其他涉及加载程序的内容都已过时。文件加载器已弃用:v4.webpack.js.org/loaders/file-loader【参考方案4】:我遇到了同样的问题。 在我的例子中,字体的“src”变成了 src="[object Module]"。
在 webpack 上禁用 esModule 是解决方案:
test: /\.(png|jpe?g|gif|svg|ttf|woff|otf)$/,
use: [
loader: 'file-loader',
options:
name: '[name].[contenthash].[ext]',
outputPath: 'static/img',
esModule: false // <- here
]
更多信息here。
【讨论】:
这对我有用,但使用的是 url-loader,而不是 file-loader。我正在使用 webpack 4.43.0【参考方案5】:尝试将您的加载器更改为
test: /\.(eot|svg|ttf|woff|woff2)$/, loader: 'file?name=[name].[ext]'
并将publicPath: 'build/'
添加到您的output
密钥中。
【讨论】:
在我的输出路径(webpack.config.js)中我有“build”,所以使用那个加载器我在 build 中得到了另一个 build 文件夹。类似构建/构建。 哦,好吧,我已经从加载器中删除了 build/。那应该将字体放在构建文件夹的根目录中,是吗?然后将publicPath: 'build/'
添加到output
。可以打开index.html找到style标签,看看字体的url是什么,应该是build/Darkenstone.woff
我在 mi 控制台中收到此错误:95% emitError: EACCES: permission denied, open '/Darkenstone.woff' at Error (native) I've remove Path: __dirname+"/build" to add publicPath,这样可以吗?
不,您应该同时拥有path: __dirname + '/build'
和publicPath: 'build/'
。请将index.html
的内容添加到您的问题中。
实际上我已经用不同的加载器解决了我的问题,它在下面的答案中,但非常感谢你的帮助;)【参考方案6】:
当我从 Webpack 4.x.x 更新到最新的 5.52.1 时,我的字体出现了一些问题
我导出的.woff / .woff2 / .ttf ...
的内容如下所示:
export default __webpack_public_path__ + "glyphicons-halflings-regular.woff2";
我的解决方案是完全删除我以前的file-loader
。文件似乎被多次处理,导致错误。
之前:
...
module:
rules: [
test: /\.(png|jpg|gif|ico|woff|woff2|ttf|svg|eot)$/,
use:
loader: 'file-loader',
options:
name: '[name].[ext]',
useRelativePath: true
,
test: /\.css$/,
use: [
MiniCssExtractPlugin.loader,
loader: 'css-loader',
options: url: false
]
]
...
之后:
...
module:
rules: [
test: /\.css$/,
use: [
MiniCssExtractPlugin.loader,
loader: 'css-loader',
options: url: false
]
]
...
欲了解更多信息:https://webpack.js.org/guides/asset-modules/
【讨论】:
这在尝试将自定义字体加载添加到 Next.js 项目时救了我。谢谢!【参考方案7】:我将 webpack 版本从 4.20.2 升级到 4.42.0,我的代码开始加载我想要的字体。
const URL_LOADER_LIMIT = 8192
module.exports = () => (
module:
rules: [
test: /\.eot(\?v=\d+\.\d+\.\d+)?$/,
use: [
loader: 'url-loader',
options:
name: '[name].[ext]',
outputPath: 'fonts/',
limit: URL_LOADER_LIMIT
]
,
test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/,
use: [
loader: 'url-loader',
options:
name: '[name].[ext]',
outputPath: 'fonts/',
limit: URL_LOADER_LIMIT,
mimetype: 'application/font-woff'
]
,
test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/,
use: [
loader: 'url-loader',
options:
name: '[name].[ext]',
outputPath: 'fonts/',
limit: URL_LOADER_LIMIT,
mimetype: 'application/octet-stream'
]
,
test: /\.mp3$/,
use: ['file-loader']
,
test: /\.svg(\?v=\d+\.\d+\.\d+)?$/,
use: [
loader: 'url-loader',
options:
outputPath: 'images/',
name: '[name].[ext]',
limit: URL_LOADER_LIMIT,
mimetype: 'image/svg+xml'
]
,
test: /\.(png|jpg|gif)$/,
use: [
loader: 'url-loader',
options:
outputPath: 'images/',
name: '[name].[ext]',
limit: URL_LOADER_LIMIT
]
]
)
【讨论】:
这个答案没有提供真正解决问题的解决方案。只是建议更新一个版本是可以的,但可能不是这里的问题,因为你还添加了一个长配置,请解释一下这个配置可能有什么不同。以上是关于使用 Webpack 和 font-face 加载字体的主要内容,如果未能解决你的问题,请参考以下文章
Webpack sass-loader,css-loader 在 scss 文件中与 font-face 中断
如何在 webpack 的 css-loader 中使用@font-face?