How do I load font-awesome using SCSS (SASS) in Webpack using relative paths?
Asked Answered
T

10

92

I have font-awesome in my node_modules folder so I try to import it in my main .scss file like so:

@import "../../node_modules/font-awesome/scss/font-awesome.scss";

But Webpack bundling compilation fails, telling me

Error: Cannot resolve 'file' or 'directory' ../fonts/fontawesome-webfont.eot 

because the font-awesome.scss file refers to a relative path, '../fonts/'.

How can I tell scss \ webpack to @import another file, and use that file's folder as the home folder so that its relative paths work as it expects?

Thomasina answered 11/11, 2015 at 11:39 Comment(5)
I don't knows webpack, but do you can put the .eot in ../../node_modules/font-awesome/fonts/fontawesome-webfont.eot?Austrasia
I could do that by altering the font-awesome file, but then I'd lose the changes whenever I update npm, so that's not an option.Thomasina
webpack works together express @Richard?Austrasia
No, not using expressThomasina
I am using the npm for font-awesome sass loader. did you use a different one?Bikini
T
33

There doesn't appear to be any way to @import files that have their own relative paths in SCSS \ SASS.

So instead I managed to get this to work:

  • Import the scss \ css font-awesome file in my .js or .jsx files, not my stylesheet files:

    import 'font-awesome/scss/font-awesome.scss';    
  • Add this to my webpack.config file:

    module:
    {
        loaders:
        [
            {test: /\.js?$/, loader: 'babel-loader?cacheDirectory', exclude: /(node_modules|bower_components)/ },
            {test: /\.jsx?$/, loader: 'babel-loader?cacheDirectory', exclude: /(node_modules|bower_components)/ },
            {test: /\.scss?$/, loaders: ['style-loader', 'css-loader', 'sass-loader']},         
            {test: /\.svg(\?v=\d+\.\d+\.\d+)?$/, loader: 'file-loader?mimetype=image/svg+xml'},
            {test: /\.woff(\?v=\d+\.\d+\.\d+)?$/, loader: "file-loader?mimetype=application/font-woff"},
            {test: /\.woff2(\?v=\d+\.\d+\.\d+)?$/, loader: "file-loader?mimetype=application/font-woff"},
            {test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/, loader: "file-loader?mimetype=application/octet-stream"},
            {test: /\.eot(\?v=\d+\.\d+\.\d+)?$/, loader: "file-loader"},
        ]
    }
Thomasina answered 11/11, 2015 at 12:15 Comment(6)
How do you handle a different font path? I mean you import the scss there but you cannot change the path to your font-files, e.g. if you need to change it for production and the fonts are found in a different folder. Any ideas? Thats what I need to do.Dregs
I haven't got to altering stuff for production yet. I imagine I'd just copy everything over from my local build and leave the paths alone. Otherwise maybe look at the output section of webpack.config.js and see if you can change paths. Or just add a post build step in your package.json scripts section.Thomasina
Got it working. I changed the path for the loader and now its loading the fonts from the specified path.Dregs
You don't need to include the font-awesome scss file in the javascript. You can still include it in your scss, as long as you set the font path like user137794 suggests, then update the webpack.config file to account for font types as you suggest.Storied
Which npm did you use? I am using the sass font awesome loader and having no success.Bikini
don't forget to add *-loader suffix (the loaders for .scss files). Leaving it without -loader suffix is not longer allowed. Check webpack.js.org/migrate/3/…Critchfield
B
143

Use

$fa-font-path: "~font-awesome/fonts";
@import "~font-awesome/scss/font-awesome";

where the $fa-font-path variable is seen in font-awesome/scss/_variables.scss

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

The tilde "~" is interpolated by sass-loader using the webpack mecanism.

