Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Webpack 5 issues with fonts getting Failed to decode & OTS parsing error

Tags:

webpack

fonts

Please could someone shed some light into the issues I'm having with Webpack. I've not used Webpack for fonts before and have run into a bit of a headache I've not been able to solve. I'm pulling the fonts from a .css file using url().

What I'm getting after Webpack has done its thing is 3 .woff files with their names changed to a hash like name. I then have a fonts folder with the 3 fonts in named correctly. Looking at the main.css (the one Webpack produced) the url() is now looking at the font files with the hash names. When I open the hash named .woff files its an export command pointing to the fonts folder and to the correct font.... Is this how it meant to work?

When I load up the webpack in the console I have errors for each file: Failed to decode downloaded font: http://localhost/OPM/wpcontent/themes/theme/assets/build/b4f8bd69b3d37cc51e2b.woff OTS parsing error: invalid sfntVersion: 1702391919

This is wants in the .woff file export default __webpack_public_path__ + "fonts/font-icons.woff";

const path = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin'); 
const cssnano = require( 'cssnano');
const UglifyJsPlugin = require( 'uglifyjs-webpack-plugin');

const JS_DIR = path.resolve(__dirname, 'src/js');
const IMG_DIR = path.resolve(__dirname, 'src/img');
const BUILD_DIR = path.resolve(__dirname, 'build');

const entry ={
    main: JS_DIR + '/main.js',
}

const output = {
    path: BUILD_DIR,
    filename: 'js/[name].js'
};

const rules = [
    {
        test: /\.js$/,
        include: [JS_DIR],
        exclude: /node_modules/,
        use: 'babel-loader'
    },
    {
        test: /\.css$/,
        exclude: /node_modules/,
        use: [
            {
            loader: MiniCssExtractPlugin.loader,
            options: {

        
              },
            },
            'css-loader',
        ],
    },
    /*{
        test: /\.(png|jpg\svg\jpeg\gif\ico)$/,
        use: [
            {
                loader:'file-loader',
                options:{
                    name: '[path][name].[ext]',
                    publicPath: 'production' === process.env.NODE_ENV ? '../' : '../../',
                }
            }]
    },*/
    {
        test: /\.(woff|woff2)$/,
        use: {
          loader: 'file-loader',
          options:{
            name: '[name].[ext]',
            //publicPath: 'production' === process.env.NODE_ENV ? '../' : '../../',
            outputPath: './fonts/',
          }
        },
      },
   
];

const plugins = ( argv ) => [
    new CleanWebpackPlugin({
        cleanStaleWebpackAssets: ( 'production' === argv.mode )
    }),

    new MiniCssExtractPlugin({
        filename: 'css/[name].css'
    })
];

module.exports = (env, argv) => ({
    entry: entry,
    output: output,
    devtool: 'source-map',
    module:{
        rules: rules,
    },
    optimization:{
        minimizer:[
            /*new OptimizeCssAssetsPlugin({
                cssProcessor: cssnano,
            }),*/
            new UglifyJsPlugin({
                cache: false,
                parallel: true,
                sourceMap: false,
            })
        ]
    },
    plugins: plugins( argv ),
    externals: {
        jquery: 'jQuery'
    }
});
like image 762
monkeyman905 Avatar asked Aug 18 '21 20:08

monkeyman905


1 Answers

tl;dr;

  use: {
    loader: 'file-loader',

All constructions like the above have to be replaced with the type: asset/resource (the entire use block).

Here is an example of what I did to solve the exact same issue on the project I work on.

Before:

        {
          test: /\.eot(\?v=\d+.\d+.\d+)?$/,
          use: [
            {
              loader: 'url-loader',
              options: {
                name: '[name].[ext]',
              },
            },
          ],
        },
        {
          test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/,
          use: [
            {
              loader: 'url-loader',
              options: {
                limit: 10000,
                mimetype: 'application/font-woff',
                name: '[name].[ext]',
              },
            },
          ],
        },
        {
          test: /\.[ot]tf(\?v=\d+.\d+.\d+)?$/,
          use: [
            {
              loader: 'url-loader',
              options: {
                limit: 10000,
                mimetype: 'application/octet-stream',
                name: '[name].[ext]',
              },
            },
          ],
        },
        {
          test: /\.svg(\?v=\d+\.\d+\.\d+)?$/,
          use: [
            {
              loader: 'url-loader',
              options: {
                limit: 10000,
                mimetype: 'image/svg+xml',
                name: '[name].[ext]',
              },
            },
          ],
        },
        {
          test: /\.(jpe?g|png|gif|ico)$/i,
          use: [
            {
              loader: 'file-loader',
              options: {
                name: '[name].[ext]',
              },
            },
          ],
        },

After:

        {
          test: /\.(jpe?g|svg|png|gif|ico|eot|ttf|woff2?)(\?v=\d+\.\d+\.\d+)?$/i,
          type: 'asset/resource',
        },

The file-loader and url-loader have been deprecated and are conflicting with css-loader 6.x.

Consider removing the file-loader and url-loader and use the Asset Modules built into Webpack 5.

Another option might be to stick to the css-loader 5.x, but not recommended.

like image 151
BR0kEN Avatar answered Oct 16 '22 19:10

BR0kEN