Search code examples
node.jsexpresswebpackreact-hot-loader

Error development is not defined error with react-hot-loader v3 and webpack-hot-middleware


Given that these are the dependencies that I am using:

"react-hot-loader": "3.0.0-beta.7",
"webpack": "2.6.1",
"webpack-dev-middleware": "^1.11.0",
"webpack-hot-middleware": "^2.18.1",
"webpack-merge": "^4.1.0"

Error

patch.js:5 

Uncaught ReferenceError: development is not defined
    at Object.defineProperty.value (patch.js:5)
    at __webpack_require__ (bootstrap 921586e…:659)
    at fn (bootstrap 921586e…:85)
    at Object.options.path (patch.js:1)
    at __webpack_require__ (bootstrap 921586e…:659)
    at fn (bootstrap 921586e…:85)
    at Object.<anonymous> (process-update.js:132)
    at __webpack_require__ (bootstrap 921586e…:659)
    at validateFormat (bootstrap 921586e…:708)
    at bootstrap 921586e…:708

You might want to either take a look at this repo 

webpack-config

const FILE_PATHS = {
  entry: path.resolve('./src/index.js'),
  reactHotLoader: 'react-hot-loader/patch',
  hmrEntry: 'webpack-hot-middleware/client?path=/__webpack_hmr&timeout=20000', // this is from the webpack-hot-middleware docs
  output: '/' // this is the path used by webpack-dev-middleware, the docs say no real path is required, just pass in `/`
}

const devOnly = {
  entry: FILE_PATHS.entry,
  output: {
    path: '/',
    publicPath: '/assets/',
    filename: 'bundle.js'
  },
  devtool: 'source-map',
  module: {
    rules: [
      {
        test: /\.jsx?$/,
        use: [
          {
            loader: 'babel-loader'
          }
        ],
        // react-hot-loader asks to include src and exclude node_modules in https://github.com/gaearon/react-hot-loader/blob/master/docs/Troubleshooting.md
        include: path.resolve('./src'),
        exclude: /node_modules/
      },
      {
        test: /\.json$/,
        use: [
          {
            loader: 'json-loader'
          }
        ]
      },
      {
        test: /\.svg$/,
        use: [
          {
            loader: 'svg-sprite-loader'
          }
        ]
      }
    ]
  },
  plugins: [
    new DefinePlugin({
      'process.env.NODE_ENV': 'development'
    })
  ]
}

const hmr = {
  entry: [FILE_PATHS.reactHotLoader, FILE_PATHS.hmrEntry, FILE_PATHS.entry],
  plugins: [new HmrPlugin(), new NoErrorsPlugin()],
  devServer: {
    hot: true
  }
}

const dev = merge(devOnly, hmr)

module.exports = {dev}

Express Server

// process.env.NODE_ENV = 'development'
const express = require('express')
const webpack = require('webpack')
const historyApiFallback = require('connect-history-api-fallback')

const normalizeAssets = assets => {
  return Array.isArray(assets) ? assets : [assets]
}

const getLinks = assets => {
  const styles = assets.filter(path => path.endsWith('.css'))
  const links = styles.map(path => `<link rel="stylesheet" href="${path}" />`)
  return links.join('\n')
}

const publicPath = '/assets/'

const getScripts = assets => {
  const js = assets.filter(path => path.endsWith('.js'))
  const scripts = js.map(path => `<script src="${path}"></script>`)
  return scripts.join('\n')
}

const devMiddlewareConfig = {
  serverSideRender: true,
  stats: 'normal',
  publicPath: publicPath,
  watchOptions: {
    poll: 1000,
    aggregateTimeout: 300
  }
}

const hotMiddlewareConfig = {
  reload: true,
  overlay: true
}

const devMiddlewareCreator = require('webpack-dev-middleware')
const hotMiddlewareCreator = require('webpack-hot-middleware')

const options = require('./webpack.config')

const {dev: devConfig} = options

const compiler = webpack(devConfig)
const devMiddleware = devMiddlewareCreator(compiler, devMiddlewareConfig)
const hotMiddleware = hotMiddlewareCreator(compiler, hotMiddlewareConfig)

const app = express()
app.use(devMiddleware)
app.use(hotMiddleware)
app.use(express.static(__dirname + '/public'))
app.use((req, res) => {
  const stats = res.locals.webpackStats.toJson()
  const assets = normalizeAssets(stats.assetsByChunkName.main)
  const styles = getLinks(assets)
  const scripts = getScripts(assets)
  res.send(
    `
<!DOCTYPE html>
    <html>
      <head>
        <title>Webpack is crazy</title>
        ${styles}
      </head>
      <body>
      <div id="app">
      </div>
      ${scripts}
      </body>
    </html>
`
  )
})

// app.use(historyApiFallback)

app.listen(3000, err => {
  if (!err) {
    console.log('Server is listening on port 3000')
  }
})

Solution

  • The error is caused by this part of your configuration:

    new DefinePlugin({
      'process.env.NODE_ENV': 'development'
    })
    

    To quote the documentation:

    Note that because the plugin does a direct text replacement, the value given to it must include actual quotes inside of the string itself. Typically, this is done either with either alternate quotes, such as '"production"', or by using JSON.stringify('production').

    If you replace it with, for example, the following, it should work:

    new DefinePlugin({
      'process.env.NODE_ENV': '"development"'
    })