WDS执行热模块更换问题,然后在

时间:2016-11-15 22:13:59

标签: webpack webpack-dev-server webpack-hmr

我目前正在尝试使用我的webpack项目设置HOT MODULE REPLACEMENT。当我对源代码中的react组件进行更改时,我看到模块在浏览器中重新加载而没有刷新,然后完全刷新页面。

以下是我在控制台中看到的内容。

WDS seems to be running TWICE?

然后控制台中的这两行:

  • 列表项

dev-server.js:28 [HMR]无法找到更新。需要做一个完整的重载!(匿名函数)@ dev-server.js:28(匿名函数)@

  • 列表项

index.js:238request.onreadystatechange @ index.js:37 dev-server.js:29 [HMR](可能是因为重启了webpack-dev-server)

您可以看到'客户端:37 [WDS]应用已更新。重新编译...'似乎是运行TWICE ...也许这就是为什么它既热插拔又完全重新加载。

有什么想法吗?

这是我的webpack.config

module.exports = {
  devtool: 'eval',
  cache: true,

  entry: {
    index: [
        'react-hot-loader/patch',
        'webpack-dev-server/client?http://localhost:8080',
        'webpack/hot/only-dev-server',
        './js/src/index.js'
    ],
    login: './login/index.js',
  },

  output: {
    path: path.join(__dirname, 'dist'),
    publicPath: '/dist/',
    filename: '[name].js',
    chunkFilename: '[name].js'
  },

  module: {

    loaders: [

      // Transpile ES6 JSX to ES5 JS
      {
        test: /\.(js|jsx)$/,
        exclude: /node_modules/,
        loader: 'babel',
      },

      // SCSS
      {
        test: /\.scss$/,
        loaders: [
          'style',
          'css?importLoaders=1&localIdentName=[local]-[hash:base64:5]',
          'postcss-loader',
          'resolve-url',
          'sass'
        ]
      },

        {
            test: /\.json$/,
            loaders: ['json-loader'],
        }
    ]

  },

  postcss: function () {
    return {
      defaults: [autoprefixer],
      cleaner:  [autoprefixer({ browsers: ['last 2 versions'], cascade: true })]
    };
  },

  plugins: [
    new webpack.ContextReplacementPlugin(/moment[\/\\]locale$/, /en|de|fr|zh|ja|it/),
    new webpack.HotModuleReplacementPlugin(),
    new webpack.IgnorePlugin(/ReactContext/),
    new webpack.DefinePlugin({ 'process.env.apiEndPointUrl': '"'+apiEndPointUrl+'"' }),
    new JsonBundlerPlugin({
        fileInput: '**/locales/*.json',
        omit: /\/locales|\/?components|\/?services|\/?scenes|\/?features/g,
        rootDirectory: 'src'
    }),
  ],

  resolve: {
    extensions: ['', '.js', '.json', '.jsx']
  }
};

这是我在我的npm任务中运行的devServer.js文件。

const webpack = require('webpack');
const WebpackDevServer = require('webpack-dev-server');
const opener = require('opener');
const config = require('./webpack.config.js');
const host = 'localhost';
const port = 8080;

new WebpackDevServer(webpack(config), {
        publicPath: config.output.publicPath,
        hot: true,
        historyApiFallback: true,
        stats: {
            colors: true // color is life
        },
    })
    .listen(port, host, (err) => {
        if (err) {
            console.log(err);
        }
        console.log(`Listening at ${host}:${port}`);
        opener(`http://${host}:${port}`);
    });

1 个答案:

答案 0 :(得分:0)

你和我都想做的是使用webpack 2的代码片段和webpack 1安装和配置文件。

我的解决方案是密切关注此处的React HMR的webpack 2指南:https://webpack.js.org/guides/hmr-react/

$data[0]->passObject->question_1, $data[0]->passObject->question_2, $data[0]->passObject->question_3

.babelrc

npm i --save-dev babel-core babel-loader babel-preset-es2015 babel-preset-react babel-preset-stage-2 react-hot-loader@3.0.0-beta.6 webpack@2.1.0-beta.25 webpack-dev-server@2.1.0-beta.0

npm i --save react react-dom

webpack.config.js

{
  "presets": [["es2015", {"modules": false}], "stage-2", "react"],
  "plugins": ["react-hot-loader/babel"]
}

现在,这是新的重要部分

index.js

const { resolve } = require('path');
const webpack = require('webpack');

const publicPath = '/';
const contentBase = resolve(__dirname, 'dist');

module.exports = {
  entry: [
    'react-hot-loader/patch',
    'webpack-dev-server/client?http://localhost:8080',
    'webpack/hot/only-dev-server',
    './index.js'
  ],
  output: {
    filename: 'bundle.js',
    path: contentBase,
    publicPath: publicPath
  },
  devtool: 'inline-source-map',
  devServer: {
    hot: true,
    contentBase: contentBase,
    publicPath: publicPath
  },
  module: {
    rules: [
      {
        test: /\.jsx?$/,
        use: ['babel-loader'],
        exclude: /node_modules/
      }
    ],
  },
  plugins: [
    new webpack.HotModuleReplacementPlugin(),
    new webpack.NamedModulesPlugin()
  ],
  resolve: {
    extensions: ['.json', '.js', '.jsx']
  }
};

现在你的App.jsx可能是一个实际的组件,如

import React from 'react';
import ReactDOM from 'react-dom';

import { AppContainer } from 'react-hot-loader';
// AppContainer is a necessary wrapper component for HMR

import App from './components/App';

const render = (Component) => {
  ReactDOM.render(
    <AppContainer>
      <Component/>
    </AppContainer>,
    document.getElementById('root')
  );
};

render(App);

// Hot Module Replacement API
if (module.hot) {
  module.hot.accept('./components/App', () => {
    const NewApp = require('./components/App').default
    render(NewApp)
  });
}

在这种情况下保留index.js文件不变。但是,您的App.jsx可能会有更多,例如使用react-router或redux等。在这种情况下,您的App.jsx可能看起来类似于以下

import * as React from 'react';

class App extends React.Component {

  ...

  render() {
    return <div>hello world!</div>
  }
}

export default App;

在这种情况下,你想要修改index.js中的render方法,如下所示

import * as React from 'react';
import { Router, Route, IndexRoute, browserHistory } from 'react-router';

export default <Router history={browserHistory}>
  <Route component={Main}>
    <Route path="page-one" component={PageOne} />
  </Route>
</Router>;

我只是从命令行使用webpack-dev-server,所以我还没有尝试使用来自快速服务器的中间件。祝你好运,编码愉快!