laravel-mix: BrowserSync: Sass compilation causing whole page reload

  • Laravel Mix Version: 1.4.2 (github:jeffreyway/laravel-mix#5aad0dfde5349e284e0876388a6f307547f7c002)
  • Node Version (node -v): 8.2.1
  • NPM Version (npm -v): 5.3.0
  • OS: macOS Sierra 10.12.6

Description:

When using browserSync, css changes are injected however the page is also reloaded due to the fact that the JS bundle is re-emitted even when the only file that changed was a sass file.

Steps To Reproduce:

webpack.mix.js:

mix
	.js('resources/assets/js/main.js', 'public/assets/js/bundle.js')
	.extract(['jquery', 'babel-polyfill'])
	.autoload({
		jquery: ['$', 'jQuery', 'window.jQuery']
	})
	.sass('resources/assets/sass/style.scss', 'public/assets/css')
	.disableNotifications()
	.options({
			processCssUrls: false
	})
	.sourceMaps()
	.browserSync({
		proxy: process.env.APP_URL,
        files: [
            'app/**/*.php',
            'resources/views/**/*.php',
            'public/assets/js/**/*.js',
            'public/assets/css/**/*.css'
        ]
    })

Run npm run watch, site is served at localhost:3000, save a sass file and watch the browser refresh rather than just inject the changes.

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Reactions: 18
  • Comments: 56 (7 by maintainers)

Commits related to this issue

Most upvoted comments

I finally found a workaround for my case.

I believe the issue is that laravel-mix’s CustomTasksPlugin runs all post-build tasks again for every rebuild. In these tasks is where all files built using .babel(), .scripts(), .combine(), .styles() and even .copy() are built again.

Here is a drop in plugin that ensures these tasks only run at the first build. Subsequent watch builds won’t rebuild all those files again unless you actually modified one of their files. This fixed all my browserSync reload problems.

mix.webpackConfig({
  plugins: [{
    apply(compiler) {
      // Intercept done hook to modify CustomTasksPlugin tap function
      compiler.hooks.done.intercept({
        register: (tapInfo) => {
          let firstRun = true;
          if (tapInfo.name === "CustomTasksPlugin") {
            const fn = tapInfo.fn;
            tapInfo.fn = (stats, callback, ...args) => {
              // Only run tap function (tasks) for first build
              if (firstRun) {
                fn(stats, callback, ...args);
                firstRun = false;
              } else {
                callback();
              }
            };
          }
          return tapInfo;
        }
      })
    }
  }],
});

@karneaud the only workaround is to use mix.standaloneSass or just move styles build process out of Webpack

Could it be that the reload is intended, because Mix checks for .vue component files, which could contain CSS styles that it tries to extract?

If I use

.standaloneSass('assets/sass/styles.scss', 'build/css'),

instead of .sass(), then it works fine for me. I guess if you don’t use CSS styles in your Vue components or if you don’t use Vue at all, then this might be the easiest solution. And it should be faster as well.

Anyone still having this issue?

I’m using Laravel Mix 4.0.7 & BrowserSync 2.26.3.

When I leave in the mix.scripts() it’s refreshing the browser on every save even scss

I found out, that what causes the reload for me is mix.copy(), which I use to copy a JS file from node_modules to public. If I don’t use it, the CSS injection works as intended and without a reload. I know, that BrowserSync reloads upon changed JS. Could it be, that mix.copy() is triggered upon every save?

Same issue on version 2.0.0. 😭

Changing a .styl file triggers rebuilding JS files, then causes page reloading.

The only problem with this is that you do not get the benefits of actual webpack processing of your sass files. For example: referencing node_modules files with ~module/file and postcss support.

Using 1.4.2 as well. Just found out, the JS doesn’t get recompiled after CSS changes when you don’t use .extract().

Until this behaviour changes I now just use a different mode for development and production like this:

const mixJs = mix.inProduction() ? mix.scripts : mix.js
mixJs('src/index.js', 'dist')

Anyone still having this issue?

I’m using Laravel Mix 4.0.7 & BrowserSync 2.26.3.

When I leave in the mix.scripts() it’s refreshing the browser on every save even scss

Same thing on mix.babel()

Anyone still having this issue?

I’m using Laravel Mix 4.0.7 & BrowserSync 2.26.3.

When I leave in the mix.scripts() it’s refreshing the browser on every save even scss

Using Laravel Mix 4.0.14 and I’m still experiencing this problem, when using min.scripts(). Without min.scripts() CSS injection is used instead of an entire page reload. To me this is a noticeable slow down in some of my larger projects, but unfortunately I couldn’t find a solution yet.

@karneaud macOS, whichever version is the most recent and, yes, we’re using VueJS.

I just moved from injecting CSS using Browsersync to Chrome Dev Tools. I just added folder with assets into Sources › Filesystem › + Add folder to workspace. Now, Browsersync reload whole page on JS or template updates and injects CSS when file is updated.

Is there some possible workaround? Development is really troublesome

I spent two days and couldn’t get browserSync or “npm hot” to work as expected. I get a page reload instead of reload one file. I used different versions 1.1.1 -> 2.1.11.

test.blade.php

test blade

<script id="__bs_script__">//<![CDATA[
  document.write("<script async src='http://HOST:3000/browser-sync/browser-sync-client.js?v=2.18.12'><\/script>".replace("HOST", location.hostname));
  //]]>
</script>

<script src="{{ mix('/js/test.js') }}"></script>

test.js

console.log(123);

webpack.erp.mix.js

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

var assetsDir = 'app/Modules/Erp/Resources/Assets/';
mix.js(assetsDir + 'js/test.js', 'js')
  .setPublicPath('public/erp')

mix.browserSync({
  proxy: 'erp.test',
  open: false,
  files: [
    'public/erp/js/test.js',
  ],
  reload: false
});

Result in terminal

 DONE  Compiled successfully in 83ms  

/js/test.js  2.61 kB       0  [emitted]  /js/test
[Browsersync] Reloading Browsers...

and reload page in browser

Same issue here on version 2.1.11. Would be great if this can be fixed soon.

Same issue. 1.4.5

I am also getting this problem where i make 1 change in a scss file and the page gets reloaded.

If i set browsersync to watch just the public/css/flytedesk.css file, then it works, but as soon as I start watching public/js/*.js it will reload the page every time.

I am using laravel-mix 1.4.2

Here is the output from browsersync while watching the public/js/*.js directory:

WAIT  Compiling...                                                                                                               6:06:03 PM

 95% emitting[Browsersync] Reloading Browsers...                                   
[Browsersync] File event [change] : public/css/flytedesk.css


 DONE  Compiled successfully in 1658ms                                                                                            6:06:05 PM

[Browsersync] Reloading Browsers...
[Browsersync] Reloading Browsers...
[Browsersync] Reloading Browsers...
[Browsersync] Reloading Browsers...
[Browsersync] Reloading Browsers...
[Browsersync] Reloading Browsers...
[Browsersync] Reloading Browsers...
[Browsersync] Reloading Browsers...

Yea, I am going to nuke my install and retry with the tagged version until I hit the one that doesn’t work, will report back with my findings 😃