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

node.jsSassNpmFont AwesomeWebpack

node.js Problem Overview


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?

node.js Solutions


Solution 1 - node.js

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.

Solution 2 - node.js

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"},
]
}

Solution 3 - node.js

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'
}

Solution 4 - node.js

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

Solution 5 - node.js

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.

Solution 6 - node.js

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';

Solution 7 - node.js

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

Solution 8 - node.js

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";

Solution 9 - node.js

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';

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionRichardView Question on Stackoverflow
Solution 1 - node.jsuser137794View Answer on Stackoverflow
Solution 2 - node.jsRichardView Answer on Stackoverflow
Solution 3 - node.jsYogesh AgrawalView Answer on Stackoverflow
Solution 4 - node.jsMuhammadView Answer on Stackoverflow
Solution 5 - node.jsWilkView Answer on Stackoverflow
Solution 6 - node.jsramon22View Answer on Stackoverflow
Solution 7 - node.jsExcellence IlesanmiView Answer on Stackoverflow
Solution 8 - node.jssdvlprView Answer on Stackoverflow
Solution 9 - node.jsKoudiView Answer on Stackoverflow