构建多页面应用——模板

因为大多数人都比较喜欢,或者说倾向于用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中使用includeexclude可以是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-pluginminify选项。

这样,构建页面应用的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的源代码。

本篇文章要介绍的内容,到这里是真的结束了。当然,还有很多东西没有说完,如果需要可关注后续的文章。

构建多页面应用系列文章

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,233评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,013评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,030评论 0 241
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,827评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,221评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,542评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,814评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,513评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,225评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,497评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,998评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,342评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,986评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,055评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,812评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,560评论 2 271
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,461评论 2 266

推荐阅读更多精彩内容