因为大多数人都比较喜欢,或者说倾向于用 js 操作现有的 html 代码块,而不喜欢用 js 来生成 html 代码块,之后再来操作它。很明显的一点儿就是前者清晰明了,后者不是那么直观。
因此在开发中,我们会接触到模板后者模板引擎这样概念。我们比较常见的就是 *.html 模板,Java 开发中的 *.jsp,php 开发中的 *.php,还有用于 node.js 的 *.ejs 和 *.jade(以及它的最新版本 *.pug)。
这里,着重说一下 html 和 pug。
如何使用 html-webpack-plugin 的模板和注意事项
html-webpack-plugin 支持为生成的页面指定模板,我们可以直接使用配置项为 template,那么这个指定的 html 模板应该如何操作,或者说应该怎么操作,才能达到灵活多变的特性。
使用 webapcK 做多页面应用的构建,我们当然是希望它能够实现构建单页面应用那样的模块化处理。
我们从构建建多页面应用知道了构建多页面应用,可以实现 js 代码的模块化,从构建多页面应用——单个页面的处理,知道了构建多页面应用可以实现 css 代码的模块化。那么,构建多页面应用能实现 html 代码的模块化吗?当然可以。
在上一篇文章中,有一个 title 不能注入到生成的页面的问题,但是 html-webpack-plugin 插件可以解析 <%= htmlWebpackPlugin.options.title %> 这样的语法,它内部可以写 js 语法,同样它也解决了 title 不能注入到生成的页面的问题,但它有一个限制条件就是只能使用在被当作模板的 html 文件中,其它的代码块无法使用,所以关于 html 代码块的模块化,我们可以在模板文件上下下功夫。
使用过 jQuery 的同学都知道,我们可以使用 $(‘#container’).load(‘./pages/partial.html’) 的方法引入一个 html 代码块。而在 webapck 中,我们可以使用 require(‘./pages/commons/header.html’) 的语法引入一个 html 代码块,但是 webapck 使用 require 引入的是一个文件流,不能和 html 模板文件相融合。所以这里要引入 html-loader 来做处理,它可以将流文件转化为字符串,这样就可以在 html 模板文件中使用了。
基于 html-webpack-plugin 的模板的实际操作
首先,本文中的构建多页面应用的项目目录图:
├── src │ ├── common // 公用的模块 │ │ ├── a.js // 引用了 a.css,模块 header.css,container.css, footer.css │ │ ├── b.js // 引用了 b.css │ │ ├── c.js // 引用了 c.css │ │ ├── d.js ├── pages // html 代码块 │ ├── template.html // 模板文件 │ ├── commons │ │ ├── header.html │ │ ├── footer.html │ │ ├── container.html ├── assets // 静态资源 │ ├── 19224132.jpg // 用来做页面图标 │ ├── css │ │ ├── a.css │ │ ├── b.css │ │ ├── c.css ├── assets // 静态资源 │ ├── 19224132.jpg // 用来做页面图标 │ ├── css │ │ ├── a.css │ │ ├── b.css │ │ ├── c.css │ │ ├── main.css │ │ ├── abutus.css │ │ ├── footer.css │ │ ├── container.css │ │ ├── header.css │ ├── uttils // 工具 │ │ ├── load.js // 工具代码 load.js │ ├── index.js // 主模块 index.js (包含 a.js, b.js, c.js, d.js),引用了 main.css │ ├── aboutUs.js // 主模块 aboutus.js (包含 a.js, b.js),引用了 main.css, aboutus.css │ ├── contactUs.js // 主模块 contactus.js (包含 a.js, c.js),引用了 main.css ├── webpack.config.js // css js 和图片资源 ├── package.json ├── yarn.lock
新增了 pages 目录,它里面包含了 html-webpack-plugin 所需的模板文件和组成模板的各个模块文件。
根据上文的分析,以及讲述需要,我们定义了一个公用的模板文件 template.html,代码如下:
<!DOCTYPE html>
<html lang=”en”>
<head>
<meta charset=”UTF-8″>
<meta name=”viewport” content=”width=device-width, initial-scale=1.0″>
<meta http-equiv=”X-UA-Compatible” content=”ie=edge”>
<title><%= htmlWebpackPlugin.options.title %></title>
</head>
<body>
<!– header –>
<!– <%= require(‘html-loader!./commons/header.html’) %> –>
<%= require(‘./commons/header.html’) %>
<!– container –>
<!– <%= require(‘html-loader!./commons/container.html’) %> –>
<%= require(‘./commons/container.html’) %>
<!– footer –>
<!– <%= require(‘html-loader!./commons/footer.html’) %> –>
<%= require(‘./commons/footer.html’) %>
</body>
</html>
注:这里可能有的人会有个疑惑。因为熟悉构建单页面应用的人都将 html-loader 放到 webapck.config.js 文件中,这样可以一次配置,终身受用,如果你也像构建单页面应用那样操作的话,你需要小心再小心,因为你不加控制的话,html-loader 也会处理 template.html,再加之 <%= htmlWebpackPlugin.options.title %> 是 html-webpack-plugin 插件的独有语法,这样在 webapck 编译的过程中,因为 html-loader 先执行,所以会将它转化为字符串,而 html-webpack-plugin 后执行,所以,这样的情况下,webpack 生成的 html 页面不是你所需要的。解决方法也很简单你,只需要使用 include 选项即可 (在 webapck 中使用 include 和 exclude 可以是 loader 的处理更精确,加开快编译的速度)。
当然,根据世界开发需要,我们可根据页面的不同设计效果和组成页面的不同模块来定义不同的 html 模板。
而对于哪些组成 html 模板的 html 模块,我们可以像写普通的 html 代码块那样,如:header.html,它的代码如下:
<div class=”header”>
<ul>
<li><a href=”index.html”> 首页 </a></li>
<li><a href=”aboutus.html”> 关于我们 </a></li>
<li><a href=”contactus.html”> 联系我们 </a></li>
</ul>
</div>
如果你要对生成的 html 页面压缩,可以使用 html-webpack-plugin 的 minify 选项。
这样,构建页面应用的 js、css、html 代码的模块化就都实现了。
源代码可参考 webpack4.x multi-page
文章到这里,基本算是完成了这一篇文章的目的。但是如果你想对 html 代码进行更加细粒度的处理,可以考虑 ejs 或者 pug。正如本文开始说的那样,下面就只简单的介绍 pug 的使用。
用 pug 对 html 代码进行细粒度的操作
这里,需要使用到的是 pug-loader,它的作用和 html-loader 类似,只不过它有自己的语法,要经过从 pug 的语法到 html 的转换过程。但是它有更灵活的语法,可以让我们的页面代码更简洁。
有些内容只用语言可能太空洞,还是用代码还解释。首先,模板的代码:
doctype html
html(lang=”en”)
head
meta(charset=”UTF-8″)
meta(name=”viewport” content=”width=device-width, initial-scale=1.0″)
meta(http-equiv=”X-UA-Compatible” content=”ie=edge”)
title= htmlWebpackPlugin.options.title
body
// header
include ./commons/header.pug
// container
include ./commons/container.pug
// footer
include ./commons/footer.pug
注:因为这里使用了 pug 的语法,所以要使用 pug 依赖包,它实现的是 pug 语法到 html 的转换,而 pug-loader 只是起到了一个加载解析的作用,所以使用前,我们要执行如下的安装命令:
yarn add -D pug pug-loader
因为 pug 不仅可以使用包含,还可以使用集成,扩展,迭代和混合的特性,可以让我们随心所欲的对 html 实现模块化,所以深受开发者的喜爱。它们的具体使用可参考 pug 官方文档。
具体示例可参考 webpack3.x multi-page 的源代码。
本篇文章要介绍的内容,到这里是真的结束了。当然,还有很多东西没有说完,如果需要可关注后续的文章。
构建多页面应用系列文章
webpack 构建多页面应用——初探
构建多页面应用——单个页面的处理
构建多页面应用——模板