Webpack - resolve-url-loader does not resolve paths correctly

1.2k Views Asked by At

I have a problem with setting up resolve-url-loader correctly in my webpack config. It does not seem to resolve paths in scss files at all.

Here is my project folder structure:

├───config
│   └───jest
├───public
│   └───assets
│       ├───css
│       ├───fonts
│       ├───images
│       │   ├───background
│       │   ├───icons
│       │   ├───illustration
│       │   ├───logo
│       │   └───projects
│       │       ├───one
│       │       └───two
│       ├───js
│       └───scss
│           ├───blog
│           ├───common
│           ├───default
│           ├───elements
│           ├───header
│           └───template
├───scripts
└───src
    ├───component
    │   ├───common
    │   ├───footer
    │   ├───header
    │   └───slider
    ├───elements
    │   ├───blog
    │   ├───common
    │   ├───portfolio
    │   ├───projects
    │   └───tab
    └───home

Below you will find how webpack.config.js looks like. It's kind of complex but I tried to hide all code chunks that I think are irrelevant for solving this issue. In general the loaders chain in use method is created by getStyleLoaders function defined at the beginning of the file. If preProcessor is identified as sass-loader then additionally the resolve-url-loader is added. The problem is that when looking at resolve-url-loader's debug, it seems that it does not resolve url's from scss files in public folder. The only debug logs that I get are as follows:

Resolve-url-loader debug log:

resolve-url-loader: ./node_modules/slick-carousel/slick/slick-theme.css: ./ajax-loader.gif
  ./node_modules/slick-carousel/slick
  FOUND
resolve-url-loader: ./node_modules/slick-carousel/slick/slick-theme.css: ./fonts/slick.eot
  ./node_modules/slick-carousel/slick
  FOUND
resolve-url-loader: ./node_modules/slick-carousel/slick/slick-theme.css: ./fonts/slick.woff
  ./node_modules/slick-carousel/slick
  FOUND
resolve-url-loader: ./node_modules/slick-carousel/slick/slick-theme.css: ./fonts/slick.ttf
  ./node_modules/slick-carousel/slick
  FOUND
resolve-url-loader: ./node_modules/slick-carousel/slick/slick-theme.css: ./fonts/slick.svg
  ./node_modules/slick-carousel/slick

I have some url links defined in scss files that I don't see in `debug's' log. What am I doing wrong?

webpack.config.js details:

'use strict';

/*some plugins*/
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
const safePostCssParser = require('postcss-safe-parser');
const ManifestPlugin = require('webpack-manifest-plugin');
const InterpolateHtmlPlugin = require('react-dev-utils/InterpolateHtmlPlugin');
/*some plugins*/
const getCSSModuleLocalIdent = require('react-dev-utils/getCSSModuleLocalIdent');
const paths = require('./paths');
const modules = require('./modules');
/*some plugins*/

const postcssNormalize = require('postcss-normalize');

const shouldUseSourceMap = process.env.GENERATE_SOURCEMAP !== 'true';
const shouldInlineRuntimeChunk = process.env.INLINE_RUNTIME_CHUNK !== 'false';

const useTypeScript = fs.existsSync(paths.appTsConfig);

const cssRegex = /\.css$/;
const cssModuleRegex = /\.module\.css$/;
const sassRegex = /\.(scss|sass)$/;
const sassModuleRegex = /\.module\.(scss|sass)$/;

