Laravel-mix: [6.x.x] Mix wont compile if child scss use assets relative to root // SourceMaps are False by default

Created on 20 Dec 2020  路  15Comments  路  Source: JeffreyWay/laravel-mix

  • Laravel Mix Version: 6.0.0
  • Node Version: v14.15.3
  • NPM Version: 6.14.9
  • OS: Windows 10

Description:

i've upgraded a project from Mix 4 to 6, i had some url with this format

src: url('../../assets/fonts/font.woff2') format('woff2'),

which were resolved and moved correctly.
but after the update, i had to change it to

src: url('../assets/fonts/font.woff2') format('woff2'),

otherwise mix wont compile. The very same happen with vendor dependency, for example i used to import
@import "~rpg-awesome/scss/rpg-awesome"; without issues, but now i get this error:

ERROR in ./resources/sass/app.scss Module build failed (from ./node_modules/mini-css-extract-plugin/dist/loader.js): ModuleBuildError: Module build failed (from ./node_modules/css-loader/dist/cjs.js): Error: Can't resolve '../fonts/rpgawesome-webfont.eot?v=0.1.0' in 'G:\laragon\www\tdl_laravel\resources\sass' at finishWithoutResolve (G:\laragon\www\tdl_laravel\node_modules\enhanced-resolve\lib\Resolver.js:293:18) at G:\laragon\www\tdl_laravel\node_modules\enhanced-resolve\lib\Resolver.js:362:15 at G:\laragon\www\tdl_laravel\node_modules\enhanced-resolve\lib\Resolver.js:410:5 at eval (eval at create (G:\laragon\www\tdl_laravel\node_modules\tapable\lib\HookCodeFactory.js:33:10), <anonymous>:16:1) at G:\laragon\www\tdl_laravel\node_modules\enhanced-resolve\lib\Resolver.js:410:5 at eval (eval at create (G:\laragon\www\tdl_laravel\node_modules\tapable\lib\HookCodeFactory.js:33:10), <anonymous>:27:1) at G:\laragon\www\tdl_laravel\node_modules\enhanced-resolve\lib\DescriptionFilePlugin.js:87:43 at G:\laragon\www\tdl_laravel\node_modules\enhanced-resolve\lib\Resolver.js:410:5 at eval (eval at create (G:\laragon\www\tdl_laravel\node_modules\tapable\lib\HookCodeFactory.js:33:10), <anonymous>:16:1) at G:\laragon\www\tdl_laravel\node_modules\enhanced-resolve\lib\forEachBail.js:16:12 at G:\laragon\www\tdl_laravel\node_modules\enhanced-resolve\lib\AliasPlugin.js:103:14 at next (G:\laragon\www\tdl_laravel\node_modules\enhanced-resolve\lib\forEachBail.js:14:3) at forEachBail (G:\laragon\www\tdl_laravel\node_modules\enhanced-resolve\lib\forEachBail.js:24:9) at G:\laragon\www\tdl_laravel\node_modules\enhanced-resolve\lib\AliasPlugin.js:37:5 at _next0 (eval at create (G:\laragon\www\tdl_laravel\node_modules\tapable\lib\HookCodeFactory.js:33:10), <anonymous>:8:1) at eval (eval at create (G:\laragon\www\tdl_laravel\node_modules\tapable\lib\HookCodeFactory.js:33:10), <anonymous>:30:1) at processResult (G:\laragon\www\tdl_laravel\node_modules\webpack\lib\NormalModule.js:583:19) at G:\laragon\www\tdl_laravel\node_modules\webpack\lib\NormalModule.js:676:5 at G:\laragon\www\tdl_laravel\node_modules\loader-runner\lib\LoaderRunner.js:397:11 at G:\laragon\www\tdl_laravel\node_modules\loader-runner\lib\LoaderRunner.js:252:18 at context.callback (G:\laragon\www\tdl_laravel\node_modules\loader-runner\lib\LoaderRunner.js:124:13) at Object.loader (G:\laragon\www\tdl_laravel\node_modules\css-loader\dist\index.js:155:5) at runMicrotasks (<anonymous>) at processTicksAndRejections (internal/process/task_queues.js:93:5)

it is intended? it seems strange to not points the url relative paths where the files resides, it seems the "../../" messes up the url rewriting

Steps To Reproduce:

composer create-project laravel/laravel testbug
change in package.json "laravel-mix": "^6",
npm i

create resources/sass/app.scss and resources/sass/example/test.scss
in test.scss do a simple:

@font-face {
    font-family: 'base-text';
    src: url('../../assets/fonts/base-text.woff') format('woff'),
    url('../../assets/fonts/base-text.woff2') format('woff2');
    font-weight: normal;
    font-style: normal;
}

obviusly, create folder resources/assets/fonts and put you test font in there (it can be whatever you prefer, img, svg, the same problem occur)

compile and you'll get:

