Pug 是一个健壮的、优雅的、功能丰富的node.js模板引擎。
Pug 原名不叫 Pug,而是大名鼎鼎的 jade,因为商标的原因改名 Pug,但是语法仍然没变。
(一)为什么要用 Pug
在开发官网的项目中,由于需求简单,且有大量可复用代码存在,让人不由自主地想对其进行组件化。然而由于 React 的 SEO 问题,只能选用其他的技术栈,Pug 就成了首选。
Pug 的优点很多,在官网项目里最实用的就是模板继承 Inheritance和包含 Include,这两个特性其实已经实现了我们想要的组件化的功能。
(二)Webpack 配置
由于需要输出
HTML
,所以需要安装html-webpack-plugin
1
$ npm i -D html-webpack-plugin
然后我们需要安装一下
pug
和pug-html-loader
1
$ npm i -D pug html-loader pug-html-loader
接下来就可以进入
webpack.config.js
配置处理.pug
文件的 loader 啦1
2
3
4
5
6
7
8...
module: {
rules: [{
test: /\.pug$/,
use: ['html-loader','pug-html-loader']
}]
},
...
(三)基础语法知识
Pug 的语法很简单,有HTML
和JS
x基础的话读官方文档半天就能上手,需要注意的是 Pug 用缩进来代表层级关系,这样的好处就是避免嵌套过多时由于闭合问题报错,所以最好把编辑器 Tab 调成 2。
类名和ID名
1 | a.button |
编译后:1
2<a class="button"></a>
<a class="button"></a>
属性
属性可以用()
包裹起来,属性之间用逗号隔开1
a(href="google.com",title="google")
编译后1
<a href="google.com" title="google"></a>
文本内容
单行文本1
a(href="google.com",title="google") Hello World
多行文本1
2
3
4
5p.
asdfasdfa
asdfasd
adsfasd
asdfasdfa
JavaScript
在 Pug 中写JS
代码需要在行首加一个-
,但是在条件判断时由于括号是可选的,所以可以省略行首的-
,例如:1
2
3
4
5
6
7
8
9
10
11
12
13
14- var user = { description: 'foo bar baz' }
- var authorised = false
#user
if user.description
h2.green 描述
p.description= user.description
else if authorised
h2.blue 描述
p.description.
用户没有添加描述。
不写点什么吗……
else
h2.red 描述
p.description 用户没有描述
Mixin
Mixin
,顾名思义,就是重复代码块,使用也很简单:1
2
3
4
5
6//- 定义
mixin pet(name)
li.pet = name
//- 使用
+pet('cat')
+pet('dog')
(五)Include 和 Inheritance
Include
包含(include)功能允许我们把另外的文件内容插入进来
比如我们现在有一个.pug
文件1
2
3
4//- includes/head.pug
head
title 我的网站
script(src='/javascripts/app.js')
那么我们就可以在另一个文件里引用它,是不是基本实现了我们组件化的需求呢1
2
3
4
5
6//- index.pug
doctype html
html
include includes/head.pug
body
h1 欢迎我的网站
Inheritance
Pug 支持使用 block 和 extends 关键字进行模板的继承。一个称之为“块”(block)的代码块,可以被子模板覆盖、替换
比如我们创建了一个默认布局1
2
3
4
5
6
7
8
9
10
11//- layout.pug
html
head
title 我的站点 - #{title}
block scripts
script(src='/jquery.js')
body
block content
block foot
#footer
p 一些页脚的内容
现在我们可以引用这个布局1
2
3
4
5
6
7
8
9
10
11extends layout.pug
block scripts
script(src='/jquery.js')
script(src='/pets.js')
block content
h1= title
- var pets = ['cat', 'dog']
each petName in pets
include pet.pug
(四)引入json
文件遇到的问题
Pug 的 include
机制是:包含(include)功能允许您把另外的文件内容插入进来,但是被包含的如果不是 Pug 文件,那么就只会当作文本内容来引入。
这样的话我们引入json
文件就很困难,最后的解决办法是建立一个与需要引入json
文件的pug
文件同名的js
文件,1
2
3exports.array = [{
......
}]
然后在webpack.config.js
中寻找和.pug
文件同名的.js
文件1
2
3
4//const pages = glob.sync('./your/pages/path/*.pug');
pages.map((page)=>{
let dataFilePath = page.replace(/\.pug$/, '.js');
}
我们还需要配置一下相应的loader
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17module: {
rules: [{
test: /\.(pug|html)/,
use: [{
loader: "pug-html-loader",
options: {
data: {
js(){
if(!require('fs').existsSync(dataFilePath)) return {};
delete require.cache[require.resolve(dataFilePath)];
return require(dataFilePath);
}
}
},
}]
}]
}
最后在模板文件的head
里加上就大功告成啦~1
- data = js()