webpack 插件之Html-Webpack-Plugin

2023-11-18

webpack 插件之Html-Webpack-Plugin

1. 为什么我们需要这个插件

先来看一个应用场景。
我们自己打算搭建一个网站,这个网站有很多个页面,我们为每个页面创建一大堆的css样式,js脚本,然后尝试用webpack进行打包。

于是我们在webpack.config.js里这样写了:

const path = require('path');
module.exports = {
    //两个页面相应的js
    entry:[
        "./src/scripts/hello.js",
        "./src/scripts/main.js"
    ],
    output:{
        filename:'main.bundle.js',
        path:path.resolve(__dirname,'dist')
    }
}

两个文件的内容如下:

hello.js

function sayHello (){
    alert('Hello');
}

sayHello();

main.js

function sayMain(){
    alert('Main');
}

sayMain();

但是我们这里的output只有一个path关键字,无疑,它们会被整合到一起。

我们在/dist目录下创建Index.html加载打包后的js

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <script type="text/javascript" src="./main.bundle.js"></script>
</body>
</html>

打开浏览器看看结果

这里写图片描述

这里写图片描述

这当然对于浏览器对服务器的请求数减小是极好的,但有的时候我们并不想这样做,因为两个模块没有依赖关系,我们想把它分开来

于是我们打算用webpack把它们打成两个包(在实际的应用场景中,这两个互不依赖的模块可能还有更多的依赖模块),修改过后的webpack.config.js如下

const path = require('path');
module.exports = {
    //两个页面相应的js
    entry:{
        helloModule:"./src/scripts/hello.js",
        mainModule:"./src/scripts/main.js"
    },
    output:{
        filename:'main.bundle.js',
        path:path.resolve(__dirname,'dist')
    }
}

接着用webpack进行打包
webpack抛出了一个错误

Conflict: Multiple assets emit to the same filename main.bundle.js

大致的意思多个资源不能用一个文件名

这里我们可以把output的filename改一下

output:{
    filename:'[name].bundle.js',
    path:path.resolve(__dirname,'dist')
}

改成[name],这样当webpack打包的时候,会依次把entry里的模块的名称传入进来。
我们顺利打包,并得到两个bundle

[0] ./src/scripts/hello.bundle.js 60 bytes {1} [built]
[1] ./src/scripts/main.bundle.js 57 bytes {0} [built]

然后我们在index.html里依次引入hello.bundle.js和main.bundle.js

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
</head>
<body>
    <script type="text/javascript" src="main.bundle.js"></script>
    <script type="text/javascript" src="hello.bundle.js"></script>
</body>
</html>

运行起来也是成功的。

但是这种以模块名命名的bundle总会不安全,想象一个场景,团队合作的时候的模块名冲突,好像并没有什么不妥,但是你需要修改的地方就是模块名,还有Index.html里引入的地方,这样也是麻烦。

那有没有方法可以避免这种冲突呢?

2. 使用唯一标识命名

除开用模块名进行命名,webpack还允许我们使用hash 和 chunkhash进行命名。

下面是hash和chunkhash的命名方式

output:{
    filename:'[hash].bundle.js',
    path:path.resolve(__dirname,'dist')
}
output:{
    filename:'[chunkhash].bundle.js',
    path:path.resolve(__dirname,'dist')
}

那么二者有什么不同呢?

对于二者的不同,webpack官网给出了解释:

[hash] is replaced by the hash of the compilation.

译:hash代表的是compilation的hash值。

[chunkhash] is replaced by the hash of the chunk.

译:chunkhash代表的是chunk的hash值。

2.1 什么是hash

在webpack打包的过程中会产生一个compilation对象,这个对象是以文件为对比的,什么意思呢?也就是说,compilation对象代表某个版本的资源对应的编译进程。只要在打包的文件中,有一个文件发生改变,就会废弃当前的compilation对象,而重新创建一个。也就是说,只要有文件进行了变更,每次变更创建的compilation对象都不一样。

而hash是根据compilation对象来的,而不是根据文件来的,每个打包的过程中只会有一个compilation对象,那么hash的值也是唯一的,但是不幸的是,如果是用hash值做为文件名,因为hash在整个打包过程中的值是唯一的,因此会引起冲突。