ERROR in ./resources/sass/app.scss
Module build failed (from ./node_modules/mini-css-extract-plugin/dist/loader.js):
ModuleBuildError: Module build failed (from ./node_modules/css-loader/dist/cjs.js):
Error: Can't resolve '../../assets/fonts/base-text.woff' in 'G:\xxx\testbug\resources\sass'

Most helpful comment

Working on this today. Should hopefully have a tagged patch out shortly.

All 15 comments

more info:
it seems that mix try to load assets relative from app.scss, despite resolve-url-loader should let child scss files load assets relative to them (it used to work in older verions of mix)

the very same happens with vendor packages, like bootstrap, fontawesome and such.
may be related to
https://github.com/JeffreyWay/laravel-mix/issues/2555

updated with a proper "step to reproduce"

the point is: ISN'T IT the point of having "resolve-url-loader" to be able to resolve urls relative to your web root? @thecrypticace

obviusly putting urls relative to main output (app.scss) will solve it, but it STINKS of workaround and not a proper solution

no one can confirm?

same error happen also with images/svg and such

@JeffreyWay @thecrypticace

Found the bug!
_* bonus: even a temp solution *_

it seems there is a problem in Sass.js or Processor.js (still have to figure out why):

to use the "resolve-url-loader" magic there's the need to have SourceMaps setted to true

i noticied that into Sass.js there is a default setting for the sourcemaps to true:

pluginOptions(pluginOptions) {
        return Object.assign(
            {
                sassOptions: {
                    precision: 8,
                    outputStyle: 'expanded'
                }
            },
            pluginOptions,
            { sourceMap: true } //<- this bad boy i suppose
        );
    }

well, it seems to lose the value along the way

i console.logged the value of the loaders in Processor.js, and that's the result:

[
  {
    loader: 'D:\\laragon\\www\\tanadelladro\\node_modules\\mini-css-extract-plugin\\dist\\loader.js',
    options: { esModule: true }
  },
  {
    loader: 'css-loader',
    options: { url: true, sourceMap: false, importLoaders: 1 }
  },
  {
    loader: 'postcss-loader',
    options: { sourceMap: false, postcssOptions: [Object] }
  },
  {
    loader: 'resolve-url-loader',
    options: { sourceMap: true, debug: true } //dont mind the debug, i've added it to check way it wasn't working
  },
  {
    loader: 'sass-loader',
    options: { sassOptions: [Object], sourceMap: false }
  }                                                                                                              
]      

so the workaround is pretty simple, just forcing all the way down:
mix.sass('resources/sass/app.scss', 'public/css').sourceMaps();

in anycase this would let the magic of resolve-url-loader to work properly.

Can confirm I was having similar issues with url() inside of child SCSS files and adding mix.sourceMaps() fixed it.

Adding .sourceMaps() or .sourceMaps(true) does nothing for me. For every url() which has a path relative to the root the resolve fails. Unfortunately I don't have the time to debug this right now, but currently this makes laravel-mix 6.0 unusable for me.

@stephan-v Actually I missed off the fact that I converted the path relative from the child component first, and then added .souceMaps(). If I leave the url path in the child scss file relative to app.scss then it still fails even with .sourceMaps().

Adding .sourceMaps() or .sourceMaps(true) does nothing for me. For every url() which has a path relative to the root the resolve fails. Unfortunately I don't have the time to debug this right now, but currently this makes laravel-mix 6.0 unusable for me.

truth is that resolve-url-loader to work need sourcemaps:true as per docs:
https://github.com/bholloway/resolve-url-loader/blob/master/packages/resolve-url-loader/README.md

However webpack's css-loader will encounter url(bar.png) and expect to find src/bar.png. This is not the correct location and the build will fail.

Thankfully resolve-url-loader provides the "url rewriting" that Sass is missing. Use it after the transpiler (such as sass-loader). It makes use of the source-map to find the original source file and rewrite url() statements.

you could try to do somethig provisional like i did: putting a console.log(loaders) into node_modules/laravel-mix/src/components/Preprocessor.js and look while building if mix mantains the proper settings, maybe are you overriding something in your mix file?

you could also try to install the Alpha 4.0 version of resolve-url-loader

For me .options({ processCssUrls: true }) fixed it

mix.sourceMaps(true) did it for me, thanks.

Working on this today. Should hopefully have a tagged patch out shortly.

@Ragash Can you update to the latest patch release and let me know if the issue is resolved on your end?

@Ragash Can you update to the latest patch release and let me know if the issue is resolved on your end?

Works for me

@Ragash Can you update to the latest patch release and let me know if the issue is resolved on your end?

yep, can confirm it works now! thanks for your help Jeffrey!

馃帀

Was this page helpful?
0 / 5 - 0 ratings

Related issues

nezaboravi picture nezaboravi  路  3Comments

mementoneli picture mementoneli  路  3Comments

RomainGoncalves picture RomainGoncalves  路  3Comments

Bomavi picture Bomavi  路  3Comments

jpriceonline picture jpriceonline  路  3Comments