HtmlWebpackPlugin对webpack dev server的影响

7
我正在一个React项目中使用Webpack,似乎HtmlWebpackPlugin以一种我不理解的奇怪方式影响webpack dev server
它似乎允许我浏览到index.html,无论该文件在代码库中的位置如何,在没有dev server的情况下是不可能实现的。
假设我有以下目录结构:
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.html 或者 http://localhost:8080/src/index.html。这是怎么回事?HtmlWebpackPlugin 做了什么使这成为可能?

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

6

好的,我想我弄清楚了。

简而言之

一旦添加了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 只会显示磁盘上的原始文件。

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

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

现在你将有两个关于bundle的引用,一个是你在文件中添加的,另一个是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以获取它生成的版本。Webpack. Be. Crazy.

3
正如您所观察到的,当您运行webpack-dev-server时,所有的webpack输出文件(包括样式、脚本和服务工作者)都将仅从内存中加载。这不会写入任何文件到配置的输出目录。
根据Webpack-dev-server文档所述,
“此修改后的捆绑包通过在publicPath(请参见API)中指定的相对路径从内存中提供。它不会被写入您配置的输出目录。在相同的URL路径下已经存在一个捆绑包的情况下,默认情况下,内存中的捆绑包优先。”

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的响应内容,您会发现所有打包文件都已添加到HTML中(这就是我们使用它的原因)。对于文件名,您可以使用“filename”字段将其配置为任何您喜欢的内容(您还可以指定子目录)。有关更多详细信息,请查看https://github.com/jantimon/html-webpack-plugin#options

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接