javascript Webpack 5:文件加载器生成带有hash-name的字体副本

tyu7yeag  于 2023-01-24  发布在  Java
关注(0)|答案(6)|浏览(129)

我不知道这里发生了什么。我使用文件加载器来加载我的应用程序的字体:

{
    test: /.(ttf|otf|eot|svg|woff(2)?)(\?[a-z0-9]+)?$/,
    use: [{
      loader: 'file-loader',
      options: {
        name: '[name].[ext]',
        outputPath: 'assets/fonts/',
        publicPath: '../fonts/'
      }
    }]
  },

字体也是在我指定的结构中生成的:dist/assets/fonts. outputPath: 'assets/fonts/'...看起来工作正常。

**但是:**Webpack还将字体以哈希值作为名称打包在/dist下,并在CSS文件中设置这些文件的路径。

@font-face{font-family:"PaulGrotesk";font-style:normal;font-weight:400;src:url(../../d9bc4e30281429c0cddd.eot);

这里发生了什么?我怎样才能防止额外的文件被生成并用作路径?

我在用

  • 网络包:^5.47.1
  • 网络包-客户端:第四章第七节第二节
    我的网络包配置:
const path = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {

  entry: './src/index.js',

  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'assets/js/bundle_v1.0.0.js'
  },

  module: {

    rules: [

      {
        test: /\.js?$/,
        exclude: /node_modules/,
        loader: 'babel-loader',
        include: path.join(__dirname, 'index'),
        options: {
          presets: ['@babel/preset-env']
        }
      },

      {
        test: /.(ttf|otf|eot|svg|woff(2)?)(\?[a-z0-9]+)?$/,
        use: [{
          loader: 'file-loader',
          options: {
            name: '[name].[ext]',
            outputPath: 'assets/fonts/',
            publicPath: '../fonts/'
          }
        }]
      },

      {
        test: /\.scss$/,
        use: [
          MiniCssExtractPlugin.loader,
          {
            loader: 'css-loader'
          },
          {
            loader: 'sass-loader',
            options: {
              sourceMap: true,
            }
          }
        ]
      },

      {
        test: /\.css$/i,
        use: [MiniCssExtractPlugin.loader, 'css-loader'],
      },

    ]
  },
  resolve: {
    alias: {
      '@': path.resolve(__dirname, 'node_modules'),
      /* https://webpack.js.org/configuration/resolve/ */
    },
  },
  plugins: [

    new MiniCssExtractPlugin({
      filename: 'assets/css/bundle_v1.0.0.css'
    }),

    new HtmlWebpackPlugin({
      inject: 'body',
      template: './src/index.html',
      filename: 'index.html',
    })

  ]

};
qltillow

qltillow1#

我遇到的问题与OP(@toge)从Webpack 4迁移到5时遇到的问题完全相同。当我希望实施@seanbun发布的解决方案时,我遇到了新Webpack 5资产模块配置的以下设置,它允许我正确生成以前的file-loader svgs和字体文件,而不会在根输出文件夹中复制:

{
    test: /\.(woff(2)?|ttf|eot)$/,
    type: 'asset/resource',
    generator: {
        filename: './fonts/[name][ext]',
    },
},

这告诉webpack通过资产模块配置来处理它,但是输出到一个定制的文件路径,类似于file-loader配置过去的工作方式。
这个设置还消除了我降级css-loader的需要,这是一个额外的好处

llycmphe

llycmphe2#

显然,Webpack 5有一个Asset Modules函数,允许用户使用资产文件(字体、图标等),而无需配置额外的加载程序,即file-loaderurl-loader等。Asset Modules提供了四种类型来处理不同类型的资产。您可以在https://webpack.js.org/guides/asset-modules/找到更多细节。
因此,当您为字体文件添加以下规则时,Asset Modulesfile-loader将实际处理这些文件。

{
        test: /.(ttf|otf|eot|svg|woff(2)?)(\?[a-z0-9]+)?$/,
        use: [{
          loader: 'file-loader',
          options: {
            name: '[name].[ext]',
            outputPath: 'assets/fonts/',
            publicPath: '../fonts/'
          }
        }]
    }

在这种情况下,我们希望使用我们自己的file-loader并禁用Asset Module。我们可以将类型设置为“javascript/auto”。这将遵循您的路径设置并将字体文件保存在assets/fonts文件夹中。

{
        test: /.(ttf|otf|eot|svg|woff(2)?)(\?[a-z0-9]+)?$/,
        **type: "javascript/auto",**
        use: [{
          loader: 'file-loader',
          options: {
            name: '[name].[ext]',
            outputPath: 'assets/fonts/',
            publicPath: '../fonts/'
          }
        }]
    }

我正在使用css-loader 6.2.0,出现了错误-url.replace is not a function。我降级到css-loader 5.2.7来解决这个问题。

cvxl0en2

cvxl0en23#

加载器是从最后到第一个应用的。所以我的猜测是,将文件加载器放置在css/sass加载器下面可以解决这个问题。
当css加载程序需要字体时,字体可能不会以这种方式注册,因此会加载两次。

wlp8pajw

wlp8pajw4#

我已经把字体文件放在一个可服务的位置,所以我不需要复制这些资源(我很困惑为什么webpack默认这样做)。我的解决方案是通过以下方式忽略这些文件:

new webpack.IgnorePlugin({
      resourceRegExp: /\.(woff(2)?|ttf|eot|svg)$/
    }),
3ks5zfa0

3ks5zfa05#

我遇到过类似的问题,但在我的情况下,问题通过“type:'asset/inline'”解决

{
      test: /\.(woff|woff2|ttf|otf|eot)$/,
      type:'asset/inline',
      exclude: /node_modules/,
      loader: 'file-loader',
      options: {          
        esModule: false,
        name: '[name].[ext]',
        outputPath: '../assets/fonts/',
        publicPath: '../assets/fonts/'
      }
    },
xlpyo6sf

xlpyo6sf6#

我有一段时间遇到了类似的问题,这里是我如何通过添加两行代码来解决这个问题的。类型:“javascript/自动”esModule:错误

{
test: /\.(ttf|otf|eot|svg|woff(2)?)(\?[a-z0-9]+)?$/,
exclude: [IMG_DIR, /node_modules/],
type: "javascript/auto",
use: {
  loader: "file-loader",
  options: {
    name: "[name].[ext]",
    publicPath: "../assets/fonts/",
    esModule: false,
  }

我希望这能解决它:)

相关问题