Laravel Mix generate fonts into another directory
Asked Answered
H

6

23

I'm using laravel-mix which is built on the top of the webpack. I'm facing a problem with fonts directory. For Example, font-awesome package has a scss file and a font directory where all fonts are placed.

font-awesome:.
├───scss
│       fontawesome.scss
└───webfonts
        fa-regular-400.eot
        fa-regular-400.svg
        fa-regular-400.ttf
        fa-regular-400.woff
        fa-regular-400.woff2

So i place this package in my resources/assets/sass directory.

resources:.
└───asset
    └───sass
        │   main.scss
        │
        └───font-awesome (directory)

main.scss contains code:

@import 'font-awesome/scss/fontawesome';

webpack.mix.js contains:

mix.sass('resources/assets/sass/main.scss', 'public/css/frontend.css');

All assets are compiled successfully. Now public directory has a css and font directory, which has all fonts like this.

public:.
│   index.php
│
├───css
│       frontend.css
│
├───fonts
│       fa-regular-400.eot
│       fa-regular-400.svg
│       fa-regular-400.ttf
│       fa-regular-400.woff
│       fa-regular-400.woff2

But What I want is, I don't want to compile all fonts into public/fonts directory i want to compile as following structure public/fonts/vendor/font-awesome

public:.
├───css
│       frontend.css
│
└───fonts
    └───vendor
        └───font-awesome
                fa-regular-400.eot
                fa-regular-400.svg
                fa-regular-400.ttf
                fa-regular-400.woff
                fa-regular-400.woff2

What changes that i need to change in webpack.mix.js file.

Hitormiss answered 14/6, 2018 at 15:9 Comment(0)
G
6

1. First Create a explicit folder structure:

like this in your laravel project.

public/fonts/vendor/font-awesome

Move all your fonts from font-awesome package to above mention directory.

2. Change $fa-font-path variable value:

font-awesome directory has a file called _variables.scss inside that file there is a variable named as $fa-font-path change the value to something like this.

$fa-font-path: "/fonts/vendor/font-awesome" !default;

Compile your assets it would work.

Greasy answered 14/6, 2018 at 16:36 Comment(0)
R
23

If you want to use the laravel-mix and try to change public/fonts to public/assets/fonts directory, You can use this code in your webpack.mix.js

let mix = require('laravel-mix');
mix.config.fileLoaderDirs.fonts = 'assets/fonts';
Rebus answered 20/4, 2019 at 19:36 Comment(3)
Not working on current Laravel-mix version 6.0.16. Getting this error: Cannot read property 'fileLoaderDirs' of undefinedPrimogeniture
I just figured out, on recent versions of Laravel-mix (6.0) replace config by options, so it will work as intended: mix.options.fileLoaderDirs.fonts = 'assets/fonts'Primogeniture
you can do like this: mix.options({ fileLoaderDirs: { fonts: 'assets/fonts' }, });Exonerate
S
16

Try to copy them directly like this:

mix.copyDirectory('assets/font-awesome/webfonts', 'public/fonts');

Or you can copy files one by one:

mix.copy('assets/font-awesome/webfonts/example.ttf', 'public/fonts/example.ttf');
Situated answered 14/6, 2018 at 15:41 Comment(0)
G
6

1. First Create a explicit folder structure:

like this in your laravel project.

public/fonts/vendor/font-awesome

Move all your fonts from font-awesome package to above mention directory.

2. Change $fa-font-path variable value:

font-awesome directory has a file called _variables.scss inside that file there is a variable named as $fa-font-path change the value to something like this.

$fa-font-path: "/fonts/vendor/font-awesome" !default;

Compile your assets it would work.

Greasy answered 14/6, 2018 at 16:36 Comment(0)
H
4

In addition to @farid-hatami answer, you can also append to the generated URL with.

mix.setResourceRoot('/public')

This is useful if you're running backends like Django where you have to be explicit with your url.

Hunchback answered 31/1, 2020 at 12:12 Comment(0)
M
3

Mix options have changed. Use instead:

mix.options({
    fileLoaderDirs:  {
        fonts: 'assets/fonts'
    }
});
Madalena answered 9/2, 2022 at 15:16 Comment(0)
B
0

You can also just change the way Laravel Mix generates the folder structure by overwriting the Webpack rule that manages fonts.

The original rule can be found in the Laravel Mix package, in src/builder/webpack-rules.js, line 50, where the comment says // Add support for loading fonts.

In your Mix file you can overwrite the rule with the webpackConfig method, like this:

mix.webpackConfig({
  module: {
    rules: [{
      test: /(\.(woff2?|ttf|eot|otf)$|font.*\.svg$)/,
      loaders: [{
        loader: 'file-loader',
        options: {
          name: (path) => {
            if (!/node_modules|bower_components/.test(path)) {
              return 'fonts/[name].[ext]?[hash]';
            }
            return (
              'fonts/vendor/' +
              path
              .replace(/\\/g, '/')
              .replace(
                /((.*(node_modules|bower_components))|fonts|font|assets)\//g,
                ''
              ) +
              '?[hash]'
            );
          },
        },
      }],
    }],
  },
})

The rule I have written is almost identical to the one in the Laravel Mix package, so if you need to change it you will have to update one of the two returns: in this case the second one, because the fonts come from an npm module.

So instead of

path
  .replace(/\\/g, '/')
  .replace(
    /((.*(node_modules|bower_components))|fonts|font|assets)\//g,
  ''
)

you can write an hard-coded string or change what you want out of the original path: in this way the folder structure in the original node module (in this case Font Awesome) won't affect the folder structure of your public folder.

Brindabrindell answered 29/9, 2020 at 7:37 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.