Bluefield answered 19/12, 2015 at 3:25 Comment(9)
Doesn't work for me, it compile but I just get rectangle in my website... :/Clementinaclementine
I had to set mine as $fa-font-path: "font-awesome/fonts" - i.e. without the tilde.Duhon
Could you explain a bit more precisely where you edit what? I don't understand this answerThomasina
@Thomasina were you able to get this working for you? Also, please mark this as the answer!Kazue
No, I used my answer below at the time.Thomasina
The ~ was the secret sauce as my modules were in node_modules and the sass-loader was configured for them via include paths i.e., JSON options: { sassOptions: { includePaths: [ "node_modules" ] } Dell
@RobbVandaveer Could you please precisely where do I need to add this? Do I need to add this to webpack.config.js in root? Any reference link?W
Hi @Sadee, I'm sorry for the late response, I guess I haven't been on SO in a while. The tilde prefixes the paths used as references in your SCSS.Dell
This worked, but for parcel I had to use $fa-font-path: '../node_modules/font-awesome/fonts';Comnenus
T
33

There doesn't appear to be any way to @import files that have their own relative paths in SCSS \ SASS.

So instead I managed to get this to work:

  • Import the scss \ css font-awesome file in my .js or .jsx files, not my stylesheet files:

    import 'font-awesome/scss/font-awesome.scss';    
  • Add this to my webpack.config file:

    module:
    {
        loaders:
        [
            {test: /\.js?$/, loader: 'babel-loader?cacheDirectory', exclude: /(node_modules|bower_components)/ },
            {test: /\.jsx?$/, loader: 'babel-loader?cacheDirectory', exclude: /(node_modules|bower_components)/ },
            {test: /\.scss?$/, loaders: ['style-loader', 'css-loader', 'sass-loader']},         
            {test: /\.svg(\?v=\d+\.\d+\.\d+)?$/, loader: 'file-loader?mimetype=image/svg+xml'},
            {test: /\.woff(\?v=\d+\.\d+\.\d+)?$/, loader: "file-loader?mimetype=application/font-woff"},
            {test: /\.woff2(\?v=\d+\.\d+\.\d+)?$/, loader: "file-loader?mimetype=application/font-woff"},
            {test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/, loader: "file-loader?mimetype=application/octet-stream"},
            {test: /\.eot(\?v=\d+\.\d+\.\d+)?$/, loader: "file-loader"},
        ]
    }
Thomasina answered 11/11, 2015 at 12:15 Comment(6)
How do you handle a different font path? I mean you import the scss there but you cannot change the path to your font-files, e.g. if you need to change it for production and the fonts are found in a different folder. Any ideas? Thats what I need to do.Dregs
I haven't got to altering stuff for production yet. I imagine I'd just copy everything over from my local build and leave the paths alone. Otherwise maybe look at the output section of webpack.config.js and see if you can change paths. Or just add a post build step in your package.json scripts section.Thomasina
Got it working. I changed the path for the loader and now its loading the fonts from the specified path.Dregs
You don't need to include the font-awesome scss file in the javascript. You can still include it in your scss, as long as you set the font path like user137794 suggests, then update the webpack.config file to account for font types as you suggest.Storied
Which npm did you use? I am using the sass font awesome loader and having no success.Bikini
don't forget to add *-loader suffix (the loaders for .scss files). Leaving it without -loader suffix is not longer allowed. Check webpack.js.org/migrate/3/…Critchfield
S
22

Following worked for me:

$fa-font-path: "~font-awesome/fonts";
@import "~font-awesome/scss/font-awesome";

This is to import the font-awesome & required fonts in the project. Other change is in webpack configurations, to load required fonts using file-loader.

{
  test: /\.scss$/,
  loaders: ['style', 'css?sourceMap', 'sass'
  ],
}, {
  test: /\.(png|jpg|jpeg|gif|svg|woff|woff2|ttf|eot)(\?.*$|$)/,
  loader: 'file'
}
Supertax answered 5/12, 2016 at 14:34 Comment(0)
P
22

This is how it worked for me, the trick is to set $fa-font-path to the path of the fonts as following.

$fa-font-path: "~@fortawesome/fontawesome-free/webfonts/";
@import '~@fortawesome/fontawesome-free/scss/fontawesome.scss';
@import '~@fortawesome/fontawesome-free/scss/solid.scss';
@import '~@fortawesome/fontawesome-free/scss/brands.scss';

Note: Please check your fonts folder in node_modules in my case it is @fortawesome/fontawesome-free

Philander answered 16/12, 2019 at 13:51 Comment(2)
@Muhammed Actually, it is a bit tricky to load webfonts like this. When you compile sass to css, according to your way of compiling, your fonts may not be compiled. You can copy the webfonts folder directly to your public/ folder next to your css folder. In this way, font awesome css code will find the fonts and you will be on the safe side.Kittykitwe
This is what I thought I was doing. but what it turned out I was missing was the trailing directory separator at the end. (I had $fa...: "~@fort..../webfonts"; when apparently it is fully required to have a trailing forward slash: $fa...: "~@fort..../webfonts/";) couldn't figure out why my otherwise working conifg was missing fonts from font awesome until I saw your answer here @PhilanderFawkes
B
13

Resolved by changing my app.scss:

@import '~font-awesome/scss/_variables.scss';
$fa-font-path: "~font-awesome/fonts";
@import '~font-awesome/scss/font-awesome.scss';

This way is useful to keep external dependencies unchanged and unversioned.

Birdcage answered 27/3, 2017 at 10:4 Comment(2)
You could avoid line 1 and use ` !default` on line 2 end.Masonry
It's a shame that I can't get this method to work because it would mean that I didn't have to change the _variables.scss file every time I recompiled the project. It doesn't override $fa-font-path or any other variable for that matter.. so not sure how you were able to do it_Curkell
T
8

I just set the path in my main scss file and it works :

$fa-font-path: "../node_modules/font-awesome/fonts";
@import '~font-awesome/scss/font-awesome.scss';
Tumefy answered 6/12, 2017 at 6:25 Comment(0)
D
7

What worked for me was to add resolve-url-loader and enable sourceMaps

I already imported font-awesome in my root .scss file:

@import "~font-awesome/scss/font-awesome";
...

This root file is imported in my main.js file defined as Webpack's entrypoint:

import './scss/main.scss';
...

Then my final webpack module rules look like so:

 ...
 {
    test: /\.(sa|sc|c)ss$/,
    use: [
      MiniCssExtractPlugin.loader,
      'css-loader',
      { loader: 'postcss-loader', options: { sourceMap: true }, },
      'resolve-url-loader',
      { loader: 'sass-loader', options: { sourceMap: true }, },
    ],
  }, {
    test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/,
    loader: 'url-loader',
    options: { limit: 1000, name: 'fonts/[name].[ext]', },
  }
  ...

Note:

I used mini-css-extract-plugin, which can be registered like this:

new MiniCssExtractPlugin({
    filename: 'css/main.css',
    chunkFilename: '[id].[hash]',
}),

url-loader requires file-loader to be installed, so if you get an error like: cannot find module file-loader, then just install it:

npm i -D file-loader

Useful Links:

https://github.com/webpack/webpack/issues/2771#issuecomment-277514138 https://github.com/rails/webpacker/issues/384#issuecomment-301318904

Disposition answered 14/7, 2018 at 9:15 Comment(0)
Y
4

For Version 5.14, the following worked for me:

$fa-font-path : '../node_modules/@fortawesome/fontawesome-free/webfonts';

@import "../node_modules/@fortawesome/fontawesome-free/scss/solid";

@import "../node_modules/@fortawesome/fontawesome-free/scss/brands";

@import "../node_modules/@fortawesome/fontawesome-free/scss/fontawesome";
Yt answered 9/9, 2020 at 14:38 Comment(0)
R
1

Even after reading all answers, I did not copy anything but just read and still not working until i realized the scope name is @fortawesome and not @fontawesome.

So it will be

// to configure font path is necessary before importing scss
 $fa-font-path: '~@fortawesome/fontawesome-free/webfonts/';

 @import "~@fortawesome/fontawesome-free/scss/fontawesome";

//and so on .. for other scss
Representational answered 15/12, 2023 at 6:26 Comment(0)
R
0

v.4 (symofony 4 + webpack)

$fa-font-path: "~components-font-awesome/webfonts";
@import '~components-font-awesome/scss/fa-brands';
@import '~components-font-awesome/scss/fa-regular';
@import '~components-font-awesome/scss/fa-solid';
@import '~components-font-awesome/scss/fontawesome';
Racklin answered 17/4, 2018 at 9:29 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.