【问题标题】:How to watch index.html using webpack-dev-server and html-webpack-plugin如何使用 webpack-dev-server 和 html-webpack-plugin 观看 index.html
【发布时间】:2016-01-16 00:00:56
【问题描述】:

我正在使用 webpack-dev-server 进行开发,使用 html-webpack-plugin 生成带有修订源的 index.html。问题是每次我更改 index.html 时,捆绑系统都不会再次重建。我知道索引不在条目中,但是有没有办法解决这个问题?

【问题讨论】:

  • 我的解决方案是否解决了您的问题?我很想知道您是否找到了其他方法。
  • 我在同一条船上..我正在努力避免两个不同的 index.html,一个用于生产,一个用于开发,引用不同的资产..
  • @Spock 请参阅下面的答案。您可以在入口点中要求您的模板。每次更改模板时,开发服务器都应该更新。

标签: webpack webpack-dev-server


【解决方案1】:

问题是 index.html 没有被 Webpack 监视。它只监视代码中某处“需要”或“导入”的文件,并且加载程序正在测试。

解决方案分为两部分。

首先需要您的入口点中的 index.html 文件。从技术上讲,您可以在应用程序的任何地方使用它,但这非常方便。如果您在 html-webpack-plugin 中使用模板,我相信您也可以只需要您的模板。

我在我的 index.js 文件中需要我的 index.html,这是我的入口点:

require('./index.html')
const angular = require('angular')
const app = angular.module('app', [])
//...so on and so forth

最后,安装 raw-loader 和所有其他加载器,并将其添加到 Webpack 配置文件中。因此:

{
   test: /\.html$/,
   loader: "raw-loader"
}

原始加载器会将几乎所有“需要”的文件转换为文本字符串,然后,Webpack 会为您监视它并在您每次进行更改时刷新开发服务器。

无论是 Webpack 本身还是您的程序都不会在加载 index.html 文件(或模板)的阶段对其进行任何实际操作。这对于您的生产或测试环境来说完全没有必要,所以为了更好的衡量,我只在运行开发服务器时添加它:

/* eslint no-undef: 0 */

if (process.env.NODE_ENV === 'development') {
  require('./index.html')
}

const angular = require('angular')
const app = angular.module('app', [])
//...so on and so forth

理论上,您可以“要求”一堆您希望它观看的其他静态 html 文件。 ...或文本文件。我自己将 raw-loader 用于 Angular 指令模板,但我不必将它们添加到我的入口点的开头。我可以只在指令模板属性中要求,如下所示:

module.exports = function(app) {
  app.directive('myDirective', function(aListItem) {
    return {
      template: require('./myTemplate.html'),
      restrict: 'E',
      controller: function($scope) {
        $scope.someThingThatGoesInMyTemplate = 'I love raw-loader!'
      }
    }
  })
}

【讨论】:

  • 耶稣,时间过得真快!很抱歉我没有回到这个话题。这很棒,效果很好!
  • 我对在这里获取 process.env 的状态感到困惑。这是在服务器端运行吗?在我的 index.js 中使用该代码 sn-p 不起作用。我猜这个变量没有被识别,而且它是未定义的,因为它是客户端。你能澄清一下你是如何完成这项工作的吗?
  • @spb 很抱歉。这可能令人沮丧。我的意思不是要复制和粘贴我的示例。当您可以从命令行运行 webpack 时,可以设置 process.env.NODE_ENV。我只是将“NODE_ENV=development”或“NODE_ENV=production”添加到我的 webpack 命令(或 webpack-dev-sever 命令,取决于我要运行的内容)。然后我可以使用“process.env.NODE_ENV”从我的代码中引出该设置。如果需要,这会给出进一步的解释:*.com/questions/9198310/…
  • 不,没那么严重。看起来您在 Angular 文件中使用了该 process.env 评估,但推测它可能是在您的 webpack 配置或其他东西中处理的?在节点上运行的东西,我猜是底线。无论如何,我使用您的 raw-loader 提示得到了我立即需要的工作,这就足够了。所以谢谢你。 :)
  • @spb 我认为您需要使用 DefinePlugin webpack 插件才能在前端 javascript 代码中使用环境变量。比如:new webpack.DefinePlugin({ NODE_ENV: JSON.stringify(process.env.NODE_ENV) }),然后在你的app.jsif (NODE_ENV === 'development') { ... } 但也许@GabrielKunkel 可以更具体一点,他们是如何在前端代码中使用process.env.VARIABLE...
【解决方案2】:

只需将watchContentBase: true 添加到您的devServer 的配置中。 webpack-dev-server 将监视位于contentBase 目录中的所有文件的更改。这里我们看./src里面的所有文件

webpack.config.js:

...
 devServer: {
   port: 8080,
   contentBase: './src',
   watchContentBase: true

} 

【讨论】:

  • 我一直在寻找一个简单的解决方案来查看我的 html / twig(模板)目录并在这些更改时重新加载页面。我正在将 webpack 和 dev-server 用于非 SPA 站点(Craft CMS)。我所要做的就是将我的 contentBase 更改为 './templates' 。一个简单的解决方案一直在文档中,但没有在用例中找到。谢谢你的回答!
  • 多么简单。我认为这应该是公认的答案。
  • 如果可以的话,我会投票二十次!比通过一些 webpack 插件不必要地处理我的 HTML 来获得自动重新加载要简单得多。
【解决方案3】:

如果您仅使用 npx webpack --watch 构建它,您可以将缓存设置为 false 以每次生成文件。

new HtmlWebpackPlugin({
  cache: false,
})

阅读此链接以进一步定制,htmlwebpackplugin

【讨论】:

  • 正是我需要的,不知道为什么我在其他任何地方都找不到!!!
【解决方案4】:

另一种解决方案是使用file-loader在入口javascript文件处导入html文件。

import 'file-loader!../templates/index.html';

您可以像往常一样进行 html-webpack-plugin 配置

plugins: [
 new HtmlWebPackPlugin({
  template: path.resolve(__dirname, 'src/templates/index.html'),
  filename: path.resolve(__dirname, 'dist/index.html'),
  files: {
   css: ['style.css'],
   js: ['main.js'],
  }
 })
]

webpack-dev-server 运行时,这不会向光盘写入任何内容

【讨论】:

    【解决方案5】:

    使用webpack > 5.0,使用watchFiles 选项

    devServer: {
        open: true,
        watchFiles: ['src/**/*'],
    },
    

    【讨论】:

      【解决方案6】:

      来自webpack > 5.0,没有contentBasewatchContentBase 选项
      相反,您可以这样做:

      devServer: {
         watchFiles:['src/**/*'] // to detect changes on all files inside src directory
      }
      

      【讨论】: