HtmlWebpackPlugin对webpack dev server的影响

The effect of HtmlWebpackPlugin on webpack dev server

我在 React 项目上使用 Webpack,它似乎 HtmlWebpackPlugin affects the 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 才能看到我的网络应用程序.如果我尝试浏览 http://localhost:8080/index.html 然后我得到一个 404。这对我来说很有意义。

然后我添加 HtmlWebpackPluginwebpack.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 做了什么使这成为可能?

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

来自 Webpack-dev-server 文档,

This modified bundle is served from memory at the relative path specified in publicPath (see API). It will not be written to your configured output directory. Where a bundle already exists at the same URL path, the bundle in memory takes precedence (by default).

您可以访问两者 http://localhost:8080/index.html and http://localhost:8080/src/index.html。但服务方式不同。

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

http://localhost:8080/index.html, it is served by HtmlWebpackPlugin from memory. If you check the response content of this url, you will find that all your bundle file are added to the HTML(that's why we use it). For the filename, you can config it to anything you like with the 'filename' field(you can specify a subdirectory too). check https://github.com/jantimon/html-webpack-plugin#options 了解更多详情。

好的,我想我明白了。

TL;DR

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

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

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

乏味的细节:

添加 HtmlWebpackPlugin 后,它会获取您的 index.html 文件并合并到指向您的 webpack 包的 <script> 标记中。它提供来自 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 中删除 <script> 标签。这反过来意味着浏览到 src/index.html 将不再有效,因为您不再有对您的包的引用!

您现在依赖于让 HtmlWepbackPlugin 为您插入 <script> 标签,这意味着您现在必须浏览至 http://localhost:8080/index.html 以获取它生成的版本。

网页包。是。疯了。