Webpack HMR не перезагружает файл HTML - PullRequest
0 голосов
/ 23 сентября 2018

У меня есть простая настройка HMR для перезагрузки машинописных файлов и файлов postcss.И они работают отлично, и модули перезагружаются без обновления страницы.Но когда я изменяю свои HTML-файлы, веб-сайт не перезагружается сам по себе, и содержимое HTML не загружается в горячем режиме.

Это мой файл конфигурации веб-пакета:

const { resolve } = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');

module.exports = {
  entry: resolve(__dirname, 'src/main.ts'),
  output: {
    path: resolve(__dirname, 'dist'),
    filename: 'bundle.js',
  },
  module: {
    rules: [
      {
        test: /\.ts$/,
        loader: 'awesome-typescript-loader',
        exclude: /node_modules/,
      },
      {
        test: /\.css$/,
        exclude: /node_modules/,
        use: [
          {
            loader: 'style-loader'
          },
          {
            loader: 'css-loader',
            options: {
              importLoaders: 1,
            },
          },
          {
            loader: 'postcss-loader',
          }
        ]
      }
    ]
  },
  devtool: 'source-map',
  mode: 'development',
  plugins: [
    new HtmlWebpackPlugin({
      template: resolve(__dirname, './src/index.html'),
    }),
    new webpack.HotModuleReplacementPlugin(),
    new CleanWebpackPlugin(resolve(__dirname, 'dist'))
  ],
  devServer: {
    contentBase: resolve(__dirname, 'dist'),
    port: 9000,
    hot: true,
    open: true,
    progress: true,
  }
}

Ответы [ 2 ]

0 голосов
/ 24 сентября 2018

Не уверен, что это так, но если вы хотите расширить текущую конфигурацию HMR для перезагрузки браузера при изменении внешних html / view файлов, то вы можете сделать это с помощью нескольких дополнительных строк, используя chokidar .

Возможно, он у вас уже есть, потому что webpack-dev-server использует внутри себя chokidar, но, если не найден, сначала установите его с помощью npm или пряжи:

npm install chokidar --save
yarn add -D chokidar

Затем укажите это в вашей конфигурации веб-пакета:

const chokidar = require('chokidar');

Затем в вашей конфигурации devServer:

devServer: {
  before(app, server) {
    chokidar.watch([
      './src/views/**/*.html'
    ]).on('all', function() {
      server.sockWrite(server.sockets, 'content-changed');
    })
  },

Также проверьте API для получения дополнительных параметров.

Я использую это с Webpack4.Не знаю, работает ли он с более ранними версиями ...

Надеюсь, это поможет вам или другим людям, ищущим эту ситуацию.

0 голосов
/ 23 сентября 2018

Проблема в том, что html-webpack-plugin не реагирует на изменения и не вызывает hmr.Чтобы добиться этого, вы можете попробовать что-то вроде этого:

const { resolve } = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
let devServer; // set below in devserver part

function reloadHtml() {
  this.plugin('compilation',
    thing => thing.plugin('html-webpack-plugin-after-emit', trigger));
  const cache = {};
  function trigger(data, callback) {
    const orig = cache[data.outputName];
    const html = data.html.source();
    if (orig && orig !== html)
      devServer.sockWrite(devServer.sockets, 'content-changed');
    cache[data.outputName] = html;
    callback();
  }
}

module.exports = {
  entry: resolve(__dirname, 'src/main.ts'),
  output: {
    path: resolve(__dirname, 'dist'),
    filename: 'bundle.js',
  },
  module: {
    rules: [
      {
        test: /\.ts$/,
        loader: 'awesome-typescript-loader',
        exclude: /node_modules/,
      },
      {
        test: /\.css$/,
        exclude: /node_modules/,
        use: [
          {
            loader: 'style-loader'
          },
          {
            loader: 'css-loader',
            options: {
              importLoaders: 1,
            },
          },
          {
            loader: 'postcss-loader',
          }
        ]
      }
    ]
  },
  devtool: 'source-map',
  mode: 'development',
  plugins: [
    reloadHtml,
    new HtmlWebpackPlugin({
      template: resolve(__dirname, './src/index.html'),
    }),
    new webpack.HotModuleReplacementPlugin(),
    new CleanWebpackPlugin(resolve(__dirname, 'dist'))
  ],
  devServer: {
    before(app, server) {
      devServer = server;
    },
    contentBase: resolve(__dirname, 'dist'),
    port: 9000,
    hot: true,
    open: true,
    progress: true,
  }
}

Если вы получите:

DeprecationWarning: Tapable.plugin is deprecated. Use new API on `.hooks` instead

Вы можете изменить reloadHtml на это:

function reloadHtml() {
  const cache = {}
  const plugin = {name: 'CustomHtmlReloadPlugin'}
  this.hooks.compilation.tap(plugin, compilation => {
    compilation.hooks.htmlWebpackPluginAfterEmit.tap(plugin, data => {
      const orig = cache[data.outputName]
      const html = data.html.source()
      if (orig && orig !== html) {
        devServer.sockWrite(devServer.sockets, 'content-changed')
      }
      cache[data.outputName] = html
    })
  })
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...