'Laravel Mix generate fonts into another directory
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.
Solution 1:[1]
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';
Solution 2:[2]
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');
Solution 3:[3]
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.
Solution 4:[4]
Mix options have changed. Use instead:
mix.options({
fileLoaderDirs: {
fonts: 'assets/fonts'
}
});
Solution 5:[5]
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.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Farid Vatani |
| Solution 2 | Arash Hatami |
| Solution 3 | Temitayo |
| Solution 4 | Moritz |
| Solution 5 | Giorgio Tempesta |
