sasslaravel-mixnode-sassresolve-url-loader

Correct way to include image via relative path


I've updated laravel-mix to version 4.0.12 and faced with broken build on the line in *.scss where I used a relative path to include background image

I got a next files structure

resources/
|-assets/
||-img/
|||-background.png
||-sass/
|||-footer.scss

my code in footer.scss is next

.footer {
  background-image: url(../img/background.png)
}

My webpack.mix.js is next

const mix = require('laravel-mix');

const resourcesAssets = 'resources/assets/';
const dest = 'public/assets/';

mix
  .copy(`${resourcesAssets}images`, `${dest}images`, false)
  .sass(`${resourcesAssets}scss/footer.scss`, `${dest}css`);

During compling npm run prod I got

Module build failed (from ./node_modules/css-loader/index.js):
ModuleBuildError: Module build failed (from ./node_modules/resolve-url-loader/index.js):
Error: resolve-url-loader: CSS error
predicate must return an absolute path or the result of calling next()
at file://C:\xampp\htdocs\laravel-project\resources\assets\sass\footer.scss:2:3
at encodeError (C:\xampp\htdocs\laravel-project\node_modules\resolve-url-loader\index.js:218:12)
at onFailure (C:\xampp\htdocs\laravel-project\node_modules\resolve-url-loader\index.js:175:14)
at <anonymous>
    at runMicrotasksCallback (internal/process/next_tick.js:122:5)
    at _combinedTickCallback (internal/process/next_tick.js:132:7)
    at process._tickCallback (internal/process/next_tick.js:181:9)
    at runLoaders (C:\xampp\htdocs\laravel-project\node_modules\webpack\lib\NormalModule.js:301:20)
    at C:\xampp\htdocs\laravel-project\node_modules\loader-runner\lib\LoaderRunner.js:364:11
    at C:\xampp\htdocs\laravel-project\node_modules\loader-runner\lib\LoaderRunner.js:230:18
    at context.callback (C:\xampp\htdocs\laravel-project\node_modules\loader-runner\lib\LoaderRunner.js:111:13)
    at onFailure (C:\xampp\htdocs\laravel-project\node_modules\resolve-url-loader\index.js:175:5)
    at <anonymous>
        at runMicrotasksCallback (internal/process/next_tick.js:122:5)
        at _combinedTickCallback (internal/process/next_tick.js:132:7)
        at process._tickCallback (internal/process/next_tick.js:181:9)

        error  in ./resources/assets/sass/footer.scss

How can I fix this problem?


Solution

  • It's an URL rewriting thing in Webpack as Laravel Mix is built on top of Webpack. For CSS compilation, Webpack rewrites and optimizes any url() calls within your stylesheets.

    However, according to the Laravel Docs:

    Absolute paths for any given url() will be excluded from URL-rewriting. For example, url('/images/thing.png') or url('http://example.com/images/thing.png') won't be modified.

    So, Mix tries to rewrite your CSS to sth. like:

    .footer {
        background-image: url(/img/background.png?<some-hash-identifier>)
    }
    

    In that case, you can disable url() like so and Mix will not touch url(../img/background.png) in your footer.scss:

    mix.sass(`${resourcesAssets}scss/footer.scss`, `${dest}css`);
        .options({
            processCssUrls: false
        });