1

I'm trying to migrate our project build system from gulp to webpack due to the need to eventually bundle our Javascript code.

The issue I've come across is that I Webpack doesn't seem to be able to read import the fonts from SASS.

The directory is pretty standard, somewhat like this:

application
 |_assets
 | |__fonts
 | |__images
 | |__scripts
 | |__styles
 |
 |_public
 | |__fonts
 | |__images
 | |__scripts
 | |__styles
 ...

And in one of our .scss files, I import the fonts like this:

@include font-face('Visuelt', '../fonts/visuelt-regular');
@include font-face('VisueltMedium', '../fonts/visuelt-medium');
@include font-face('VisueltBold', '../fonts/visuelt-bold');
@include font-face('VisueltLight', '../fonts/visuelt-light');

The problem is that when I run the webpack build, the following error is thrown for each of the fonts:

ERROR in ./assets/styles/main.scss (./node_modules/css-loader!./node_modules/sass-loader/lib/loader.js!./assets/styles/main.scss) Module not found: Error: Can't resolve '../fonts/visuelt-bold.svg' in '/Users/jgarcia/Repositories/foo/assets/styles' @ ./assets/styles/main.scss (./node_modules/css-loader!./node_modules/sass-loader/lib/loader.js!./assets/styles/main.scss) 7:4499-4535

I have noticed that if I change the path to /fonts/visuelt-regular, webpack stops complaining. The problem is that then the fonts are not loaded when I run the application. In order for the bundled code to load the fonts properly, the bundled css must have ../fonts/visuelt-regular as the path. I'm not really sure I understand what's going on.

I've tried multiple things, but I can't seem to get it to work. Any insight?

This is the webpack config:

const path = require('path');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');

const buildPath = path.join(__dirname, 'public');

module.exports = {
  mode: 'development',
  entry: './assets/entry.js',
  output: {
    filename: 'assets/scripts/bundle.js',
    path: buildPath,
    publicPath: buildPath,
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: {
          loader: 'babel-loader',
          options: { // TODO Potentially not necesary?
            presets: ['@babel/preset-env'],
            plugins: ['@babel/plugin-transform-runtime'],
          },
        },
      },
      {
        test: /\.(jpe?g|png|gif|woff|woff2|eot|ttf|svg)(\?[a-z0-9=.]+)?$/,
        loader: 'file-loader',
        options: {
          name: '[path][name].[ext]',
          publicPath: 'assets/',
          emitFile: false,
        },
      },
      {
        test: /\.scss$/,
        use: [MiniCssExtractPlugin.loader, 'css-loader', 'sass-loader'],
      },
    ],
  },
  plugins: [
    new MiniCssExtractPlugin({
      filename: '/assets/styles/[name].css',
      chunkFilename: '[id].css',
    }),
    new CopyWebpackPlugin([
      { from: 'assets/fonts', to: 'assets/fonts' },
      { from: 'assets/images', to: 'assets/images' },
    ]),
  ],
};
Javier García Manzano
  • 1,024
  • 2
  • 12
  • 25
  • Why is this trying to load an SVG at all? The [svg font type died long ago](https://stackoverflow.com/questions/36105194/are-eot-ttf-and-svg-still-necessary-in-the-font-face-declaration/36110385#36110385)...? In fact, why is this trying to bundle static assets at all? The whole point of static assets is they almost never change so you just host them without any kind of bundling interference. – Mike 'Pomax' Kamermans Dec 11 '18 at 01:16
  • @Mike'Pomax'Kamermans The legacy gulp script used to simply move the fonts from `assets/fonts` to `public/assets/fonts`. The problem is webpack also checks that paths are correct and what else so what before was `../path-to-font` I had to translate to `/path-to-font` or webpack to stop moaning and copy the fonts. But I don't really understand why, when I run it, it actually requires the `../path-to-font` with the two dots in order to work. – Javier García Manzano Dec 11 '18 at 14:33
  • @Mike'Pomax'Kamermans I'm happy to change the approach if it makes sense though. Your suggestion would be to simply have the fonts in `public/assets/fonts` and don't move them around, right? How do I tell webpack to not process the import when Sass requires them though? That's what initially brought me to this issue listed above. – Javier García Manzano Dec 11 '18 at 14:36
  • Sass should be importing the font's associated @font-face css, not the font itself (and that css, for the modern browser landscape, should use woff2 and woff for fallback. Absolutely no otf/ttf/svg/eot anymore). What is the syntax you're using to get your webfonts loaded at the moment? – Mike 'Pomax' Kamermans Dec 11 '18 at 16:27

0 Answers0