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,
};
};
Resolved. It turned out that I had to define
url
's differently in scss files.