字体图标库FontAwesome的Web字体有时由于Webpack构建而无法加载

3
我刚刚将我们项目中旧的CSS和JS构建过程从grunt(以及less中的CSS)迁移到了webpack 5(以及scss中的CSS),一切似乎都很好。然而,有一个问题:有时候它看起来不像这样 how it looks normally 以下是在DevTools中查看心形图标的截图:
.fa-heart:before {
    content: "";
}

Fontawesome字体似乎无法正确加载,而是以这种方式加载:

completely broken

当我在DevTools中检查时,心形图标看起来像这样。

.fa-heart:before {
    content: "";
}

我本来期望能看到

.fa-heart:before {
    content: "\f004";
}

当我在DevTools中手动更改它时,它可以正常工作。

当我在浏览器中启动lighthouse审核时,可以重现此问题:当lighthouse完成最后一次加载时,它总是看起来像这样。

我真的不知道该如何解决这个问题。我尝试使用webfontloader来加载字体,但这并没有解决问题。

我在我的main.scss中这样包含fontawesome:

@import "~@fortawesome/fontawesome-pro/scss/fontawesome";
@import "~@fortawesome/fontawesome-pro/scss/light";
@import "~@fortawesome/fontawesome-pro/scss/solid";

以下是我webpack配置的简化版(少了一些条目):
module.exports = {
  entry: {
    './dist/styles.min': { import: './src/sass/main.scss' },
    './dist/scripts.min.js': { import: './src/js/scripts.js' },
  }
  module: {
    rules: [
      {
        test: require.resolve("jquery"),
        loader: "expose-loader",
        options: {
          exposes: ["$", "jQuery", "jquery"],
        },
      },
      {
        test: /\.s?[ac]ss$/i,
        use: [
          // Compiles Sass to CSS
          MiniCssExtractPlugin.loader,
          "css-loader",
          "sass-loader",
        ],
      },
      {
        test: /\.jsx?$/,
        exclude: /(node_modules|bower_components)/,
        use: {
          loader: "babel-loader",
          options: {
            presets: [["@babel/preset-env", { debug: false, useBuiltIns: "usage", corejs: 3 }], "@babel/preset-react"],
            plugins: [["@babel/plugin-transform-runtime", { corejs: 3 }]],
          },
        },
      },
      {
        test: /(ignore)/,
        use: {
          loader: "ignore-loader",
        },
      },
      {
        test: /\.(png|jpe?g|gif|svg|ttf|eot|woff2?)$/i,
        use: [
           {
            loader: "file-loader",
            options: {
              outputPath: "dist/assets/",
              publicPath: "/assets/",
            },
          },
        ],
      },
    ]
  },
  output: {
    path: __dirname,
    filename: "[name]?[contenthash]",
  },
  resolve: {
    extensions: [".jsx", ".js", ".json"],
  },
  plugins: [
    new MiniCssExtractPlugin({
      filename: "[name].css?[contenthash]",
    }),
  ],
optimization: {
    minimize: !DEV_MODE,
    minimizer: [
      "...",
      new TerserPlugin({ extractComments: false }),
      new CssMinimizerPlugin(),
    ],
    splitChunks: {
      cacheGroups: {
        polyfills: {
          test: /[\\/]node_modules[\\/](@babel|core-js|regenerator|promise)/,
          name: "./dist/polyfills.min.js",
          chunks: "all",
        },
        vendor: {
          test: /[\\/]node_modules[\\/](slick|bootstrap|jquery)/,
          name: "./dist/vendor.min.js",
          chunks: "all",
        },
      },
    },
  },
}
2个回答

2

"\f004" 实际上等同于 "",但字符""可能是由于您的CSS缺少@charset "UTF-8"规则而发生的。在最小化过程中,它可能被剥离。

这可能发生在 terser-webpack-plugin (请参见此问题) 中。您可以尝试将以下内容添加到webpack配置中:

TerserPlugin({
  terserOptions: { output: { ascii_only: true } }
})

更多信息:https://medium.com/@thinkpanda_75045/webpack-with-unicode-7a2c5eb22afd

类似问题:https://github.com/FortAwesome/Font-Awesome/issues/17644


1
感谢您提供类似问题的链接。我尝试了您的建议以及链接中提出的许多建议。有帮助的是降级到sass@1.10.4,它不会将转义序列转换为它们的Unicode等效项。 - Taxel

1

*为了确定这个解决方案是否能够解决你的问题,你可以按照第10步,使用简单的测试方法来验证。

下面详细说明如何解决奇怪图标的问题,并使用“fa-user”图标(Unicode \f007)作为示例,该图标是网站上最常用的图标之一:

之前:[在此输入图片描述][1]

之后:[在此输入图片描述][2]

我尝试过:网站上已经建议添加 @charset 'utf-8'。但是将其添加到我的 fontawesome.scss 文件的顶部并不能解决奇怪图标的问题,因为 @charset 声明会在编译时被删除。

我们目前正在使用 fontawesome 的 fontawesome-subset 特性自主托管 icon,以减小文件大小,并使用 Sass 1.58.3、sass-loader 和 css-loader 与 Webpack 4 编译我们的 scss 文件。

以下是可执行的步骤,以验证图标是否正确显示:我执行了以下步骤,以确认结果的准确性

  1. 前往网站。

  2. 按下Ctrl+U或右键选择“查看页面源代码”。

  3. 点击样式表的href链接。例如:

  4. 搜索图标,如“fa-user”。

  5. 如果问题已解决,则图标应显示Unicode内容“f007”或正确的符号。 [插入图片描述][3]

  6. 如果图标显示为[?],请再次检查确保它是正确的,可以在网上搜索它。

  7. [插入图片描述][4]

  8. 将[?]复制并粘贴到搜索引擎中,以检查它是否显示为Unicode。 [插入图片描述][5]

  9. 此解决方案适用于fontawesome 5和6,因为我在两个版本上都进行了测试。

  10. 为了快速检查和验证此解决方案是否能解决问题,您可以尝试在编译后的CSS文件开头添加@charset "utf-8";。[插入图片描述][6]

解决方案: 解决问题的方法是添加npm包“[add-charset-webpack-plugin][7]”。该包会自动在所有最终生成的CSS文件的第一行添加字符集声明,确保浏览器正确指定和解释UTF-8编码。

应用方法: 在你的webpack.config.js文件中:

  1. 导入包: import AddCharsetWebpackPlugin from 'add-charset-webpack-plugin';

  2. 将插件添加到plugins:[]部分中: new AddCharsetWebpackPlugin({ charset: "utf-8" }),

希望这有所帮助! [1]: https://istack.dev59.com/0pPvK.webp [2]: https://istack.dev59.com/bBdFU.webp [3]: https://istack.dev59.com/GHFsY.webp [4]: https://istack.dev59.com/hI6EJ.webp [5]: https://istack.dev59.com/asPO0.webp [6]: https://istack.dev59.com/VXbZY.webp [7]: https://www.npmjs.com/package/add-charset-webpack-plugin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接