Webpack热模块替换列表在控制台中列出更新的React组件,但不更新它们

时间:2016-06-20 22:13:40

标签: reactjs webpack webpack-dev-server

更改“关于”组件中的某些文本并保存文件后,我可以在控制台中看到以下日志:

client.js?6a8d:123 [HMR] bundle rebuilding
client.js?6a8d:126 [HMR] bundle rebuilt in 3786ms
process-update.js:27 [HMR] Checking for updates on the server...
bootstrap 5e8b103…:45 XHR finished loading: GET "http://localhost:3001/dist/5e8b1032c40f91ebd6ce.hot-update.json".hotDownloadManifest @ bootstrap 5e8b103…:45hotCheck @ bootstrap 5e8b103…:264check @ process-update.js:64module.exports @ process-update.js:28processMessage @ client.js?6a8d:139handleMessage @ client.js?6a8d:65
index.js:81 [React Transform HMR] Patching Marketing
process-update.js:100 [HMR] Updated modules:
process-update.js:102 [HMR]  - ./src/containers/Marketing/About.js
process-update.js:102 [HMR]  - ./src/containers/Marketing/index.js
process-update.js:107 [HMR] App is up to date.

但是,DOM未更新,获取更新文本的唯一方法是进行完整的浏览器刷新。

关于如何解决这个问题的任何想法?我很确定这在过去是正确设置的,我不确定我做了什么让它停止工作。我只记得最近在几个地方添加了代码分割,但about组件是主构建的一部分。

以下是...-hot-update.json

的内容
{"h":"c6abfe651b7516cb5169","c":[0]}

...-hot-update.js似乎包含已修改组件的代码。

这是我的开发webpack配置:

require('babel-polyfill')

// Webpack config for development
var fs = require('fs')
var path = require('path')
var webpack = require('webpack')
var assetsPath = path.resolve(__dirname, '../static/dist')
var host = (process.env.HOST || 'localhost')
var port = (+process.env.PORT + 1) || 3001

// const { CommonsChunkPlugin } = webpack.optimize

// https://github.com/halt-hammerzeit/webpack-isomorphic-tools
var WebpackIsomorphicToolsPlugin = require('webpack-isomorphic-tools/plugin')
var webpackIsomorphicToolsPlugin = new WebpackIsomorphicToolsPlugin(require('./webpack-isomorphic-tools'))

var babelrc = fs.readFileSync('./.babelrc')
var babelrcObject = {}

try {
  babelrcObject = JSON.parse(babelrc)
} catch (err) {
  console.error('==>     ERROR: Error parsing your .babelrc.')
  console.error(err)
}


var babelrcObjectDevelopment = babelrcObject.env && babelrcObject.env.development || {}

// merge global and dev-only plugins
var combinedPlugins = babelrcObject.plugins || []
combinedPlugins = combinedPlugins.concat(babelrcObjectDevelopment.plugins)

var babelLoaderQuery = Object.assign({}, babelrcObjectDevelopment, babelrcObject, {plugins: combinedPlugins})
delete babelLoaderQuery.env

// Since we use .babelrc for client and server, and we don't want HMR enabled on the server, we have to add
// the babel plugin react-transform-hmr manually here.

// make sure react-transform is enabled
babelLoaderQuery.plugins = babelLoaderQuery.plugins || []
var reactTransform = null
for (var i = 0; i < babelLoaderQuery.plugins.length; ++i) {
  var plugin = babelLoaderQuery.plugins[i]
  if (Array.isArray(plugin) && plugin[0] === 'react-transform') {
    reactTransform = plugin
  }
}

if (!reactTransform) {
  reactTransform = ['react-transform', {transforms: []}]
  babelLoaderQuery.plugins.push(reactTransform)
}

if (!reactTransform[1] || !reactTransform[1].transforms) {
  reactTransform[1] = Object.assign({}, reactTransform[1], {transforms: []})
}

// make sure react-transform-hmr is enabled
reactTransform[1].transforms.push({
  transform: 'react-transform-hmr',
  imports: ['react'],
  locals: ['module']
})

