3
votes

I am trying to update my webpack build to take advantage fo postcss and postcss-loader. However I am having problems loading fonts, images, etc.

For example trying to get font awesome imported.

This is my setup before postcss which works:

css:

@import "~font-awesome/css/font-awesome.min.css";

webpack.config:

  ...
  module: {
    rules: [{
      test: /\.css$/,
      use: ExtractTextPlugin.extract({
        fallback: 'style-loader',
        use: 'css-loader'
      })
    },{
      test: /\.(eot|svg|ttf|woff|woff2)$/,
      loader: 'file-loader?name=fonts/[name].[ext]'
    },{
      test: /\.(png|jpg)$/,
      loader: 'file-loader?name=images/[name].[ext]'
    },{
      test: /\.html$/, loader: 'raw-loader'
    }]
  }
  ...

Trying to move to this:

@import 'font-awesome'

webpack w/ postcss:

  ...
  module: {
    rules: [{
      test: /\.css$/,
      use: ExtractTextPlugin.extract({
        fallback: 'style-loader',
        use: [{
          loader: 'css-loader',
          options: {
            importLoaders: 1
          }
        },{
          loader: 'postcss-loader',
          options: {
            ident: 'postcss',
            sourceMap: true,
            plugins: [require('postcss-import')()]
          }
        }]
      })
    },{
      test: /\.(eot|svg|ttf|woff|woff2)$/,
      loader: 'file-loader?name=fonts/[name].[ext]'
    },{
      test: /\.(png|jpg)$/,
      loader: 'file-loader?name=images/[name].[ext]'
    },{
      test: /\.html$/, loader: 'raw-loader'
    }]
  }
  ...

However when I do I get errors like this:

ERROR in ./style.css Module build failed: ModuleNotFoundError: Module not found: Error: Can't resolve '../fonts/fontawesome-webfont.eot' in '/test-project/public'

I have tried a few other libraries as well (ie bootstrap, leaflet) and am running into the same problem with those.

2

2 Answers

0
votes

It appears that the css-loader is having trouble resolving the relative url path to the font-awesome/fonts directory.

You need an alias in your css-loader options like so.

use: [{
  loader: 'css-loader',
  options: {
    importLoaders: 1,
    alias: {
      "../fonts": "font-awesome/fonts"
    }
  }
}

I tested this in an example project and it appeared to compile successfully.

$ ./node_modules/.bin/webpack
Hash: 05687ac67950e58e8485
Version: webpack 3.10.0
Time: 996ms
                          Asset     Size  Chunks                    Chunk Names
  fonts/fontawesome-webfont.eot   166 kB          [emitted]
fonts/fontawesome-webfont.woff2  77.2 kB          [emitted]
 fonts/fontawesome-webfont.woff    98 kB          [emitted]
  fonts/fontawesome-webfont.ttf   166 kB          [emitted]
  fonts/fontawesome-webfont.svg   444 kB          [emitted]  [big]
                 ./dist/main.js  2.63 kB       0  [emitted]         main
                     styles.css  38.1 kB       0  [emitted]         main
   [0] ./main.js 43 bytes {0} [built]
   [1] ./main.css 41 bytes {0} [built]
   [2] ../node_modules/css-loader?{"importLoaders":1,"alias":{"../fonts":"font-awesome/fonts"}}!../node_modules/resolve-url-loader!../node_modules/postcss-loader/lib?{"ident":"postcss"}!./main.css 43.7 kB [built]
    + 10 hidden modules
Child extract-text-webpack-plugin ../../../../Joshua Barnett\Projects\blah\node_modules\extract-text-webpack-plugin\dist ../../../../Joshua Barnett\Projects\blah\node_modules\css-loader\index.js??ref--0-2!../../../../Joshua Barnett\Projects\blah\node_modules\resolve-url-loader\index.js!../../../../Joshua Barnett\Projects\blah\node_modules\postcss-loader\lib\index.js??postcss!../../../../Joshua Barnett\Projects\blah\js\main.css:
     5 assets
       [0] ../node_modules/css-loader?{"importLoaders":1,"alias":{"../fonts":"font-awesome/fonts"}}!../node_modules/resolve-url-loader!../node_modules/postcss-loader/lib?{"ident":"postcss"}!./main.css 43.7 kB {0} [built]
        + 8 hidden modules

Also you may need to be more specific with the alias if you are also using projects that use the ../fonts relative path.

0
votes

This webpack config resolved issue for me:

const rules = [{
  test: /\.css$/,
  use: [
    'style-loader',
    {
      loader: 'css-loader',
      options: {
        importLoaders: 1,
        sourceMap: true,
      }
    },
   'resolve-url-loader',
    {
      loader: 'postcss-loader',
      options: {
        sourceMap: true,
        ident: 'postcss',
        plugins: () => [],
      }
    }
  ]
}, {
  test: /\.(png|woff|woff2|eot|ttf|svg)$/,
  loader: 'url-loader?limit=100000',
}]