linuxwebpackwebpack-dev-serverhot-module-replacement

Issue with hot reloading on linux; cleared with deleteing node_modules and cache. Fixed


first question here. Hot reloading used to working fine, then OS reinstall and now not working. Currently have an ugly fix.

My friend set up a react project that I've been learning on. I had to re-install my OS recently. Prior to that hot reloading was working fine.

With my current machine I can npm run okay for 1 session. after shutdown and startup hot reloading doesn't work. I will then:

  1. Delete node_modules
  2. npm cache clear --force
  3. npm install

as found in this answer https://github.com/webpack/webpack-dev-server/issues/1003#issuecomment-328706990

I am assuming its my machine- not sure where to look. Any help would be great. It's a slight pain to do this every time. Thanks

I'm using Xubuntu, VScode, firefox.

Contents of webpack.config.js. Not sure if it helps

const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
const path = require('path');

function createWebpackConfig() {
  const prod = process.env.NODE_ENV === 'production' || false;
  const dev = !prod;
  const buildDir = path.join(__dirname, 'build');
  const projDir = path.join(__dirname, 'src');
  const commonDir = path.join(projDir, 'common');

  const devPlugins = [
    new webpack.HotModuleReplacementPlugin(),
    new webpack.NamedModulesPlugin(),
    new webpack.NoEmitOnErrorsPlugin()
  ];

  const prodPlugins = [
    new MiniCssExtractPlugin({
      filename: 'main-[contenthash].css',
      allChunks: true
    }),
    new webpack.optimize.AggressiveMergingPlugin()
  ];

  return {
    entry: {
      app: path.join(projDir, 'index.js')
    },

    output: {
      path: buildDir,
      sourceMapFilename: '[name].map',
      filename: `[name]-[${dev ? 'hash' : 'chunkhash'}].js`
    },

    resolve: {
      modules: ['src', 'node_modules'],
      extensions: ['.js', '.jsx', '.css', '.scss'],
      alias: {
        actions: path.join(commonDir, 'actions'),
        reducers: path.join(commonDir, 'reducers'),
        assets: path.join(commonDir, 'assets'),
        components: path.join(commonDir, 'components'),
        styles: path.join(commonDir, 'styles'),
        commonStyles: path.join(commonDir, 'styles', 'common.scss'),
        utils: path.join(commonDir, 'utils')
      }
    },

    cache: dev,

    devtool: dev ? 'cheap-module-source-map' : false,

    stats: {
      colors: true,
      reasons: true,
      hash: Boolean(prod),
      version: Boolean(prod),
      timings: true,
      chunks: Boolean(prod),
      chunkModules: Boolean(prod),
      cached: Boolean(prod),
      cachedAssets: Boolean(prod)
    },

    plugins: [
      new HtmlWebpackPlugin({
        template: path.join(projDir, 'index.template.html'),
        title: 'IMDB Clone',
        favicon: path.join(commonDir, 'assets', 'favicon.ico'),
        inject: false,
        minify: {
          removeComments: Boolean(prod),
          collapseWhitespace: Boolean(prod),
          removeRedundantAttributes: Boolean(prod),
          useShortDoctype: Boolean(prod),
          removeEmptyAttributes: Boolean(prod),
          removeStyleLinkTypeAttributes: Boolean(prod),
          keepClosingSlash: Boolean(prod),
          minifyJS: Boolean(prod),
          minifyCSS: Boolean(prod),
          minifyURLs: Boolean(prod)
        },
        baseUrl: dev ? '' : "location.protocol + '//' + location.host"
      }),
      new webpack.ProvidePlugin({
        React: 'react',
        PropTypes: 'prop-types',
        classNames: 'classnames'
      })
    ].concat(dev ? devPlugins : prodPlugins),

    module: {
      rules: [
        {
          test: /\.jsx?$/,
          exclude: /node_modules/,
          use: {
            loader: 'babel-loader',
            options: {
              cacheDirectory: dev
            }
          }
        },
        {
          test: /\.css$/,
          include: /node_modules/,
          use: ['style-loader', 'css-loader']
        },
        {
          test: /\.s?css$/,
          exclude: /node_modules/,
          use: dev
            ? [
                'style-loader',
                {
                  loader: 'css-loader',
                  options: {
                    minimize: Boolean(prod),
                    localIdentName: dev ? '[path][name]__[local]' : '',
                    modules: true,
                    url: false,
                    sourceMap: true,
                    importLoader: 2
                  }
                },
                {
                  loader: 'sass-loader',
                  options: {
                    sourceMap: true
                  }
                }
              ]
            : MiniCssExtractPlugin.extract({
                fallback: 'style-loader',
                use: [
                  {
                    loader: 'css-loader',
                    options: {
                      minimize: Boolean(prod),
                      modules: true
                    }
                  },
                  'sass-loader'
                ]
              })
        },
        {
          test: /\.html$/,
          exclude: [/node_modules/, path.join(__dirname, 'src', 'index.template.html')],
          use: [
            {
              loader: 'html-loader',
              options: {
                minimize: true
              }
            }
          ]
        },
        {
          test: /\.(jpg|png|eot|svg|ttf|woff|woff2)?(\?[a-z0-9#=&.]+)?$/,
          use: 'file-loader'
        }
      ]
    },

    devServer: {
      historyApiFallback: true
    }
  };
}

module.exports = createWebpackConfig();

Solution

  • Update: found a fix! https://github.com/guard/listen/wiki/Increasing-the-amount-of-inotify-watchers?fbclid=IwAR1zVoZK_jSBXnpDdH3aXO_vwNyDoYoOmdhbXkGcsxh9QNmziHn19Gw6KmA

    I'm running Ubuntu and there was an issue with inotify. All happy now. Summary from link: Listen uses inotify by default on Linux to monitor directories for changes. It's not uncommon to encounter a system limit on the number of files you can monitor. For example, Ubuntu Lucid's (64bit) inotify limit is set to 8192.

    Fix: run command to increase limit. Found below and is OS dependent

    From link:

    If you are not interested in the technical details and only want to get Listen to work:

        echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.conf && sudo sysctl -p
    
        echo fs.inotify.max_user_watches=524288 | sudo tee /etc/sysctl.d/40-max-user-watches.conf && sudo sysctl --system
    

    Then paste it in your terminal and press on enter to run it. The technical details

    Listen uses inotify by default on Linux to monitor directories for changes. It's not uncommon to encounter a system limit on the number of files you can monitor. For example, Ubuntu Lucid's (64bit) inotify limit is set to 8192.

    You can get your current inotify file watch limit by executing:

    $ cat /proc/sys/fs/inotify/max_user_watches
    

    When this limit is not enough to monitor all files inside a directory, the limit must be increased for Listen to work properly.

    You can set a new limit temporary with:

    $ sudo sysctl fs.inotify.max_user_watches=524288
    $ sudo sysctl -p
    

    If you like to make your limit permanent, use:

    $ echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.conf
    $ sudo sysctl -p
    

    You may also need to pay attention to the values of max_queued_events and max_user_instances if Listen keeps on complaining.