css-modules / webpack-demo

Working demo of CSS Modules, using Webpack's css-loader in module mode
https://css-modules.github.io/webpack-demo/
1.49k stars 180 forks source link

[HMR] CSS vanishes on hot reload #33

Closed levino closed 7 years ago

levino commented 7 years ago

So I am using this with HMR. I got everything working fine when I firstly load the app. But when I change something in my css file, I get an update in the app but the styles are not replaced with the new information but the class just vanishes from the head section of the html. I have to F5 to reload the page and the styles are added in the head section again.

It looks to me as if on update the css is removed from the head but not added again. I understand that this issue might be unrelated to this specific package, but I thought it might be worth while starting to ask here.

webpack.config.babel.js

import path from 'path'
import webpack from 'webpack'
import HtmlWebpackPlugin from 'html-webpack-plugin'
export default {
  entry: {
    preview: './src/preview/index.jsx'
  },
  output: {
    path: path.join(__dirname, 'preview'),
    filename: '[name].js',
    publicPath: 'http://localhost:4000/'
  },
  module: {
    rules: [
      {
        test: /\.jsx?$/,
        exclude: /node_modules/,
        use: [
          {
            loader: 'babel-loader',
            options: {
              presets: [ [ "es2015", { "modules": false } ], "stage-2", "react" ]
            }
          }
        ]
      },
      {
        test: /\.json$/,
        loader: 'json-loader'
      },
      {
        test: /\.hbs$/,
        loader: 'handlebars-loader'
      },
      {
        test: /\.scss$/,
        use: [
          'style-loader',
          { loader: 'css-loader', options: { modules: true } },
          'sass-loader'
        ]
      },
      {
        test: /\.css$/,
        use: [
          'style-loader',
          { loader: 'css-loader', options: { modules: true } }
        ]
      },
      {
        test: /\.less$/,
        use: [
          'style-loader',
          { loader: 'css-loader', options: { importLoaders: 1 } },
          'less-loader'
        ]
      }
    ]
  },
  resolve: {
    extensions: ['.js', '.jsx']
  },
  plugins: [
    new webpack.ProvidePlugin({
      $: 'jquery',
      jQuery: 'jquery'
    }),
    new HtmlWebpackPlugin({
      title: 'Static Preview SatoshiPay Widget',
      template: `${__dirname}/index.ejs`
    }),
    new webpack.HotModuleReplacementPlugin(),
    // enable HMR globally
    new webpack.NamedModulesPlugin(),
    // prints more readable module names in the browser console on HMR updates
  ],
  devServer: {
    port: 4000,
    stats: 'minimal',
    host: 'localhost',
    hot: true
  },
  devtool: 'inline-source-map'
}

devDeps from package.json:


  "devDependencies": {
    "async": "^2.1.5",
    "autoprefixer": "^6.7.3",
    "babel-cli": "^6.18.0",
    "babel-core": "^6.21.0",
    "babel-eslint": "^7.1.1",
    "babel-loader": "^6.3.2",
    "babel-plugin-syntax-dynamic-import": "^6.18.0",
    "babel-polyfill": "^6.20.0",
    "babel-preset-es2015": "^6.18.0",
    "babel-preset-node6": "^11.0.0",
    "babel-preset-react": "^6.16.0",
    "babel-preset-stage-2": "^6.22.0",
    "babel-register": "^6.23.0",
    "babelify": "^7.2.0",
    "browser-sync": "^2.9.8",
    "browserify": "^14.1.0",
    "chai": "^3.5.0",
    "chai-as-promised": "^6.0.0",
    "css-loader": "^0.26.1",
    "deep-freeze": "^0.0.1",
    "del": "^2.2.2",
    "dotenv": "^4.0.0",
    "electron": "^1.4.15",
    "envify": "^4.0.0",
    "eslint": "^3.14.1",
    "eslint-plugin-react": "^6.9.0",
    "event-stream": "^3.3.2",
    "expect": "^1.20.2",
    "extract-text-webpack-plugin": "^2.0.0",
    "file-loader": "^0.10.1",
    "finalhandler": "^1.0.0",
    "flow-bin": "^0.40.0",
    "git-rev-sync": "^1.8.0",
    "glob": "^7.0.3",
    "gulp-standard": "^9.0.0",
    "handlebars": "^4.0.6",
    "handlebars-loader": "^1.4.0",
    "html-webpack-plugin": "^2.26.0",
    "json-loader": "^0.5.4",
    "karma": "^1.4.0",
    "karma-babel-preprocessor": "^6.0.1",
    "karma-chai": "^0.1.0",
    "karma-chrome-launcher": "^2.0.0",
    "karma-coverage": "^1.1.1",
    "karma-electron": "^5.1.1",
    "karma-junit-reporter": "^1.2.0",
    "karma-mocha": "^1.3.0",
    "karma-phantomjs-launcher": "^1.0.2",
    "karma-sourcemap-loader": "^0.3.7",
    "karma-spec-reporter": "^0.0.30",
    "karma-webpack": "^2.0.2",
    "less": "^2.7.2",
    "less-loader": "^2.2.3",
    "mocha": "^3.2.0",
    "mocha-loader": "^1.1.0",
    "mock-local-storage": "^1.0.2",
    "node-sass": "^4.5.0",
    "phantomjs-polyfill": "^0.0.2",
    "postcss-loader": "^1.2.2",
    "postcss-smart-import": "^0.6.7",
    "precss": "^1.4.0",
    "promise-polyfill": "^6.0.2",
    "react-hot-loader": "next",
    "sass-loader": "^6.0.2",
    "selenium-webdriver": "^3.0.1",
    "serve-static": "^1.9.3",
    "source-map-support": "^0.4.11",
    "standard": "^9.0.0",
    "style-loader": "^0.13.1",
    "uglifyify": "^3.0.1",
    "vinyl-source-stream": "^1.1.0",
    "watchify": "^3.1.2",
    "webpack": "^2.2.1",
    "webpack-dev-server": "^2.4.1"
  }
levino commented 7 years ago

The issue was in my .babelrc. One needs to set the preset for ES2015 like this:

["es2015", {"modules": false}],

See also: https://webpack.js.org/guides/hmr-react/#babel-config

I could not do it in my .babelrc because I need the modules for the webpack.config.babel.js as I want to use import there instead of require. So I had to put the babel config into the webpack config and tell webpack to ignore the rc file like this:

 module: {
    rules: [
      {
        test: /\.jsx?$/,
        exclude: /node_modules/,
        use: [
          {
            loader: 'babel-loader',
            query: {
              babelrc: false,
              presets: [
                ['es2015', { modules: false }],
                'stage-2',
                'react'
              ],
              plugins: [
                'react-hot-loader/babel'
                // Enables React code to work with HMR.
              ]
            }
          }
        ]
      }
   ]
}

After that everything worked fine.