从上面我们可以知道,当本次打包的源文件中,有一个文件发生了修改,那么整个hash的值就会变,也就是说,每个文件的hash值都是一样的!因此会发生冲突!

output:{
    filename:'[hash].bundle.js',
    path:path.resolve(__dirname,'dist')
}

用webpack打包,还是会抛出一个错误

Conflict: Multiple assets emit to the same filename main.bundle.js

这也证实了hash是针对compilation唯一的事实。

那么有没有是针对文件的唯一标识,来避免这种冲突呢?

答案就是chunkhash

2.2 了解chunkhash

chunkhash就是针对于文件的,每次文件修改只会修改相对于自己的chunkhash的值,不会影响到其他文件。

用chunkhash来做bundle的文件名再合适不过了。

于是我们修改webpack.config.js

output:{
    filename:'[chunkhash].bundle.js',
    path:path.resolve(__dirname,'dist')
}

编译通过~!

现在我们成功的避免了命名冲突,但是现在我们必须面临一个问题,每次文件修改后,chunkhash的值会改变,chunkhash又是和bundle的名字绑定在一起,所以我们就必须在每次文件修改完之后去引用它的地方的名字,对于程序员来说,我们需要去掉这种机械重复的劳动。

于是html-webpack-plugin登场了!!!!!

3. 什么是html-webpack-plugin

html-webpack-plugin是webpack里的插件,我们可以通过在webpack.config.js里增加plugins字段来引入这个插件。
它能帮助你自动生成引入这些bundle的html文件,从而减少你的工作量。而你只需要修改一下webpack.config.js即可以引入它。

首先我们需要做的是在这个项目里安装html-webpack-plugin依赖。

npm install --save-dev html-webpack-plugin

等待安装完毕,在webpack.config.js里将它引入

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
    entry:{
        hello:"./src/scripts/hello.js",
        main:"./src/scripts/main.js"
    },
    output:{
        filename:'[chunkhash].bundle.js',
        path:path.resolve(__dirname,'dist')
    },
    plugins:[
        new HtmlWebpackPlugin()
    ]
}

然后我们用webpack再次打包,可以看到在dist目录下已经产生了打包后的bundle以及一个index.html文件,这个index.html文件是由html-webpack-plugin创建的,而并非我们创建的,打开这个html文件如下

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>Webpack App</title>
  </head>
  <body>
  <script type="text/javascript" src="f213fbbcef9ce12fdbb3.bundle.js"></script><script type="text/javascript" src="8a5558af06376743f39d.bundle.js"></script></body>
</html>

接下来我们就可以在这个index.html里愉快的开发了。

等等!万一我在dist目录下已经有一个正在开发的index.html怎么办,用html-webpack-plugin只会让我的index.html被替换掉,这是我们不希望的结果。如果有版本管理工具还好,还能够很快的恢复,如果没有版本管理岗工具也没有备份这个就很悲剧了。

然而事实上html-webpack-plugin允许接收一些参数来适应更多的应用场景:

title: 用来生成页面的 title 元素
filename: 输出的 HTML 文件名,默认是 index.html, 也可以直接配置带有子目录。
template: 模板文件路径,支持加载器,比如 html!./index.html
inject: true | 'head' | 'body' | false  ,注入所有的资源到特定的 template 或者 templateContent 中,如果设置为 true 或者 body,所有的 javascript 资源将被放置到 body 元素的底部,'head' 将放置到 head 元素中。
favicon: 添加特定的 favicon 路径到输出的 HTML 文件中。
minify: {} | false , 传递 html-minifier 选项给 minify 输出
hash: true | false, 如果为 true, 将添加一个唯一的 webpack 编译 hash 到所有包含的脚本和 CSS 文件,对于解除 cache 很有用。
cache: true | false,如果为 true, 这是默认值,仅仅在文件修改之后才会发布文件。
showErrors: true | false, 如果为 true, 这是默认值,错误信息会写入到 HTML 页面中
chunks: 允许只添加某些块 (比如,仅仅 unit test 块)
chunksSortMode: 允许控制块在添加到页面之前的排序方式,支持的值:'none' | 'default' | {function}-default:'auto'
excludeChunks: 允许跳过某些块,(比如,跳过单元测试的块) 

这里我们使用template设置模板文件。

比如我现在有个正在开发的index.html文件,内容如下:

