【问题标题】:Webpack can't load fonts (ttf)Webpack 无法加载字体 (ttf)
【发布时间】:2018-09-27 08:44:28
【问题描述】:

目前我有 3 种字体要添加到我的 React 项目中:a、light、bold
我的文件结构:

/src
├── /fonts/
│   ├── /A.ttf
│   ├── /A-light.ttf
│   └── /A-bold.ttf
│  
├── /styles/
│   ├── /base/
│   │   └── /__base.scss
│   └── styles.scss
│ 
├── app.jsx
└── webpack.config.js

_base.scss:

@font-face {
  font-family: "A";
  font-style: normal;
  font-weight: 400;
  src: url("../../fonts/A.ttf") format("truetype");
}

@font-face {
  font-family: "A";
  font-style: normal;
  font-weight: 800;
  src: url("../../fonts/A-bold.ttf") format("truetype");
}
@font-face {
  font-family: "A";
  font-style: normal;
  font-weight: 300;
  src: url("../../fonts/A-light.ttf") format("truetype");
}
body {
  font-family: A, Helvetica, Arial, sans-serif;
}

_base.scss 由styles.scss 导入,styles.scss 由app.jsx 导入。

我的 webpack 配置如下所示:
webpack.config.js

const path = require('path');
const webpack = require('webpack');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const StyleLintPlugin = require('stylelint-webpack-plugin');

process.env.NODE_ENV = process.env.NODE_ENV || 'development';
console.log(process.env.NODE_ENV);
if (process.env.NODE_ENV === 'development') {
  require('dotenv').config({path: '.env.development'});
}

module.exports = env => {
  const isProduction = env === 'production';
  const CSSExtract = new ExtractTextPlugin('styles.css');

  return {
    entry: ['babel-polyfill', './src/app.jsx'],
    output: {
      path: path.join(__dirname, 'public', 'dist'),
      filename: 'bundle.js'
    },
    resolve: {
      extensions: ['.js', '.jsx', '.json', '.css', '.scss']
    },
    module: {
      rules: [
        {
          exclude: /(node_modules|bower_components)/,
          test: /\.jsx?$/,
          use: ['babel-loader', 'eslint-loader']
        },
        {
          test: /\.s?css$/,
          use: CSSExtract.extract({
            use: [
              {
                loader: 'css-loader',
                options: {
                  sourceMap: true
                }
              },
              {
                loader: 'sass-loader',
                options: {
                  sourceMap: true
                }
              }
            ]
          })
        },
        {
          test: /\.(png|jpg|svg)$/,
          use: {
            loader: 'url-loader'
          }
        },
        {
          test: /\.(ttf|eot|woff|woff2)$/,
          loader: 'file-loader',
          options: {
            name: 'fonts/[name].[ext]'
          }
        }
      ]
    },
    plugins: [
      CSSExtract,
      new webpack.DefinePlugin({
        'process.env.API_AUTH_TOKEN': JSON.stringify(process.env.API_AUTH_TOKEN),
        'process.env.API_EMAIL': JSON.stringify(process.env.API_EMAIL),
        'process.env.API_PASSWORD': JSON.stringify(process.env.API_PASSWORD)
      }),
      new StyleLintPlugin({})
    ],
    devtool: isProduction ? 'source-map' : 'inline-source-map',
    devServer: {
      overlay: {
        warnings: true,
        errors: true
      },
      contentBase: path.join(__dirname, 'public'),
      historyApiFallback: true,
      publicPath: '/dist/'
    }
  };
};

但是 Webpack 无法编译。

错误:

./src/styles/styles.scss 模块构建失败:ModuleNotFoundError:找不到模块:错误:无法解析“../../fonts/A.ttf”

任何帮助将不胜感激!

【问题讨论】:

  • 我意识到这是很久以前的事了,但是您的 src 语句 src: url("../../fonts/A.ttf") 不应该有一个额外的 ../ 来查找字体目录吗?
  • 整个互联网上没有一个资源可以显示完整、简单的工作示例。难以置信。

标签: reactjs webpack fonts font-face webpack-3


【解决方案1】:

关于 Webpack 5:如果这对其他人有帮助,这里有一个解决方案,用于解决使用 Webpack 5 加载 truetype 字体时遇到的常见问题。这实际上是一个 CSS 问题。

在文档的 Webpack 5 资产管理部分,在“加载字体”标题下,style.css 文件具有以下示例 @font-face 声明:

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

为了使此声明与其他字体类型(例如 truetype 或 opentype 字体)一起使用,需要正确指定 format。以下任何format 类型均有效:

“woff”、“woff2”、“truetype”、“opentype”、“embedded-opentype”、“svg”。

例如,如果将format 类型设置为“ttf”或“otf”,则不会导入字体。 format 类型用于告诉浏览器字体的格式,但不是强制性的,因此,如果您将其省略,您的字体仍应正确加载。

假设您已正确设置字体的路径,此示例应按预期工作:

@font-face {
   font-family: 'MyFont';
   src: url('./my-font.ttf') format('truetype');
}

这也应该有效:

@font-face {
   font-family: 'MyFont';
   src: url('./my-font.ttf');
}

【讨论】:

    【解决方案2】:

    从 webpack 5 开始,您可以改用内置资产模块。来自官方 Webpack 指南 here,将其添加到 module.rules 以加载 .ttf 文件:

    {
      test: /\.(woff|woff2|eot|ttf|otf)$/i,
      type: 'asset/resource',
    },
    
    

    【讨论】:

      【解决方案3】:

      在字体路径前加上~,告诉Webpack这不是相对导入 https://github.com/webpack-contrib/sass-loader#imports

      【讨论】:

        【解决方案4】:

        使用 npm 中的“ttf-loader”对我来说非常有效。

        https://www.npmjs.com/package/ttf-loader

        module: {
          rules: [
            {
              test: /\.ttf$/,
              use: [
                {
                  loader: 'ttf-loader',
                  options: {
                    name: './font/[hash].[ext]',
                  },
                },
              ]
            }
          ]
        }
        

        【讨论】:

          【解决方案5】:

          Webpack 需要字体加载器来加载项目中存在的字体文件。您正在使用文件加载器来加载字体。 改变

          {
                test: /\.(ttf|eot|woff|woff2)$/,
                loader: 'file-loader',
                options: {
                name: 'fonts/[name].[ext]'
           }
          

           {
                test: /\.ttf$/,
                use: [
                  {
                    loader: 'ttf-loader',
                    options: {
                      name: './font/[hash].[ext]',
                    },
                  },
                ]
            }
          

          通过在您的项目中安装字体加载器,例如 TTF Loader 来自NPM

          【讨论】:

          • 感谢您的回复,但不幸的是,这并没有帮助。此外,我已将“'./font/[hash].[ext]'”更改为“name: './fonts/[hash].[ext]'”。
          • 你应该在你的代码中导入 ttfs !从 'name-of-font.ttf' 导入 someFontFamily;
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2017-06-05
          • 1970-01-01
          • 1970-01-01
          • 2015-09-19
          • 2022-08-19
          • 2017-02-02
          • 2015-06-26
          相关资源
          最近更新 更多