oquiroz
oquiroz

Reputation: 95

BrowserSync reloading the whole page instead of injecting CSS

I'm developing a WordPress plugin that has a CSS stylesheet. I decided to move from Gulp to Webpack as I intend to start developing with React.js in the future and thought that getting used to Webpack was a good thing to start doing.

So I'm processing, minimizing and extracting my .scss files successfully. Same with my .js files. The problem is that I'm trying to use BrowserSync to reload the page when a .php file changes and to inject my css changes each time Webpack builds the new dist/*.css file but BrowserSync is reloading the whole page each time there's css change. The weird thing is that it's injecting the changes before doing the full reload. I've tried watching the .css files and executing bs.reload({stream: true}) on change but it still does the full reload.

Do anyone has any idea what could be happening? I'm suspecting is a BrowserSync config issue because it's effectively injecting the changes before doing the full reload, but I can't figure out what setting is causing the issue.

Here's the webpack.config.js:

const path              = require('path');
const UglifyJS          = require('uglifyjs-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const extractSass       = new ExtractTextPlugin({
  filename: "../dist/[name].min.css"
});
const BrowserSyncPlugin = require('browser-sync-webpack-plugin');

module.exports = {
  entry: './src/js/main.js',
  output: {
    filename: 'custom.min.js',
    path: path.resolve(__dirname, 'dist')
  },
  plugins: [
    new UglifyJS({sourceMap: true}),
    extractSass,
    new BrowserSyncPlugin({
      host: 'localhost',
      port: '3000',
      proxy: 'http://domain.localdev',
      open: false,
      files: [{
        match: ['**/*.php'],
        fn: function(event, file) {
          if (event === "change") {
            const bs = require('browser-sync').get('bs-webpack-plugin');
            bs.reload();
          }
        }
      },
      {
        match: ['dist/*.css', 'dist/*.js'],
        fn: function(event, file) {
          if (event === "change") {
            const bs = require('browser-sync').get('bs-webpack-plugin');
            bs.stream();
          }
        }
      }],
      injectChanges: true,
      notify: true
    })
  ],
  externals: {
    jquery: "jQuery"
  },
  devtool: "source-map",
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /(node_modules|bower_components)/,
        use: {
          loader: 'babel-loader',
          options: {
            presets: ['babel-preset-env'],
            sourceMap: true
          }
        }
      },
      {
        test: /\.scss$/,
        use: extractSass.extract({
          use: [{
            loader: "css-loader",
            options: {
              minimize: true,
              sourceMap: true
            }
          },
          {
            loader: "sass-loader",
            options: {
              sourceMap: true
            }
          }],
          fallback: "style-loader"
        })
      },
      {
        test: /\.css$/,
        loader: 'style-loader',
      },
      {
        test: /\.css$/,
        loader: 'css-loader',
        options: {
          minimize: true
        }
      }
    ]
  }
}

Upvotes: 1

Views: 4686

Answers (2)

João Barreto
João Barreto

Reputation: 11

I had the same issue, and I discover you should detect which file is changed inside the function and, bs-webpack-plugin didn't inject JavaScript into browser only CSS stylesheet, as in code below.

new BrowserSyncPlugin({
   host: HOST,
   open: false,
   files: [
     {
       match: ['dist/*.css', 'dist/*.js', '**/*.php'],
       fn: (event, file) => {
         if (event == 'change') {
           const bs = require("browser-sync").get("bs-webpack-plugin");
           if (file.split('.').pop()=='js' || file.split('.').pop()=='php' ) {
             bs.reload();
           } else {
             bs.reload("*.css");
           }
         }
       }
     }
   ]
 },
 {
   reload: false,
   name: 'bs-webpack-plugin'
 }
)

Upvotes: 1

oquiroz
oquiroz

Reputation: 95

Ok, this was... fast? I checked again the browser-sync-webpack-plugin documentation and at the bottom of the page I found that you can pass an option object to the plugin setting reload:false. By doing that the page won't reload when the build process is finished but it will inject the changes. And by just leaving the ['**/*.php'] match in the "files" option when initializing the BrowserSyncPlugin object the page will reload on php changes.

So I got it to work just as I wanted. Yay for me!

Upvotes: 0

Related Questions