<!DOCTYPE html>
<html>
  <head>
    <meta charset="UTF-8">
    <title>Webpack App</title>
  </head>
  <body>
    <h1>hello world</h1>
  </body>
</html>

然后我们在html-webpack-plugin中添加template参数

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
    entry:{
        hello:"./src/scripts/hello.js",
        main:"./src/scripts/main.js"
    },
    output:{
        filename:'[chunkhash].bundle.js',
        path:path.resolve(__dirname,'dist')
    },
    plugins:[
        new HtmlWebpackPlugin({
            template:"./dist/index.html"
        })
    ]
}

这时,我们再次webpack一下,打开index.html


<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Webpack App</title>
</head>
<body>
<h1>hello world</h1>
<script type="text/javascript" src="f213fbbcef9ce12fdbb3.bundle.js"></script><script type="text/javascript" src="8a5558af06376743f39d.bundle.js"></script></body>
</html>

可以看到很顺利的进行引入。

4. 结尾

webpack的插件让webpack极具活力,拥有很强的扩展性

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

webpack 插件之Html-Webpack-Plugin 的相关文章

  • 如何避免在 webpack 生产构建中重复模块“bn.js”?

    我的应用程序使用了 webpack 4 不知何故 bn js包在生产构建中占用了大量资源 从图中可以看出 它占用了594 22KB 数据 有没有办法让1个文件bn js对于所有依赖于的包bn js 发生这种情况可能是因为您的依赖项都需要不同
  • 上传时自动缩小 CSS 和 Javascript

    有谁知道通过上传处理 脚本自动运行某些文件类型的好方法 当我将 CSS 和 Javascript 上传到服务器时 我试图自动缩小它们 在本地保留一个漂亮的 人类可读的版本 同时在服务器上保留一个缩小的版本 我目前在 Windows 上使用
  • 将弹性项目放置在网格中彼此的顶部而不包裹它们[重复]

    这个问题在这里已经有答案了 我使用 Flexbox 有以下布局 我想让 div 包含2在右侧 以及Team and Scorers应该弥补它左边的空间 Required layout 这和下面的想法是一样的2如果使用表格 div 的行跨度为
  • 本机反应:“order”不是有效的样式属性

    顺序是 Flex 中一个有用的属性 我在互联网上搜索这个 概括 CSS order 属性指定用于在 Flex 容器中布置 Flex 项目的顺序 元素按顺序值的升序排列 具有相同 order 值的元素按照它们在源代码中出现的顺序排列
  • Asp 按钮悬停和 CSS

    我有一个 asp 按钮控件 我在上面应用了一些样式 我希望鼠标悬停在该按钮上时 按钮的颜色应该发生变化或类似的情况 但我不明白为什么在 CSS 中按钮悬停功能不起作用 请帮忙 另请让我知道按钮悬停的最佳效果是什么
  • 通过列计数拆分时重复表头

    我正在 Magento 中输出产品列表 作为包装在表格中的简单列表 由于此列表可能会很长 100 个以上产品 因此我使用了来自这里的想法 https stackoverflow com questions 21001803 how to h
  • IE9支持CSS线性渐变吗?

    有了 Chrome Safari 和 Firefox webkit gradient and moz linear gradient特性 我怎样才能用 IE9 做同样的事情呢 最好的跨浏览器解决方案是 background fff back
  • 状态代码 304(Jade、Node、Express)

    我在我的 jade 文件中链接 bootstrap 和 jquery link rel stylesheet href stylesheets bootstrap css and script src javascripts jquery
  • 如何在 Bootstrap 4 中隐藏和替换 navbar-toggler-icon?

    如何隐藏和替换 Bootstrap 4 中的导航栏切换图标 现在 下面的代码只是将 X 放在汉堡菜单下方
  • 为什么 webkit 径向渐变在 Safari 中不起作用?

    这在 Chrome 中有效 但在 Safari 中无效 background webkit radial gradient center ellipse cover fdfdfd d3d3d3 我该如何修复 Safari 的问题 它甚至在
  • iOS 中输入字段显示不同大小

    我有一个带有背景和固定宽度 高度的输入字段 它在我桌面上的所有浏览器中看起来都很好 但由于某种原因 它看起来更大iPad and iPhone 我在 CSS 中尝试了一些技巧 但到目前为止没有任何效果 width 120px importa
  • 如何限制 Chrome 中的最大文本区域宽度和高度或如何禁用文本区域调整大小

    Chrome 允许通过在右下角添加文本区域来调整文本区域的大小 但有时这种移动可能会破坏页面的设计 所以我想知道如何限制该操作的最大和最小宽度 即如何完全禁用该功能和thml javascript css在页面上 您可以使用 resize
  • 从三行菜单到十字菜单的动画变换

    我有一个三行动画菜单 当您单击它时 它会切换为十字 首先 您会看到三条线变成一条线 然后切换到十字线 但我想跳过从三行到一行的步骤 我怎样才能做到这一点 这是小提琴http jsfiddle net adyocsm9 http jsfidd
  • 我可以为CSS写一个循环吗

    我有一个场景 我得到像这样生成的 ID div class containerLength div div div div div div div div div 等等 有没有办法我可以编写一些CSS来通过循环来定位它们 也许像 new i
  • 某些表格后的分页符

    我的问题是 我有一个页面 其中包含几个要打印的 html 表格 有些表有很多行 有些则没有 我想要做的是将第一个和第二个表 大表 打印在单独的页面中 其余表 小表 每页打印两个 如何在我想要的位置放置分页符 我试过 但这会在每个表格后面添加
  • SVG 图标像素对齐?

    在此图像中 左侧 黑色 垃圾桶是图标字体 它的字体大小是 16px 这使得图标在 100 的时间里看起来都很清晰 两个蓝色垃圾桶是 SVG 它们具有完全相同的标记 其中之一happened一个是像素对齐的 另一个不是 我怎样才能强制我的 S
  • React 无法识别 DOM 元素上的 `isActive` 属性 - styled-components

    我有以下内容svg我传递道具的组件 import React from react export default props gt
  • CONDITION CSS 区分 IE6 到 IE7

    我想声明一个不同于 ie6 和 ie7 的风格 但我的CSS条件被IE7识别为IE6 我用的是XP和explorer 7 这是我使用的代码
  • CSS 网格最小内容不适合内容

    我试图通过显式分配行 列和元素大小来将一些 div 放入网格中 并允许 CSS 网格使用以下 CSS 执行列和行大小调整工作 display grid grid auto columns min content 价值min content应
  • 需要一个正则表达式将 css 类添加到第一个和最后一个列表项

    更新 谢谢大家的意见 一些附加信息 它实际上只是我正在使用的一小部分标记 20 行 目的是利用正则表达式来完成工作 我还能够修改脚本 电子商务脚本 以在构建导航时插入类 我想限制我所采用的黑客数量 以便在更新到软件的最新版本时让事情变得更容

