Va1 / browser-sync-webpack-plugin

Easily use BrowserSync in your Webpack project.
MIT License
369 stars 40 forks source link

CSS hot reload does not work with Webpack 4 and mini-css-extract-plugin #69

Closed HriBB closed 4 years ago

HriBB commented 6 years ago

When I save a .scss file it always reloads the page. I'm not really sure if this is a "problem" with this plugin or webpack or mini-css-extract-plugin.

Here's my webpack config

const path = require('path')
const webpack = require('webpack')
const autoprefixer = require('autoprefixer')
const FileManagerPlugin = require('filemanager-webpack-plugin')
const CompressionPlugin = require('compression-webpack-plugin')
const BrowserSyncPlugin = require('browser-sync-webpack-plugin')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const UglifyJsPlugin = require('uglifyjs-webpack-plugin')

const isProduction = process.env.NODE_ENV === 'production'
const isDevelopment = !isProduction

const paths = {
  entry: path.resolve(__dirname, 'src', 'aokranj.js'),
  output: path.resolve(__dirname, 'public'),
  src: path.resolve(__dirname, 'src'),
  dist: path.resolve(__dirname, 'dist'),
}

const config = {
  mode: isProduction ? 'production' : 'development',
  entry: paths.entry,
  output: {
    filename: 'aokranj.js',
    path: paths.output,
  },
  devtool: 'source-map',
  module: {
    rules: [{
      test: /\.js$/,
      include: paths.src,
      use: [{ loader: 'babel-loader' }],
    },{
      test: /\.(css|scss)$/,
      include: paths.src,
      use: [
        MiniCssExtractPlugin.loader,
        //'style-loader',
        'css-loader',
        //'postcss-loader',
        'sass-loader',
      ],
    },{
      test: /\.(png|jpg|svg|gif)$/,
      loader: 'file-loader',
    }],
  },
  plugins: [
    new webpack.ProvidePlugin({
      $: 'jquery',
      jQuery: 'jquery',
      Popper: ['popper.js', 'default'],
    }),
    new MiniCssExtractPlugin({
      filename: 'aokranj.css',
    }),
  ],
}

if (isDevelopment) {
  config.plugins.push(
    new BrowserSyncPlugin({
      proxy: 'http://aokranj.local/',
      host: 'localhost',
      port: 3000,
      injectCss: true,
      files: [
        './*.php',
        './inc/**/*.php',
        './templates/**/*.php',
        './languages/*.po',
        './public/*.css',
        './public/*.js',
      ],
    },{
      reload: false,
    }),
  )
}

if (isProduction) {
  config.optimization = {
    namedModules: true,
    noEmitOnErrors: true,
    concatenateModules: true,
    minimizer: [
      new UglifyJsPlugin({
        test: /\.js($|\?)/i,
        cache: true,
        parallel: true,
      })
    ],
  }
  config.plugins.push(
    new CompressionPlugin({
      test: /\.js/
    }),
  )
}

module.exports = config

Problem is that both .js and .css files are built

[Browsersync] Watching files...
WARNING: The `text-hide()` mixin has been deprecated as of v4.1.0. It will be removed entirely in v5.
         on line 10 of node_modules/bootstrap/scss/mixins/_text-hide.scss, in mixin `text-hide`
         from line 57 of node_modules/bootstrap/scss/utilities/_text.scss
         from line 14 of node_modules/bootstrap/scss/_utilities.scss
         from line 41 of node_modules/bootstrap/scss/bootstrap.scss
         from line 12 of stdin

Hash: d73a1f9c82601110f4e9
Version: webpack 4.5.0
Time: 1116ms
Built at: 2018-4-18 04:54:02
          Asset     Size  Chunks             Chunk Names
    aokranj.css  174 KiB    main  [emitted]  main
     aokranj.js  475 KiB    main  [emitted]  main
aokranj.css.map  228 KiB    main  [emitted]  main
 aokranj.js.map  596 KiB    main  [emitted]  main
Entrypoint main = aokranj.css aokranj.js aokranj.css.map aokranj.js.map
[./src/aokranj.scss] 39 bytes {main} [built]
    + 8 hidden modules
