IncrediblePony
IncrediblePony

Reputation: 751

Webpack fonts looking in the wrong directory at build

I have a webpack project where during development everything works just fine but when I build my application the website looks in the wrong folder for my font files. I have a .scss file where in the top I have specified a $font_path = './assets/fonts/'; and the file lives in the src/scss/utils folder. When I have built my application the app looks for the files in ..../dist/static/css/static/fonts/filename.hash.ttf etc. and the actual files resides in the ..../dist/static/fonts folder.

Here is my webpack.common.js file (which is my base application setup):

'use strict';

const helpers = require('./helpers');
const path = require('path');
const webpack = require('webpack')

const VueLoaderPlugin = require('vue-loader/lib/plugin')

module.exports = {
    entry: {
        polyfill: '@babel/polyfill',
        main: path.resolve(__dirname, '../src/main.js'),
        vendor: path.resolve(__dirname, '../src/vendor.js')
    },
    module: {
        rules: [{
                test: /\.vue$/,
                loader: 'vue-loader',
                include: [helpers.root('src')]
            },
            {
                test: /\.html$/,
                use: [
                    'html-loader'
                ]
            },
            {
                test: /\.(jpe?g|gif|png)$/,
                use: {
                    loader: 'file-loader',
                    options: {
                        name: '[name].[hash].[ext]',
                        outputPath: 'static/img'
                    }
                }
            },
            {
                test: /\.(ttf|eot|woff2?|otf)$/,
                use: {
                    loader: 'url-loader',
                    options: {
                        name: 'static/fonts/[name].[hash].[ext]',
                        limit: 10000
                    }
                }
            },
            {
                test: /\.ico$/,
                use: {
                    loader: 'file-loader',
                    options: {
                        name: '[name].[hash].[ext]',
                        outputPath: 'static/img/icons'
                    }
                }
            },
            {
                test: /\.svg$/,
                use: [{
                        loader: 'svg-sprite-loader',
                        options: {
                            spriteFilename: 'sprites.svg',
                            runtimeCompat: true
                        }
                    },
                    {
                        loader: 'svgo-loader',
                        options: {
                            removeTitle: true,
                            removeUselessStrokeAndFill: true
                        }
                    }
                ]
            }
        ]
    },
    plugins: [
        new VueLoaderPlugin(),
    ]
};

And here is my webpack.prod.js file config for build:

const common = require('./webpack.common');
const merge = require('webpack-merge');
const helpers = require('./helpers');
const webpack = require('webpack');