随机推荐

  • Python与Stata在数据处理上的区别

    转自 微点阅读 https www weidianyuedu com 本节旨在演示如何在 pandas 中做各种类似Stata的操作 按照惯例 我们按如下方式导入 pandas 和 NumPy 计量经济学服务中心import pandas
  • 计算机中缺少vcruntime140d.dll (附下载链接,亲自试用可用)

    vcruntime140d dll下载地址 链接 https pan baidu com s 1bSigFLZHsjVbhdGs3zykGA 提取码 l0u2 win10系统 将dll复制到 C Windows SysWOW64 目录下 再
  • DBSCAN点云聚类

    1 DBSCAN算法原理 DBSCAN是一种基于密度的聚类方法 其将点分为核心点与非核心点 后续采用类似区域增长方式进行处理 下图为DBSCAN聚类结果 可见其可以对任意类别的数据进行聚类 无需定义类别数量 DBSCAN聚类说明 DBSCA
  • 网络-----浅析IP数据报格式及TCP/UDP报文段首部格式

    IP数据报的格式 先来上张图在解释 来看看每个字段的具体含义 只讨论IPV4的情况 1 版本 占4位 指IP协议的版本 通信双方使用IP协议的版本必须一致 例 使用IPV4即填4 2 首部长度 占4位 顾名思义 这个字段就是标识了IP数据报
  • nginx 部署多个vue项目 多文件方式 conf.d/*.conf

    在nginx conf目录下新建conf d文件夹 nginx conf ngxin conf worker processes 1 events worker connections 1024 http include mime type
  • vue学习笔记(超详细)

    文章目录 一 Vue基础 认识Vue js Vue安装方式 Vue的MVVM 二 Vue基础语法 生命周期 模板语法 创建Vue options可以放什么 语法 综合 v on v for遍历数组 v model表单绑定 v model结合
  • 使用iperf测试设备的网络吞吐量

    iperf简介 iperf是一个基于Client Server的网络性能测试工具 可以测试TCP UDP和SCTP带宽质量 能够提供网络吞吐量信息 以及震动 丢包率 最大段和最大传输单元通统计信息 帮助我们测试网络性能 定位网络瓶颈 ipe
  • Python入门之print()函数

    Python利用print 函数将结果输出到标准输出设备 即显示器 上 print 函数主要有以下几个参数 1 print objects objects 0个或多个输出对象 print 拥有0个参数 输出换行 print 函数拥有一个参数
  • SynchronizedMap

    Doug Lea的 util concurrent包除了包含许多其他有用的并发构造块之外 还包含了一些主要集合类型 List和 Map的高性能的 线程安全的实现 Brian Goetz向您展示了用 ConcurrentHashMap替换 H
  • 西瓜书第一章笔记

    本章从如何挑选西瓜的经验出发 介绍了本书所涉及基本术语和概念 数据集 样本 特征 属性 特征空间 属性空间 样本空间 输入空间 特征向量 维数 学习 训练 训练数据 训练样本 假设 预测 标记 样例 标记空间 输出空间 测试 测试样本 分类
  • PAT B1014

    include
  • arcgis创建公里格网并计算格网内点的平均值最后形成马赛克式栅格图

    生成公里格网 在搜索框搜索create fishnet 点击create fishnet output feature class 输出格网的位置和名字 template extent 公里格网的范围 和什么层相同 cell size wi
  • 电脑壁纸链接

    电脑壁纸链接 一 壁纸网站 1 彼岸图网 2 H128壁纸 3 Wallhaven 4 Wallhere 二 游戏壁纸 英雄联盟 神泣 鬼泣 女神联盟2 崩坏3 三国杀 QQ飞车 QQ炫舞 阴阳师 幻塔 王者荣耀 逆战 上古王冠 永恒魔法
  • springboot jar 启动 指定端口和编码格式

    java Dfile encoding utf 8 jar xxxx jar server port 8715
  • linux网络服务[网络配置]——————配置网络IP临时[ifconfig、ip]、永久[nmtui、nmcli、网络链接配置文件]

    文章目录 1 临时设定 1 1 ifconfig命令 1 1 1 安装命令 1 1 2 查看网卡设备 1 1 3 设置IP 1 2 ip命令 1 2 1 安装命令 1 2 2 设定ip 2 永久设置ip的方法 2 1 nmtui 2 2 n
  • OSPF路由汇总和外部路由汇总

    OSPF路由汇总和外部路由汇总 AR1 ospf 1 router id 11 11 11 11 area 0 0 0 1 network 1 1 1 1 0 0 0 0 network 172 16 0 0 0 0 255 255 net
  • 可变参数函数

    c c 支持可变参数的函数 即函数的参数是不确定的 一 为什么要使用可变参数的函数 一般我们编程的时候 函数中形式参数的数目通常是确定的 在调用时要依次给出与形式参数对应的所有实际参数 但在某些情况下希望函数的参数个数可以根据需要确定 因此
  • 常见锁相关

    Linux 锁 futex 所有的futex同步操作都应该从用户空间开始 首先创建一个futex同步变量 也就是位于共享内存的一个整型计数器 当进程尝试持有锁或者要进入互斥区的时候 对futex执行 down 操作 即原子性的给futex同
  • 2023Android大厂面试题详解之内存优化,内存抖动和内存泄漏。(附面试题汇总)

    内存优化 内存抖动和内存泄漏 东方头条 详细讲解 性能优化 内存泄漏与内存抖动优化实战 详细讲解 享学课堂移动互联网系统课程 性能优化 内存泄漏与内存抖动优化实战 这道题想考察什么 内存抖动与内存泄漏是什么 会对程序造成什么影响 为什么会产
  • webpack 插件之Html-Webpack-Plugin

    webpack 插件之Html Webpack Plugin 1 为什么我们需要这个插件 先来看一个应用场景 我们自己打算搭建一个网站 这个网站有很多个页面 我们为每个页面创建一大堆的css样式 js脚本 然后尝试用webpack进行打包