【问题标题】:The effect of HtmlWebpackPlugin on webpack dev serverHtmlWebpackPlugin 对 webpack 开发服务器的影响
【发布时间】:2018-10-03 15:49:43
【问题描述】:

我在 React 项目中使用 Webpack,似乎 HtmlWebpackPlugin 以一种我不明白的奇怪方式影响了 webpack dev server

无论该文件在代码库中的哪个位置,我似乎都可以浏览到 index.html,这是单独使用开发服务器无法实现的。

假设我有以下目录结构:

myproj/
  |- package.json
  |- webpack.config.js
  |- src/
    |- index.html
    |- index.jsx

还有一个如下所示的webpack.config.js 文件:

const path = require('path');

module.exports = {
    entry: './src/index.jsx',
   
    devServer: {
        contentBase: __dirname
    }
};

然后我运行webpack-dev-server --mode=development。由于我将devServer.contentBase 设置为当前目录(myproj),并且index.html 文件位于myproj/src 中,因此我必须浏览到http://localhost:8080/src/index.html 才能查看我的Web 应用程序。如果我尝试浏览http://localhost:8080/index.html,那么我会得到一个 404。这对我来说很有意义。

然后我添加HtmlWebpackPlugin,在webpack.config.js 内没有任何改变:

const HtmlWebpackPlugin = require('html-webpack-plugin');
....
plugins: [
    new HtmlWebpackPlugin({
        template: './src/index.html'
    })
]

现在我突然可以浏览到 http://localhost:8080/index.html 就好了。事实上,我可以点击http://localhost:8080/index.htmlhttp://localhost:8080/src/index.html

那是怎么回事? HtmlWebpackPlugin 做了什么让这成为可能?

【问题讨论】:

  • 它会在 root 为您创建 html 文件。可能你在src 内还有另一个index.html,它会在第二种情况下加载。
  • @Prajwal 感谢您提供的信息。所以我猜和bundle.js文件一样,这个index.html文件只存在于内存中?我没有看到它被写入任何地方的磁盘。

标签: webpack webpack-dev-server html-webpack-plugin


【解决方案1】:

正如您所观察到的,当您运行 webpack-dev-server 时,所有 webpack 输出文件(包括样式、脚本和服务工作者)都将仅从内存中加载。这不会将任何文件写入配置的输出目录。

来自Webpack-dev-server docs,

这个修改过的包是从内存中的相对路径提供的 在 publicPath 中指定(参见 API)。它不会被写入您的 配置的输出目录。捆绑已经同时存在的地方 URL路径,内存中的bundle优先(默认)。

【讨论】:

    【解决方案2】:

    您确实可以访问http://localhost:8080/index.htmlhttp://localhost:8080/src/index.html。但服务方式不同。

    对于http://localhost:8080/src/index.html,它由 webpack-dev-server 提供服务,就像不包含 HtmlWebpackPlugin 时一样。如果你查看这个url的响应内容,你会发现它和你磁盘上src/index.html的内容是一致的。

    对于http://localhost:8080/index.html,它由内存中的 HtmlWebpackPlugin 提供服务。如果你检查这个 url 的响应内容,你会发现你所有的 bundle 文件都被添加到了 HTML 中(这就是我们使用它的原因)。对于文件名,您可以使用“文件名”字段将其配置为您喜欢的任何内容(您也可以指定子目录)。查看https://github.com/jantimon/html-webpack-plugin#options了解更多详情。

    【讨论】:

      【解决方案3】:

      好的,我想我想通了。

      TL;DR

      添加HtmlWebpackPlugin 后,您应该从index.html 中删除此行:

      <script type="text/javascript" src="main.bundle.js"></script>
      

      并且只浏览到http://localhost:8080/index.html

      繁琐的细节:

      添加HtmlWebpackPlugin 后,它会获取您的index.html 文件并合并到指向您的webpack 包的&lt;script&gt; 标记中。它从http://localhost:8080 提供这个合并的 html 文件。即使index.html 已经包含对包的引用,它也会这样做。

      插件实际上并没有用合并的版本覆盖index.html。所以浏览到http://localhost:8080/src/index.html 只会显示磁盘上的文件。

      所以如果你的src/index.html 文件看起来像这样之前你添加HtmlWebpackPlugin:

      <body>
          <div id="app">it worked</div>
          <script type="text/javascript" src="main.bundle.js"></script>
      </body>
      

      然后你添加HtmlWebpackPlugin,浏览到http://localhost:8080给你这个合并版本:

      <body>
          <div id="app">it worked</div>
          <script type="text/javascript" src="main.bundle.js"></script>
          <script type="text/javascript" src="main.bundle.js"></script>
      </body>
      

      所以现在您将有两个对包的引用,一个是您在文件中添加的,另一个是 HtmlWebpackPlugin 添加的。

      浏览到http://localhost:8080/src 可以为您提供src/index.html 磁盘上的内容:

      <body>
          <div id="app">it worked</div>
          <script type="text/javascript" src="main.bundle.js"></script>
      </body>
      

      但是,由于他使用HtmlWebpackPlugin 的全部目的是让它为您插入捆绑包引用,这意味着您应该从src/index.html 中删除该&lt;script&gt; 标签。这反过来意味着浏览到src/index.html 将不再起作用,因为您不再拥有对您的捆绑包的引用!

      您现在依赖于让HtmlWepbackPlugin 为您插入&lt;script&gt; 标签,这意味着您现在必须浏览到http://localhost:8080/index.html 才能获得它生成的版本。

      网页包。是。疯了。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-11-20
        • 2015-10-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-06-26
        相关资源
        最近更新 更多