const { CleanWebpackPlugin } = require('clean-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const TerserPlugin = require('terser-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin');

process.env.NODE_ENV = "production";

let dateStamp = new Date().toISOString().slice(0,10).replace(/-/g,"");

module.exports = merge(common, {
    mode: "production",
    resolve: {
        extensions: [ '.js', '.vue' ],
        alias: {
            'vue$': 'vue/dist/vue.runtime.min.js',
            '@': helpers.root('src')
        }
    },
    output: {
        filename: `[name].${dateStamp}.[contentHash].bundle.js`,
        path: helpers.root('dist')
    },
    optimization: {
        runtimeChunk: 'single',
        minimizer: [
            new OptimizeCssAssetsPlugin(), // CSS Minimization
            new TerserPlugin() // JS Minimization (UglifyJS replacement)
        ],
        splitChunks: {
            chunks: "all",
            maxInitialRequests: Infinity,
            minSize: 0
        }
    },
    plugins: [
        new webpack.EnvironmentPlugin({NODE_ENV: 'production'}),
        new MiniCssExtractPlugin({
            filename: `static/css/[name].${dateStamp}.[contentHash].css`
        }),
        new CleanWebpackPlugin(),
        new HtmlWebpackPlugin({
            template: "./index.html",
            inject: true,
            minify: {
                removeAttributeQuotes: true,
                collapseWhitespace: true,
                removeComments: true
            }
        })
    ],
    module: {
        rules: [
            {
                test: /\.(scss|sass)$/,
                use: [
                    MiniCssExtractPlugin.loader, 
                    "css-loader", 
                    "sass-loader"
                ]
            },
            {
                test: /\.css$/,
                use: [
                    'style-loader',
                    'css-loader'
                ]
            }
        ]
    }
});

Hope you can spot my error.

EDIT Adding ./src/scss/utils/fonts.scss since I have a knawing feeling that this is where something messes up.

$font_path: './assets/fonts/';

/* Comfortaa */

@font-face {
    font-family: "Comfortaa";
    font-weight: 300;
    font-style: normal;
    src: url($font_path + 'Comfortaa/Comfortaa_Thin.ttf') format("truetype")
}

@font-face {
    font-family: "Comfortaa";
    font-weight: 400;
    font-style: normal;
    src: url($font_path + 'Comfortaa/Comfortaa_Regular.woff') format("woff"),
        url($font_path + 'Comfortaa/Comfortaa_Regular.woff2') format("woff2"),
        url($font_path + 'Comfortaa/Comfortaa_Regular.ttf') format("truetype"),
        url($font_path + 'Comfortaa/Comfortaa_Regular.eot') format("embedded-opentype"),
        // url($font_path + 'Comfortaa/Comfortaa_Regular.svg') format("svg")
}

@font-face {
    font-family: "Comfortaa";
    font-weight: 700;
    font-style: normal;
    src: url($font_path + 'Comfortaa/Comfortaa_Bold.ttf') format("truetype")
}

/* ROBOTO */

@font-face {
    font-family: "Roboto";
    font-weight: 100;
    font-style: normal;
    src: url($font_path + 'Roboto/Roboto-Thin.woff') format("woff"),
        url($font_path + 'Roboto/Roboto-Thin.woff2') format("woff2"),
        url($font_path + 'Roboto/Roboto-Thin.ttf') format("truetype"),
        url($font_path + 'Roboto/Roboto-Thin-webfont.eot') format("embedded-opentype"),
        // url($font_path + 'Roboto/Roboto-Thin-webfont.svg') format("svg");
}

@font-face {
    font-family: "Roboto";
    font-weight: 300;
    font-style: normal;
    src: url($font_path + 'Roboto/Roboto-Light.woff') format("woff"),
        url($font_path + 'Roboto/Roboto-Light.woff2') format("woff2"),
        url($font_path + 'Roboto/Roboto-Light.ttf') format("truetype"),
        url($font_path + 'Roboto/Roboto-Light-webfont.eot') format("embedded-opentype"),
        // url($font_path + 'Roboto/Roboto-Light-webfont.svg') format("svg");
}

@font-face {
    font-family: "Roboto";
    font-weight: 400;
    font-style: normal;
    src: url($font_path + 'Roboto/Roboto-Regular.woff') format("woff"),
        url($font_path + 'Roboto/Roboto-Regular.woff2') format("woff2"),
        url($font_path + 'Roboto/Roboto-Regular.ttf') format("truetype"),
        url($font_path + 'Roboto/Roboto-Regular-webfont.eot') format("embedded-opentype"),
        // url($font_path + 'Roboto/Roboto-Regular-webfont.svg') format("svg");
}

@font-face {
    font-family: "Roboto";
    font-weight: 500;
    font-style: normal;
    src: url($font_path + 'Roboto/Roboto-Medium.woff') format("woff"),
        url($font_path + 'Roboto/Roboto-Medium.woff2') format("woff2"),
        url($font_path + 'Roboto/Roboto-Medium.ttf') format("truetype"),
        url($font_path + 'Roboto/Roboto-Medium-webfont.eot') format("embedded-opentype"),
        // url($font_path + 'Roboto/Roboto-Medium-webfont.svg') format("svg");
}

@font-face {
    font-family: "Roboto";
    font-weight: 700;
    font-style: normal;
    src: url($font_path + 'Roboto/Roboto-Bold.woff') format("woff"),
        url($font_path + 'Roboto/Roboto-Bold.woff2') format("woff2"),
        url($font_path + 'Roboto/Roboto-Bold.ttf') format("truetype"),
        url($font_path + 'Roboto/Roboto-Bold-webfont.eot') format("embedded-opentype"),
        // url($font_path + 'Roboto/Roboto-Bold-webfont.svg') format("svg");
}

/* SOURCE SANS PRO */

@font-face {
    font-family: "Source Sans Pro";
    font-weight: 100;
    font-style: normal;
    src: url($font_path + 'SourceSans/SourceSansPro-ExtraLight.otf.woff') format("woff"),
        url($font_path + 'SourceSans/SourceSansPro-ExtraLight.otf.woff2') format("woff2"),
        url($font_path + 'SourceSans/SourceSansPro-ExtraLight.ttf') format("truetype"),
        url($font_path + 'SourceSans/SourceSansPro-ExtraLight.eot') format("embedded-opentype"),
        url($font_path + 'SourceSans/SourceSansPro-ExtraLight.otf') format("otf");
}

@font-face {
    font-family: "Source Sans Pro";
    font-weight: 300;
    font-style: normal;
    src: url($font_path + 'SourceSans/SourceSansPro-Light.otf.woff') format("woff"),
        url($font_path + 'SourceSans/SourceSansPro-Light.otf.woff2') format("woff2"),
        url($font_path + 'SourceSans/SourceSansPro-Light.ttf') format("truetype"),
        url($font_path + 'SourceSans/SourceSansPro-Light.eot') format("embedded-opentype"),
        url($font_path + 'SourceSans/SourceSansPro-Light.otf') format("otf");
}

@font-face {
    font-family: "Source Sans Pro";
    font-weight: 400;
    font-style: normal;
    src: url($font_path + 'SourceSans/SourceSansPro-Regular.otf.woff') format("woff"),
        url($font_path + 'SourceSans/SourceSansPro-Regular.otf.woff2') format("woff2"),
        url($font_path + 'SourceSans/SourceSansPro-Regular.ttf') format("truetype"),
        url($font_path + 'SourceSans/SourceSansPro-Regular.eot') format("embedded-opentype"),
        url($font_path + 'SourceSans/SourceSansPro-Regular.otf') format("otf");
}

@font-face {
    font-family: "Source Sans Pro";
    font-weight: 500;
    font-style: normal;
    src: url($font_path + 'SourceSans/SourceSansPro-Semibold.otf.woff') format("woff"),
        url($font_path + 'SourceSans/SourceSansPro-Semibold.otf.woff2') format("woff2"),
        url($font_path + 'SourceSans/SourceSansPro-Semibold.ttf') format("truetype"),
        url($font_path + 'SourceSans/SourceSansPro-Semibold.eot') format("embedded-opentype"),
        url($font_path + 'SourceSans/SourceSansPro-Semibold.otf') format("otf");
}

@font-face {
    font-family: "Source Sans Pro";
    font-weight: 700;
    font-style: normal;
    src: url($font_path + 'SourceSans/SourceSansPro-Bold.otf.woff') format("woff"),
        url($font_path + 'SourceSans/SourceSansPro-Bold.otf.woff2') format("woff2"),
        url($font_path + 'SourceSans/SourceSansPro-Bold.ttf') format("truetype"),
        url($font_path + 'SourceSans/SourceSansPro-Bold.eot') format("embedded-opentype"),
        url($font_path + 'SourceSans/SourceSansPro-Bold.otf') format("otf");
}

Upvotes: 1

Views: 3374

Answers (1)

IncrediblePony
IncrediblePony

Reputation: 751

Right.. So I don't know what was wrong - but this solved my issues (and it's ugly AF but it works)

The browser after compilation was looking for my fonts in ./dist/static/css/static/fonts/some_name.ttf etc. I of course wanted it to be ./dist/static/fonts/some_name.ttf. I changed and moved my old config from webpack.common.js that looked like this:

{
   test: /\.(ttf|eot|woff2?|otf)$/,
   use: {
       loader: 'url-loader',
       options: {
           name: 'static/fonts/[name].[hash].[ext]',
           limit: 10000
        }
    }
},

And moved this into my webpack.dev.js file. Because my dev env worked perfectly. Then in my webpack.prod.js I copied the setup and added an outputPath and a publicPath to my url-loader and this now looks as follows:

{
    test: /\.(ttf|eot|woff2?|otf)$/,
    use: {
         loader: 'url-loader',
         options: {
             name: '[name].[hash].[ext]',
             outputPath: 'static/fonts',
             publicPath: './../fonts',
             limit: 10000
         }
     }
 },

so I tell the build to put my files into the ./dist/static/fonts directory and the publicPath is set to be one folder up from where it's currently looking then go into fronts

Upvotes: 2

Related Questions