Child mini-css-extract-plugin node_modules/css-loader/index.js!node_modules/sass-loader/lib/loader.js!src/aokranj.scss:
    Entrypoint mini-css-extract-plugin = *
    [./node_modules/css-loader/index.js!./node_modules/sass-loader/lib/loader.js!./src/aokranj.scss] ./node_modules/css-loader!./node_modules/sass-loader/lib/loader.js!./src/aokranj.scss 181 KiB {mini-css-extract-plugin} [built]
        + 1 hidden module
[Browsersync] Reloading Browsers... (buffered 2 events)

And my package.json

{
  "name": "aokranj",
  "version": "2.0.0",
  "description": "AO Kranj Wordpress Theme",
  "scripts": {
    "start": "npm run watch",
    "dev": "NODE_ENV=development webpack --watch",
    "build": "NODE_ENV=production webpack -p"
  },
  "repository": {
    "type": "git",
    "url": "git@bitbucket.org:preset-si/aokranj-website.git"
  },
  "author": "Bojan Hribernik",
  "license": "UNLICENSED",
  "homepage": "https://www.aokranj.com/",
  "dependencies": {
    "bootstrap": "4.1.0",
    "jquery": "^3.3.1",
    "popper.js": "^1.14.3"
  },
  "devDependencies": {
    "@babel/core": "^7.0.0-beta.44",
    "@babel/plugin-proposal-class-properties": "^7.0.0-beta.44",
    "@babel/plugin-proposal-object-rest-spread": "^7.0.0-beta.44",
    "@babel/preset-env": "^7.0.0-beta.44",
    "@babel/preset-flow": "^7.0.0-beta.44",
    "@babel/preset-react": "^7.0.0-beta.44",
    "autoprefixer": "^8.3.0",
    "babel-loader": "^8.0.0-beta.2",
    "browser-sync": "^2.23.6",
    "browser-sync-webpack-plugin": "^2.2.2",
    "clean-webpack-plugin": "^0.1.19",
    "compression-webpack-plugin": "^1.1.11",
    "copy-webpack-plugin": "^4.5.1",
    "cross-env": "^5.1.4",
    "css-hot-loader": "^1.3.9",
    "css-loader": "^0.28.11",
    "cssnano": "^3.10.0",
    "extract-text-webpack-plugin": "^3.0.2",
    "file-loader": "^1.1.11",
    "filemanager-webpack-plugin": "^1.0.26",
    "mini-css-extract-plugin": "^0.4.0",
    "node-sass": "^4.8.3",
    "postcss": "^6.0.21",
    "postcss-loader": "^2.1.4",
    "postcss-url": "^7.3.2",
    "precss": "^3.1.2",
    "sass-loader": "^7.0.1",
    "style-loader": "^0.20.3",
    "uglifyjs-webpack-plugin": "^1.2.4",
    "url-loader": "^1.0.1",
    "webpack": "^4.5.0",
    "webpack-cli": "^2.0.14",
    "webpack-dev-server": "^3.1.3"
  },
  "babel": {
    "presets": [
      [
        "@babel/preset-env"
      ],
      "@babel/preset-react",
      "@babel/preset-flow"
    ],
    "plugins": [
      "@babel/plugin-proposal-class-properties",
      "@babel/plugin-proposal-object-rest-spread"
    ]
  },
  "browserslist": [
    "> 5%",
    "last 2 versions"
  ]
}
gorangatuzo commented 6 years ago

I have the same problem (setup is mostly the same). Anyone found out any solutions?

onetrev commented 6 years ago

Hey @paulmasek ... I'm not sure the JS file output in mini-css-extract-plugin is related to this issue above.

For sure if you have BrowserSync watching for JS file updates then that will cause the browser refresh, but by default BrowserSync doesn't watch for JS file. And so the main issue is right now any SCSS/CSS file changes and BrowserSync does a full browser refresh (jumps to the top in Firefox) instead of injecting the CSS.

paulmasek commented 5 years ago

@onetrev I started a new webpack config today and I was able to get this working. Thanks to @fqborges comment and package here https://github.com/webpack-contrib/mini-css-extract-plugin/issues/151#issuecomment-414739879. This (magically) deletes the JS file outputted, meaning that BrowserSync doesn't try and reload the browser when it spots a JS change, and injects the CSS instead, as per the injectCss: true, setting.

This in turn means, the JS refresh isn't broken with reload: false.

Va1 commented 4 years ago

please, refer to the above comment.

thanks everyone.