Laravel-mix: Community Feedback Requested

Created on 21 Feb 2017  路  24Comments  路  Source: JeffreyWay/laravel-mix

Hi, everyone. One of the biggest points of confusion with Laravel Mix stems from the fact that it will automatically rewrite your CSS urls(). Now, this is simply a Webpack feature, and has nothing to do with Mix, specifically; however, I understand that it can be confusing to newcomers.

An Example

Imagine that we want to compile a bit of Sass.

.example {
    background: url('../images/thing.png');
}

Notice that relative URL (absolute URLs are always ignored, of course)? Well, by default, Laravel Mix and Webpack will find thing.png, copy it to your public/images folder, and then rewrite the url(). As such, your compiled CSS will be:

.example {
  background: url(/images/thing.png?d41d8cd98f00b204e9800998ecf8427e);
}

This, again, is a very cool feature of Webpack's. However, it does have a tendency to confuse folks who don't understand how Webpack and the css-loader plugin works. It's possible that your folder structure is already just how you want it, and you'd prefer that Mix not modify those url()s. If that's the case, we do offer an override:

mix.options({
    processCssUrls: false
});

With this addition to your webpack.mix.js file, we will no longer match url()s or copy assets to your public directory. As such, the compiled CSS will remain exactly as you typed it:

.example {
  background: url("../images/thing.png");
}

My Question

Should we disable CSS url() processing by default, for the next point release? Or, in other words, should CSS rewriting be opt-in, rather than opt-out?

I ask, because this is easily the most common point of confusion for folks switching from Laravel Elixir to Laravel Mix and Webpack.

help wanted

Most helpful comment

For me, opt-out. And the config line should be in mix config file, but commented.

All 24 comments

Opt-in.

For me, opt-out. And the config line should be in mix config file, but commented.

Only speaking for me of course, but my expectation was as it currently works by default. That's how I've always stored my assets. It seems that structure has been the convention for several years not only in Laravel but other frameworks.
Opt-out

At first, I was thinking opt-out esp. because it's already opt-out so that would not break anything. But that will defeat the purpose of not confusing newcomers. So, I'd say opt-in.

I think it should be on by default. Letting Webpack manage your assets and write URLs is one of the perks of using Webpack. This seems like a pain point of having such a sophisticated, high-level abstraction over top of Webpack without everyone who uses it having a pretty decent understanding of how Webpack does things. It seems like something that could be solved by very thoroughly documenting that this is how Mix works because its how Webpack works.

Think about it. Laravel Mix basically has 1 page of docs on the Laravel site, but a comparable Webpack abstraction, create-react-app, has like, 20 pages of docs to make sure people understand exactly what it's doing. Sure, most people don't read it, but it's there if they need/want to. Something like that is probably what a project like this needs.

The reason I like Mix is because it simplifies Webpack, so my vote is: don't rewrite URLs by default, make rewriting opt-in.

It is cool & should be on by default! & @kduma suggestion is fine too.

I'd say disabled by default. Like you said, directory structures may be different.

Dunno, I always use full path in url(), I just set public as resource root in phpstorm and it autocompletes all paths to images that I keep there. Having a separate copy in resources folder and coping them to public on each build seems redundant. Though if I ever decide to rely on this feature, it would be better to discover it through the documentation, rather than having a massive WTF-moment when in messes things up

TL:DR Opt-in.

Hi Jeff,

I was a Laravel Elixir user and start migrating my projects to Laravel Mix since 0.5.0.
So I expected most of the things to work exactly the same as before.
Back to Mix v. 0.5 there was no option to disable processCssUrl by default.
I with little knowledge of how Webpack work was very frustrated at the time (maybe even now still).
I had to spend hours hacking around with webpack.config.js to make the css url to actually work.

So yeah, I would choose to leave the processCssUrl off by default
And as other people says the Laravel Mix's documentation on Laravel site is very limited (why?). Maybe explain more on the site so that people who understand Webpack can choose to do whatever the see appropriate.

opt-out like @kduma said, this is the best of both worlds

Opt-Out, I'd say.

My vote for opt-out as @kduma suggests

opt-out

opt out. use webpack default, and then prominent note in laravel docs. theres bound to be threads on laracasts aswell

Opt-out and if possible add more information when it pops an error

I'd go with opt out, too. Opt in will lead to more confusion imho

I think should be opt-in. I actually tried to use and get back on elixir because SAAS processing was veeery slow (I used relative url to some fonts).

Will move to mix in the next release now.

@JeffreyWay added what you said, but get an error when compiling.

mix.options({
    ^

TypeError: mix.options is not a function

Mix 0.6.3
my webpack.mix.js:

mix.options({
    processCssUrls: false
})
    .js('resources/assets/js/pages/main.js', 'public/js/main.js')
    .js('resources/assets/js/pages/account.js', 'public/js')
    .js('resources/assets/js/pages/test-upload.js', 'public/js')
    .js('resources/assets/js/pages/help.js', 'public/js')
    .sass('resources/assets/sass/app.scss', 'public/css')
    .sourceMaps()
    .version();

I expect url() rewriting to work by default. There should be no argument about this because every popular webpack boilerplate in the wild (including CRA) works with this assumption.

Now, it's going off-topic, but if you want to clean up some defaults, I suggest you look at ProvidePlugin first, specifically these lines:

    new webpack.ProvidePlugin(Mix.autoload || {
        jQuery: 'jquery',
        $: 'jquery',
        jquery: 'jquery'
    }),

What if, for example, your average Laravel developer would decide to use Bootstrap 4 and jquery-slim? With the current default they'll have both versions of jQuery implicitly included in the build and have no idea what is happening behind the scenes. And this option isn't even needed for default Laravel installation because jquery is attached to window object. It's just adds to confusion.

Vote: Opt-out + docs + comments.

Since laravel-mix is a new direction with use of webpack as the core technology vs laravel-elixir and gulp, webpack defaults should be adhered to. This will help reduce confusion in the long run especially if people end up reading webpack documentation.

Newbies should read the documentation.

Thanks so much for the feedback, everyone! This is a tough one, only because newcomers are immediately confused. But I do agree that better education and documentation is perhaps the solution, instead of making it opt-in...especially when it's such a core Webpack feature.

So I will plan on keeping things as they are, while providing better explanations in the docs.

@elasticsteve - Update Laravel Mix. mix.options() was added after your version.

@adiachenko - I agree. I have a note to remove that for the next release.

@JeffreyWay after my version? I just ran npm update and it updated to this one. How can there be another version?

I think I have to update package json... just saw that L 5.4 now comes with 0.8.1...

Was this page helpful?
0 / 5 - 0 ratings

Related issues

terion-name picture terion-name  路  3Comments

jpriceonline picture jpriceonline  路  3Comments

kpilard picture kpilard  路  3Comments

rlewkowicz picture rlewkowicz  路  3Comments

mementoneli picture mementoneli  路  3Comments