使用 Webpack 和 font-face 加载字体

IT技术 css node.js reactjs webpack font-face
2021-03-31 12:38:37

我正在尝试使用我的 CSS 文件加载字体,@font-face但该字体从未加载。这是我的目录结构。

在此处输入图片说明

然后在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';
}

最后,我使用以下命令调用我的 CSS 文件index.js

import './src/css/master.css';

一切正常,但 de font 永远不会加载。

6个回答

在尝试了很多东西之后,下一个加载器完成了工作。我使用 url-loader 而不是 file-loader 。您需要安装 url-loader。

{ test: /\.(png|woff|woff2|eot|ttf|svg)$/, loader: 'url-loader?limit=100000' }
如果您使用 Webpack 5 及更高版本,这不再是答案。请参阅@arbob 的答案,其中包含“资产/资源”。
2021-05-22 12:38:37
内联 Base64 不是一个好主意,因为可以更有效地缓存外部资源。此外,它在移动设备上的解释速度慢了 30%,这是一个巨大的差异。
2021-05-27 12:38:37
在为这个错误挣扎了几个小时后,你救了我的命!
2021-06-19 12:38:37

使用 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-loaderfile-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'] }
    ]
  }
};

根据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 拾取,就像它与图像一样。

请仅链接答案没有用,即使它回答了问题。请将链接的相关部分添加到您的答案中
2021-05-29 12:38:37
这是 Webpack 5 的正确答案。任何其他涉及加载器的内容都已过时。不推荐使用文件加载器:v4.webpack.js.org/loaders/file-loader
2021-06-11 12:38:37

我遇到了同样的问题。在我的例子中,字体的 '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
      }
    }
  ]
}

关于它的更多信息在这里

这对我有用,但使用的是 url-loader,而不是文件加载器。我正在使用 webpack 4.43.0
2021-06-06 12:38:37

尝试将您的装载机更改为

{test: /\.(eot|svg|ttf|woff|woff2)$/, loader: 'file?name=[name].[ext]'}

并添加publicPath: 'build/'到您的output密钥中。

不,你应该同时拥有path: __dirname + '/build'publicPath: 'build/'请将 的内容添加index.html到您的问题中。
2021-05-24 12:38:37
我在 mi 控制台中收到此错误: 95% emitError: EACCES: permission denied, open '/Darkenstone.woff' at Error (native) 我已经删除了 Path: __dirname+"/build" 以添加 publicPath,这样可以吗?
2021-05-30 12:38:37
哦,好的,我已经从加载器中删除了 build/。那应该将字体放在构建文件夹的根目录中,是吗?然后添加publicPath: 'build/'output. 你可以打开index.html,找到style标签,看看字体的url是什么,应该是build/Darkenstone.woff
2021-06-04 12:38:37
在我的输出路径 (webpack.config.js) 中,我有“build”,因此使用该加载程序,我在 build 中获得了另一个 build 文件夹。诸如构建/构建之类的东西。
2021-06-07 12:38:37
实际上我已经用不同的加载器解决了我的问题,它在下面的答案中,但非常感谢您的帮助;)
2021-06-09 12:38:37