【问题标题】:Webpack Hot Module Replacement does not inject the updated codeWebpack Hot Module Replacement 不会注入更新的代码
【发布时间】:2017-07-26 06:32:56
【问题描述】:

我一直在尝试使用 Webpack-Dev-Server 配置 Webpack 2 Hot Module Replacement。

webpack.config.js 如下:

  const path = require('path');
  const Webpack = require('webpack');
  const ExtractTextPlugin = require('extract-text-webpack-plugin');

  const HotModuleReplacement = new Webpack.HotModuleReplacementPlugin();
  const NamedModulesPlugin = new Webpack.NamedModulesPlugin();
  const NoEmitOnErrorsPlugin = new Webpack.NoEmitOnErrorsPlugin();

  const extractCSS = new ExtractTextPlugin('main.css');
  const extractSCSS = new ExtractTextPlugin('styles.css');

  const config = {
      entry: [
          'webpack-dev-server/client?http://localhost:8080',
          // bundle the client for webpack-dev-server
          // and connect to the provided endpoint
         'webpack/hot/only-dev-server',
         // bundle the client for hot reloading
         // only- means to only hot reload for successful updates
         './src/index.js',
      ],
      output: {
          path: path.resolve(__dirname, 'dist'),
          filename: 'bundle.js',
          publicPath: 'http://localhost:8080/',
          hotUpdateChunkFilename: 'hot/hot-update.js',
          hotUpdateMainFilename: 'hot/hot-update.json',
      },
      module: {
          rules: [
              {
                  test: /\.(js|jsx)$/,
                  exclude: [
                      path.resolve(__dirname, 'node_modules'),
                  ],
                  loader: 'babel-loader',
                  options: {
                      presets: ['react', 'es2015', 'stage-2'],
                  },
              },
              {
                  test: /\.scss$/,
                  loader: extractSCSS.extract({
                      fallback: 'style-loader',
                      use: ['css-loader', 'postcss-loader', 'sass-loader'],
                  }),
              },
              {
                  test: /\.css$/,
                  loader: extractCSS.extract({
                      fallback: 'style-loader',
                      use: ['css-loader', 'postcss-loader'],
                  }),
              },
          ],
      },
      plugins: [
          extractCSS,
          extractSCSS,
          HotModuleReplacement,
          NamedModulesPlugin,
          NoEmitOnErrorsPlugin,
      ],

      devtool: 'source-map',
      devServer: {
          publicPath: 'http://localhost:8080/',
          contentBase: './',
          inline: true,
          hot: true,
          historyApiFallback: true,
          stats: {
              colors: true,
          },
      },
   };

   module.exports = config;

我有这个文件夹结构:

/
/src
/src/index.js
/src/index.scss

我认为我需要像这样在index.js 中使用 HMR API:

import MockComponent from './MockComponent/MockComponent';

export default class App {
    constructor() {
        this.mock = new MockComponent();
    }
    render() {
        return `<div class="element">${this.mock.render()}</div>`;
    }
}

let app = {};
app = new App();
const mainDiv = document.querySelector('#root');
mainDiv.innerHTML = app.render();

// Hot Module Replacement API
if (module.hot) {
    module.hot.accept();
}

问题是当我在控制台中更改代码时,我得到了:

但是 HMR 似乎没有对渲染进行任何更改。

有人可以帮我解决这个问题吗?

非常感谢

【问题讨论】:

  • 您最终解决了这个问题吗?这个答案有帮助吗?
  • 感谢您的回答,但我还没有排序。我从我的开发环境中删除了ExtractTextPlugin,但现在在替换组件样式时,我在控制台中得到了[HMR] Update failed: Error: Manifest request to http://localhost/hot/hot-update.json timed out. at XMLHttpRequest.request.onreadystatechange (http://localhost:8080/main.bundle.js:38:22) 输出(请参阅此分支github.com/andrixb/WebpackSassStarter/blob/testHMR/…)。我有两个单独的 dev 和 prod 配置,所以我没有像你展示的那样使用环境变量。

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


【解决方案1】:

问题似乎是您在开发模式下没有disable ExtractTextPlugin。如果不禁用它,您传递的 fallback 加载程序将不会运行,在这种情况下,style-loaderExtractTextPlugin 本身不支持 HMR。

在生产中,您不希望禁用ExtractTextPlugin,因此一种方法是使用一个配置,即使用--env 标志。请注意,通常建议使用分离配置,一种用于生产,一种用于开发,尽管您可以使用webpack-merge 之类的工具来共享公共位。

因此,在您的 package.json 中,您需要更新您的脚本,然后将您的配置更改为一个函数,以便它可以接受 env 对象作为参数。

package.json

{
  ...
  scripts: {
    "start": "webpack-dev-server --env.dev",
    "build": "webpack"
  },
  ...
}

webpack.config.js

...

const config = (env = {}) => ({
  ...
  plugins: [
    new ExtractTextPlugin({
      filename: 'styles.css',
      disable: env.dev === true
    })
  ]
})

为了简洁起见,我在这里排除了很多,但这应该会给你一个很好的主意。请参阅下面的我正在使用的版本...

extract-text-webpack-plugin@2.1.0
style-loader@0.14.0
webpack@2.2.1
webpack-dev-server@2.4.2

需要注意的是,虽然您可以在 devServer 中使用 hot: true 和在 plugins 中使用 new HotModuleReplacementPlugin() 启用 HMR,但需要其他加载程序和配置更改才能在浏览器中针对不同情况产生“实时”更改代码类型...这里有一些我想到的:

【讨论】:

    【解决方案2】:

    这个问题已经解决了(请参考这个repohttps://github.com/andrixb/WebpackSassStarter):

    • 添加到webpack.config.jsHtmlWebpackPlugin,配置如下:

      new HtmlWebpackPlugin({ title: 'FE Build Setup', hash: true, template: './src/index.html', }),

    • index.html 移到src 文件夹内,并删除了静态脚本和链接标签(index.html 现在仅用作模板)
    • webpack.config.js 中删除 在entry

      'webpack-dev-server/client? http://localhost:8080', // bundle the client for webpack-dev-server // and connect to the provided endpoint 'webpack/hot/only-dev-server', // bundle the client for hot reloading // only- means to only hot reload for successful updates

      output:

      publicPath: 'http://localhost:8080/', hotUpdateChunkFilename: 'hot/hot-update.js', hotUpdateMainFilename: 'hot/hot-update.json',

    • 按照 @Skip Jack

    • 的建议从开发环境中删除(在 webpack.config.js 中)ExtractTextPlugin
    • 修改了webpack.config.js中的devServer配置

    【讨论】:

      猜你喜欢
      • 2021-03-07
      • 1970-01-01
      • 1970-01-01
      • 2018-03-12
      • 1970-01-01
      • 2016-10-01
      • 2018-12-03
      • 2016-05-17
      • 2016-07-08
      相关资源
      最近更新 更多