module.exports = {
  devtool: 'inline-source-map',
  context: path.resolve(__dirname, '..'),
  entry: {
    'main': [
      'webpack-hot-middleware/client?path=http://' + host + ':' + port + '/__webpack_hmr',
      'bootstrap-sass!./src/styles/theme/bootstrap.config.js',
      // 'font-awesome-webpack!./src/styles/theme/font-awesome.config.js',
      './src/client.js',
    ]
  },
  output: {
    path: assetsPath,
    filename: '[name]-[hash].js',
    chunkFilename: '[name]-[chunkhash].js',
    publicPath: 'http://' + host + ':' + port + '/dist/'
  },
  module: {
    loaders: [
      { test: /\.jsx?$/, exclude: /node_modules/, loaders: ['babel?' + JSON.stringify(babelLoaderQuery)]},
      { test: /\.json$/, loader: 'json-loader' },
      { test: /\.less$/, loader: 'style!css?modules&importLoaders=2&sourceMap&localIdentName=[local]___[hash:base64:5]!autoprefixer?browsers=last 2 version!less?outputStyle=expanded&sourceMap' },
      {
        test: /\.scss$/,
        loader: 'style!css?sourceMap&localIdentName=[local]___[hash:base64:5]!autoprefixer?browsers=last 2 version!sass?outputStyle=expanded&sourceMap'
      },
      { test: /\.woff(\?v=\d+\.\d+\.\d+)?$/, loader: "url?limit=10000&mimetype=application/font-woff" },
      { test: /\.woff2(\?v=\d+\.\d+\.\d+)?$/, loader: "url?limit=10000&mimetype=application/font-woff" },
      { test: /\.ttf(\?v=\d+\.\d+\.\d+)?$/, loader: "url?limit=10000&mimetype=application/octet-stream" },
      { test: /\.eot(\?v=\d+\.\d+\.\d+)?$/, loader: "file" },
      { test: /\.svg(\?v=\d+\.\d+\.\d+)?$/, loader: "url?limit=10000&mimetype=image/svg+xml" },
      { test: webpackIsomorphicToolsPlugin.regular_expression('images'), loader: 'url-loader?limit=10240' }
    ]
  },
  progress: true,
  resolve: {
    modulesDirectories: [
      'src',
      'node_modules'
    ],
    extensions: ['', '.json', '.js', '.jsx']
  },
  plugins: [
    // hot reload
    new webpack.HotModuleReplacementPlugin(),
    new webpack.IgnorePlugin(/webpack-stats\.json$/),
    // TODO: where should I put this in array?
    new CommonsChunkPlugin({ name: 'common' }),
    new webpack.DefinePlugin({
      __CLIENT__: true,
      __SERVER__: false,
      __DEVELOPMENT__: true,
      __DEVTOOLS__: true,  // <-------- DISABLE redux-devtools HERE
      'process.env.API_URL': JSON.stringify(process.env.API_URL),
      'process.env.PUBLIC_URL': JSON.stringify(process.env.PUBLIC_URL),
      'process.env.STRIPE_PUBLISHABLE_KEY': JSON.stringify(process.env.STRIPE_PUBLISHABLE_KEY),
      'process.env.INTERCOM_APP_ID': JSON.stringify(process.env.INTERCOM_APP_ID),
      'process.env.GOOGLE_ANALYTICS_CODE': JSON.stringify(process.env.GOOGLE_ANALYTICS_CODE),
      'process.env.FEATURE_MONITORING': JSON.stringify(process.env.FEATURE_MONITORING),
    }),
    webpackIsomorphicToolsPlugin.development()
  ],
}

更新:我刚刚注意到HMR对某些组件(例如我的页眉和页脚)正常工作,但对其他组件(关于页面的内容)没有。无法弄清楚是什么导致某些组件无法更新。

1 个答案:

答案 0 :(得分:0)

I had the exact same fail type: everything "looks" like it hot reloads (correct files showing up in console, compile succeeding), but the DOM simply wasn't updating. Full refresh required to update.

Fix for me was: Do not mix Stateless and 'normal' React Components in a single file.

Multiple components styles in a single file failed with HMR.

In short, keep Stateless components:

export default const MyCom = () => <div></div>

Separate (files) from class based components:

export default class NextCom extends React.Component {
  render () { return <div></div> }
}

Putting those two examples into a single file produced the HMR-working-but-failing-to-update-DOM issue you seem to be having too.