1

我一直在尝试使用 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 似乎没有对渲染进行任何更改。

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

非常感谢

4

2 回答 2

0

这已经解决了(请参考这个 repo https://github.com/andrixb/WebpackSassStarter):

  • 添加webpack.config.js HtmlWebpackPlugin了以下配置:

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

  • 移动到外面的src文件夹内index.html并删除了静态脚本和链接标签(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.jsExtractTextPlugin

  • 编辑了devServer中的配置webpack.config.js

于 2017-03-30T15:38:41.630 回答
0

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

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

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

包.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

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

于 2017-03-22T14:10:27.700 回答