module.exports = function(webpackEnv) {
  const isEnvDevelopment = webpackEnv === 'development';
  const isEnvProduction = webpackEnv === 'production';

  // Webpack uses `publicPath` to determine where the app is being served from.
  // It requires a trailing slash, or the file assets will get an incorrect path.
  // In development, we always serve from the root. This makes config easier.
  const publicPath = isEnvProduction
    ? paths.servedPath
    : isEnvDevelopment && '/';
  const shouldUseRelativeAssetPaths = publicPath === './';

  const publicUrl = isEnvProduction
    ? publicPath.slice(0, -1)
    : isEnvDevelopment && '';
  // Get environment variables to inject into our app.
  const env = getClientEnvironment(publicUrl);

  // common function to get style loaders
  const getStyleLoaders = (cssOptions, preProcessor) => {
    const loaders = [
      isEnvDevelopment && require.resolve('style-loader'),
      isEnvProduction && {
        loader: MiniCssExtractPlugin.loader,
        options: shouldUseRelativeAssetPaths ? { publicPath: '../../' } : {},
      },
      {
        loader: require.resolve('css-loader'),
        options: cssOptions,
      },
      {
        loader: require.resolve('postcss-loader'),
        options: {
          ident: 'postcss',
          plugins: () => [
            require('postcss-flexbugs-fixes'),
            require('postcss-preset-env')({
              autoprefixer: {
                flexbox: 'no-2009',
              },
              stage: 3,
            }),
            postcssNormalize(),
          ],
          sourceMap: isEnvProduction && shouldUseSourceMap,
        },
      },
    ].filter(Boolean);
    if (preProcessor) {
        if (preProcessor === "sass-loader") {
            loaders.push({
                loader: require.resolve('resolve-url-loader'),
                options: cssOptions,
            })
        }

      loaders.push({
        loader: require.resolve(preProcessor),
        options: {
          sourceMap: isEnvProduction && shouldUseSourceMap,
        },
      });
    }
    return loaders;
  };

  return {
    mode: isEnvProduction ? 'production' : isEnvDevelopment && 'development',
    bail: isEnvProduction,
    devtool: isEnvProduction
      ? shouldUseSourceMap
        ? 'source-map'
        : false
      : isEnvDevelopment && 'cheap-module-source-map',
    entry: [/*...*/].filter(Boolean),
    output: {/*...*/},
    optimization: {/*...*/},
    resolve: {/*...*/},
    resolveLoader: {/*...*/},
    module: {
    strictExportPresence: true,
    rules: [
        { parser: { requireEnsure: false } },

        {
          /*es-lint loader*/
        },
        {
          oneOf: [
            {
              test: [/\.bmp$/, /\.gif$/, /\.jpe?g$/, /\.png$/],
              loader: require.resolve('url-loader'),
              options: {
                limit: 10000,
                name: 'static/media/[name].[hash:8].[ext]',
              },
            },
            {/*babel-loader*/},
        },
        {/*babel-loader*/},
        {
              test: cssRegex,
              exclude: cssModuleRegex,
              use: getStyleLoaders({
                importLoaders: 1,
                sourceMap: isEnvProduction && shouldUseSourceMap,
              }),
              sideEffects: true,
        },
        {
              test: cssModuleRegex,
              use: getStyleLoaders({
                importLoaders: 1,
                sourceMap: isEnvProduction && shouldUseSourceMap,
                modules: true,
                getLocalIdent: getCSSModuleLocalIdent,
              }),
        },
        {
              test: sassRegex,
              exclude: sassModuleRegex,
              use: getStyleLoaders(
                {
                  importLoaders: 2,
                  sourceMap: isEnvProduction && shouldUseSourceMap,
                },
                'sass-loader'
              ),
              sideEffects: true,
        },
        {
              test: sassModuleRegex,
              use: getStyleLoaders(
                {
                  importLoaders: 2,
                  sourceMap: isEnvProduction && shouldUseSourceMap,
                  modules: true,
                  getLocalIdent: getCSSModuleLocalIdent,
                },
                'sass-loader'
              ),
        },
        {
              loader: require.resolve('file-loader'),
              exclude: [/\.(js|mjs|jsx|ts|tsx)$/, /\.html$/, /\.json$/],
              options: {
                name: 'static/media/[name].[hash:8].[ext]',
              },
        },
      ],
    },
    plugins: [/*...*/].filter(Boolean),
    node: {/*...*/},
    performance: false,
  };
};

1

There are 1 best solutions below

1
On

Resolved. It turned out that I had to define url's differently in scss files.