安装
使用npm安装pug
$ npm install pug
但运行pug命令时,提示pug命令未找到
![](https://i-blog.csdnimg.cn/blog_migrate/79e98bf7e4f29425447baab09d3584ba.png)
这时,需要安装pug命令行工具pug-cli
[注意]一定要全局安装pug-cli,否则无法正常编译
npm install pug-cli -g
再运行pug命令时,正常执行
![](https://i-blog.csdnimg.cn/blog_migrate/36cd1d8c5c117dec3e00fc22024673f7.png)
命令行
在学习pug基础语法之前,首先要了解pug的命令行的使用
【基础编译】
将如下内容输入文件中,并命名为index.pug
html head title aaa body
在命令行中敲入pug index.pug即可实现基础编译
![](https://i-blog.csdnimg.cn/blog_migrate/7cd2ab5f1d459bd046f4d328b7f6cb80.png)
在当前目录下生成一个index.html,是index.pug编译后的结果
![](https://i-blog.csdnimg.cn/blog_migrate/7f177020bbd00d3d0a8c1f8916eda310.png)
【sublime两列设置】
但是,这样查看并不方便。下面将sublime设置为两列放置,将index.pug和index.html分别放置在左右两列,方便查看
![](https://i-blog.csdnimg.cn/blog_migrate/6afd39b474433f387f5736a974b4373d.png)
【自动编译】
使用pug -w功能可以实现自动编译
![](https://i-blog.csdnimg.cn/blog_migrate/678910ae8ca35cd057b780de47f5bce4.png)
更改index.pug文件并保存后,index.html文件会实时更新为最新的编译的文件
![](https://i-blog.csdnimg.cn/blog_migrate/74522063a349f3dac204cd242dd03f82.png)
【标准版HTML】
如上所示,默认地,pug编译出的HTML文件是压缩版的。如果要编译标准版的HTML文件,需要设置-P参数
pug index.html -P
【路径设置】
如果并不希望在当前目录下输入编译后的HTML文件,而是有自定义目录的需求,则需要设置-o参数
如下设置,index.html将输入到a目录下面,如果a目录不存在,则会新建a目录
pug index.pug -o a
【重命名】
默认地,编译后的HTML与pug文件同名。如果需要重命名,则可以进行如下设置
通过如下设置,可以同时设置路径和名称
[注意]这里的路径必须提前建立好,否则不会成功
pug <xx.pug> <xx/xx.html>
最终,test.html文件被保存到templates目录下
![](https://i-blog.csdnimg.cn/blog_migrate/49305a81f6439970197bcfdb6e66a8c5.png)
【批量编译】
假设,编译href目录下所有的pug文件
![](https://i-blog.csdnimg.cn/blog_migrate/f455373664b09f56fc59bf48cfd97450.png)
结构语法
下面介绍关于结构的基础语法
标签
【树状】
在默认情况下,在每行文本的开头(或者紧跟白字符的部分)书写这个 HTML 标签的名称。使用缩进来表示标签间的嵌套关系,这样可以构建一个 HTML 代码的树状结构
ul li Item A li Item B li Item C
![](https://i-blog.csdnimg.cn/blog_migrate/a9fcac4d73cee158d18bd94aeb42b2dc.png)
【内联】
为了节省空间, Pug 嵌套标签提供了一种内联式语法
a: img
![](https://i-blog.csdnimg.cn/blog_migrate/f6bce23dd006e8bb5f19f1cd8fc41a38.png)
【自闭合】
Pug知道哪些元素是自闭合的,也可以通过在标签后加上 /
来明确声明此标签是自闭合的
img input img/ input/
![](https://i-blog.csdnimg.cn/blog_migrate/14d5a338280aec322b8d8b1c9bf91229.png)
【DOCTYPE】
HTML5的DOCTYPE书写如下
doctype html
![](https://i-blog.csdnimg.cn/blog_migrate/e193465fe15cdc77eb52ced7a5f2886b.png)
也可以自定义一个 doctype 字面值
doctype html PUBLIC "-//W3C//DTD XHTML Basic 1.1//EN"
![](https://i-blog.csdnimg.cn/blog_migrate/09625d851a69b4ccbc4b136e5472df17.png)
内容
Pug 提供了三种常用的方式来放置内容
【管道文本】
这是最简单的向模板添加纯文本的方法。只需要在每行前面加一个 |
字符,这个字符在类 Unix 系统下常用作“管道”功能,因此得名
| 纯文本当然也可以包括 <strong>HTML</strong> 内容。 p | 但它必须单独起一行。
![](https://i-blog.csdnimg.cn/blog_migrate/d3e78fe521d9b1cbedccc49b485280d7.png)
【标签内文本】
这实际上是最常见的情况,文本只需要和标签名隔开一个空格即可
p 纯文本当然也可以包括 <strong>HTML</strong> 内容。
![](https://i-blog.csdnimg.cn/blog_migrate/81092e5406e2aee4fc740823bb206005.png)
【嵌入大段文本】
有时可能想要写一个大段文本块。比如嵌入脚本或者样式。只需在标签后面接一个 .
即可
[注意]不要有空格
script. if (usingPug) console.log('这是明智的选择。') else console.log('请用 Pug。')
![](https://i-blog.csdnimg.cn/blog_migrate/4c52150af632c477a74b2a3c02c4192e.png)
属性
标签属性和 HTML 语法非常相似,它们的值就是普通的 JavaScript 表达式。可以用逗号作为属性分隔符,也可以不加逗号
a(href='baidu.com') 百度 = '\n' a(class='button' href='baidu.com') 百度 = '\n' a(class='button', href='baidu.com') 百度
![](https://i-blog.csdnimg.cn/blog_migrate/54123efa3f1d505201e68d8f77a56339.png)
【多行属性】
如果有很多属性,可以把它们分几行写
input( type='checkbox' name='agreement' checked )
![](https://i-blog.csdnimg.cn/blog_migrate/c1baa53c24cefa89460ad91a477d2a34.png)
【长属性】
如果有一个很长的属性,并且JavaScript运行时引擎支持ES2015模板字符串,可以使用它来写属性值
input(data-json=` { "非常": "长的", "数据": true } `)
![](https://i-blog.csdnimg.cn/blog_migrate/03cfbcba5d83d41b9a22898edf092767.png)
【特殊字符】
如果属性名称中含有某些奇怪的字符,可能会与 JavaScript 语法产生冲突的话,可以将它们使用 ""
或者 ''
括起来。还可以使用逗号来分割不同的属性
div(class='div-class', (click)='play()') div(class='div-class' '(click)'='play()')
![](https://i-blog.csdnimg.cn/blog_migrate/d03f9550fde8e7be3b7eab916b6411cc.png)
【转义属性】
默认情况下,所有的属性都经过转义(即把特殊字符转换成转义序列)来防止诸如跨站脚本攻击之类的攻击方式。如果要使用特殊符号,需要使用 !=
而不是 =
[注意]未经转义的缓存代码十分危险。必须正确处理和过滤用户的输入来避免跨站脚本攻击
div(escaped="<code>") div(unescaped!="<code>")
![](https://i-blog.csdnimg.cn/blog_migrate/610210231c5b3480d745cedb4ee1bedf.png)
【布尔值】
在Pug中,布尔值属性是经过映射的,这样布尔值(true
和false)
就能接受了。没有指定值时,默认是true
input(type='checkbox' checked) = '\n' input(type='checkbox' checked=true) = '\n' input(type='checkbox' checked=false) = '\n' input(type='checkbox' checked=true.toString())
![](https://i-blog.csdnimg.cn/blog_migrate/14ddb11b4ed3449c27e55379c94a4758.png)
【行内样式】
style
(样式)属性可以是一个字符串(就像其他普通的属性一样)还可以是一个对象
a(style={color: 'red', background: 'green'})
![](https://i-blog.csdnimg.cn/blog_migrate/1cfc64426c7a6ad6958eb8e5e9296b34.png)
【类和ID】
类可以使用 .classname
语法来定义,ID 可以使用 #idname
语法来定义
考虑到使用 div
作为标签名这种行为实在是太常见了,所以如果省略掉标签名称的话,它就是默认值
a.button .content =”\n” a#main-link
![](https://i-blog.csdnimg.cn/blog_migrate/343be4342739c897f87f9de89777acab.png)
标签嵌入
标签支持一种标签嵌入的写法,形式如下
#[标签名(标签属性) 标签内容]
对于内联标签来说,这种写法比较简单
p. 这是一个很长很长而且还很无聊的段落,还没有结束,是的,非常非常地长。 突然出现了一个 #[strong 充满力量感的单词],这确实让人难以 #[em 忽视]。
![](https://i-blog.csdnimg.cn/blog_migrate/81383e3d6e562434242daf93836f8a5d.png)
【空格调整】
Pug 默认会去除一个标签前后的所有空格,而标签嵌入功能可以在需要嵌入的位置上处理前后空格
p | 如果我不用嵌入功能来书写,一些标签比如 strong strong | 和 em em | 可能会产生意外的结果。 p. 如果用了嵌入,在 #[strong strong] 和 #[em em] 旁的空格就会让我舒服多了。
![](https://i-blog.csdnimg.cn/blog_migrate/f1f38a9c5463e3246217f88d877b9120.png)
注释
【单行注释】
单行注释和 JavaScript 类似,但是必须独立一行
// 一些内容 p foo p bar
![](https://i-blog.csdnimg.cn/blog_migrate/2d0ac668cc3d4080a6e46a7e271454a4.png)
【不输出注释】
只需要加上一个横杠,就可以使用不输出注释
//- 这行不会出现在结果里 p foo p bar
![](https://i-blog.csdnimg.cn/blog_migrate/3fd6bc29a2cb241604d71d156bde1024.png)
【块注释】
body // 随便写多少字 都没关系。
![](https://i-blog.csdnimg.cn/blog_migrate/b877a75ad87bb7079856633daa5f4055.png)
【条件注释】
Pug 没有特殊的语法来表示条件注释(conditional comments)。不过因为所有以 <
开头的行都会被当作纯文本,因此直接写一个 HTML 风格的条件注释也是没问题的
<!--[if IE 8]> <html lang="en" class="lt-ie9"> <![endif]--> <!--[if gt IE 8]><!--> <html lang="en"> <!--<![endif]-->
![](https://i-blog.csdnimg.cn/blog_migrate/5b29ffe188923d0e29401c0097fb86ba.png)
逻辑语法
以下是关于模板逻辑的语法
JS代码
【不输出的代码】
用 -
开始一段不直接进行输出的代码
- for (var x = 0; x < 3; x++) li item
![](https://i-blog.csdnimg.cn/blog_migrate/e96e56c8275d30368a08e327d0768135.png)
【输出的代码】
用=
开始一段带有输出的代码,它应该是可以被求值的一个JavaScript表达式。为安全起见,它将被HTML转义
p = '这个代码被 <转义> 了!' p= '这个代码被 <转义> 了!'
![](https://i-blog.csdnimg.cn/blog_migrate/12710028caa3e85cf6dd303f30a50224.png)
【不转义的输出代码】
用 !=
开始一段不转义的,带有输出的代码。这将不会做任何转义,所以用于执行用户的输入将会不安全
p != '这段文字 <strong>没有</strong> 被转义!' p!= '这段文字' + ' <strong>没有</strong> 被转义!'
![](https://i-blog.csdnimg.cn/blog_migrate/43f18023b277b6459ce7256887e7832a.png)
变量
【内容变量】
使用=或#{}来进行变量的真实值替换
- var title = "On Dogs: Man's Best Friend"; - var author = "enlore"; - var theGreat = "<span>转义!</span>"; h1= title p #{author} 笔下源于真情的创作。 p 这是安全的:#{theGreat}
![](https://i-blog.csdnimg.cn/blog_migrate/63fbd9c346d7ef07015659ba542d8eed.png)
在 #{
和 }
里面的代码也会被求值、转义,并最终嵌入到模板的渲染输出中
- var msg = "not my inside voice"; p This is #{msg.toUpperCase()}
![](https://i-blog.csdnimg.cn/blog_migrate/b87597c912ccdd085e3943844d8da65c.png)
Pug 足够聪明来分辨到底哪里才是嵌入表达式的结束,所以不用担心表达式中有 }
,也不需要额外的转义
p 不要转义 #{'}'}!
![](https://i-blog.csdnimg.cn/blog_migrate/64e36ed5a227da0b2b241ad4362bba27.png)
如果需要表示一个 #{
文本,可以转义它,也可以用嵌入功能来生成
p Escaping works with \#{interpolation} p Interpolation works with #{'#{interpolation}'} too!
![](https://i-blog.csdnimg.cn/blog_migrate/a51d932c80d979b7da6f0006d55e2d92.png)
使用!{}嵌入没有转义的文本进入模板中
- var riskyBusiness = "<em>我希望通过外籍教师 Peter 找一位英语笔友。</em>"; .quote p 李华:!{riskyBusiness}
![](https://i-blog.csdnimg.cn/blog_migrate/287c277004216159524eb31342a9e11c.png)
[注意]如果直接使用用户提供的数据,未进行转义的内容可能会带来安全风险
【属性变量】
如果要在属性当中使用变量的话,需要进行如下操作
- var url = 'pug-test.html'; a(href='/' + url) 链接 = '\n' - url = 'https://example.com/' a(href=url) 另一个链接
![](https://i-blog.csdnimg.cn/blog_migrate/082d0e130ece71e6858d2253066dd69c.png)
如果JavaScript运行时支持 ECMAScript 2015 模板字符串,还可以使用下列方式来简化属性值
- var btnType = 'info' - var btnSize = 'lg' button(type='button' class='btn btn-' + btnType + ' btn-' + btnSize) = '\n' button(type='button' class=`btn btn-${btnType} btn-${btnSize}`)
![](https://i-blog.csdnimg.cn/blog_migrate/8c45825923786af8ac31ea17a25bb5a0.png)
&attributes
语法可以将一个对象转化为一个元素的属性列表
div#foo(data-bar="foo")&attributes({'data-foo': 'bar'}) - var attributes = {}; - attributes.class = 'baz'; div#foo(data-bar="foo")&attributes(attributes)
![](https://i-blog.csdnimg.cn/blog_migrate/bca4431b84e66ed80dfe7fc5d57a23a0.png)
【变量来源】
变量来源有三种,分别是pug文件内部、命令行参数和外部JSON文件
1、pug文件内部
![](https://i-blog.csdnimg.cn/blog_migrate/78f8daf45c999721d250939fc386c85e.png)
2、命令行参数
使用–obj参数,就可以跟随一个对象形式的参数
![](https://i-blog.csdnimg.cn/blog_migrate/5b2697ac29e3ee6c6b37aebc28de4264.png)
![](https://i-blog.csdnimg.cn/blog_migrate/ff33097389b5b7d0a98476342b20fdad.png)
3、外部JSON文件
使用-O,跟随一个JSON文件的路径即可
![](https://i-blog.csdnimg.cn/blog_migrate/3f8226da6b00700733fc43f31de3452f.png)
![](https://i-blog.csdnimg.cn/blog_migrate/660fcf12e735a39a7efdc328c94ee22a.png)
这三种方式,pug文件内部的变量优先级最多,而外部JSON文件和命令行传参优先级相同
如下所示,外部JSON文件和命令行传参两种方式都存在,由于–obj写在-w后面,最终以命令行传参为准
![](https://i-blog.csdnimg.cn/blog_migrate/d5c6761d94690679edef8b57e4ee5b2c.png)
条件
Pug 的条件判断的一般形式的括号是可选的,所以可以省略掉开头的 -
,效果完全相同。类似一个常规的 JavaScript 语法形式
【if else】
- var user = { description: 'foo bar baz' } - var authorised = false
![](https://i-blog.csdnimg.cn/blog_migrate/0b57244158861fab808b571caf165723.png)
Pug 同样也提供了它的反义版本 unless
unless user.isAnonymous p 您已经以 #{user.name} 的身份登录。
![](https://i-blog.csdnimg.cn/blog_migrate/0be12ac4384707354596e108ff52cc79.png)
【switch】
case
是 JavaScript 的 switch
指令的缩写,并且它接受如下的形式
- var friends = 10 case friends when 0 p 您没有朋友 when 1 p 您有一个朋友 default p 您有 #{friends} 个朋友
![](https://i-blog.csdnimg.cn/blog_migrate/ae767734f71f36c068133b53387c6828.png)
在某些情况下,如果不想输出任何东西的话,可以明确地加上一个原生的 break
语句
- var friends = 0 case friends when 0 - break when 1 p 您的朋友很少 default p 您有 #{friends} 个朋友
![](https://i-blog.csdnimg.cn/blog_migrate/a2980c2806ae50c88ce2ffe88b33df47.png)
也可以使用块展开的语法
- var friends = 1 case friends when 0: p 您没有朋友 when 1: p 您有一个朋友 default: p 您有 #{friends} 个朋友
![](https://i-blog.csdnimg.cn/blog_migrate/cf2b740bf9a936bdd109aed3e6730c86.png)
循环
Pug 目前支持两种主要的迭代方式: each
和 while
【each】
这是 Pug 的首选迭代方式
ul each val in [1, 2, 3, 4, 5] li= val
![](https://i-blog.csdnimg.cn/blog_migrate/c1fbbcb8f946275d6abd3ddae8b7dda9.png)
可以在迭代时获得索引值
ul each val, index in ['〇', '一', '二'] li= index + ': ' + val
![](https://i-blog.csdnimg.cn/blog_migrate/cc0d8216852df35b66fb4a356dcfa4c7.png)
能够迭代对象中的键值
ul each val, index in {1:'一',2:'二',3:'三'} li= index + ': ' + val
![](https://i-blog.csdnimg.cn/blog_migrate/f28e7033bb6b6d06579e915fce52d33f.png)
用于迭代的对象或数组仅仅是个 JavaScript 表达式,因此它可以是变量、函数调用的结果,又或者其他
- var values = []; ul each val in values.length ? values : ['没有内容'] li= val
![](https://i-blog.csdnimg.cn/blog_migrate/2b90cf72d0c8555b53d02a6bc01e7f97.png)
还能添加一个 else
块,这个语句块将会在数组与对象没有可供迭代的值时被执行
- var values = []; ul each val in values li= val else li 没有内容
![](https://i-blog.csdnimg.cn/blog_migrate/5a3c9380b4051d3955ff9a136acaea88.png)
[注意]也可以使用 for
作为 each
的别称
【while】
也可以使用 while
来创建一个循环
- var n = 0; ul while n < 4 li= n++
![](https://i-blog.csdnimg.cn/blog_migrate/c489d470c806a9037e030a2c0de009fe.png)
混入
混入是一种允许在 Pug 中重复使用一整个代码块的方法
//- 定义 mixin list ul li foo li bar li baz //- 使用 +list +list
![](https://i-blog.csdnimg.cn/blog_migrate/5e8cd72fd502205ed0e8d0e6ae513ea9.png)
混入可以被编译成函数形式,并传递一些参数
mixin pet(name) li.pet= name ul +pet('猫') +pet('狗') +pet('猪')
![](https://i-blog.csdnimg.cn/blog_migrate/2cbaf39e9f40ac8c254700819d3d2365.png)
混入也可以把一整个代码块像内容一样传递进来
mixin article(title) .article .article-wrapper h1= title if block block else p 没有提供任何内容。 +article('Hello world') +article('Hello world') p 这是我 p 随便写的文章
![](https://i-blog.csdnimg.cn/blog_migrate/dc51b40653a5a1f6b44fdf0095ee7855.png)
混入也可以隐式地,从“标签属性”得到一个参数 attributes
![](https://i-blog.csdnimg.cn/blog_migrate/ba5bb87fecf22fe75d883cb6335bcebc.png)
也可以直接用 &attributes
方法来传递 attributes
参数
mixin link(href, name) a(class!=attributes.class href=href)= name +link('/foo', 'foo')(class="btn")
![](https://i-blog.csdnimg.cn/blog_migrate/c8e02100c88fa1c0d41fdce62c0c121b.png)
[注意]+link(class="btn")
等价于 +link()(class="btn")
,因为 Pug 会判断括号内的内容是属性还是参数。但最好使用后面的写法,明确地传递空的参数,确保第一对括号内始终都是参数列表
可以用剩余参数(rest arguments)语法来表示参数列表最后传入若干个长度不定的参数
mixin list(id, ...items) ul(id=id) each item in items li= item +list('my-list', 1, 2, 3, 4)
![](https://i-blog.csdnimg.cn/blog_migrate/34533f1c7a52cc5a7f2853c831beb483.png)
文件包含
包含(include)功能允许把另外的文件内容插入进来
//- index.pug doctype html html include includes/head.pug body h1 我的网站 p 欢迎来到我这简陋得不能再简陋的网站。 include includes/foot.pug
//- includes/head.pug head title 我的网站 script(src='/javascripts/jquery.js') script(src='/javascripts/app.js')
//- includes/foot.pug footer#footer p Copyright (c) foobar
![](https://i-blog.csdnimg.cn/blog_migrate/93a9b91522c987d7bdf2b9acec6b5f59.png)
被包含的如果不是 Pug 文件,那么就只会当作文本内容来引入
//- index.pug doctype html html head style include style.css body h1 我的网站 p 欢迎来到我这简陋得不能再简陋的网站。 script include script.js
/* style.css */ h1 { color: red; }
// script.js console.log('真了不起!');
![](https://i-blog.csdnimg.cn/blog_migrate/12462bd3f70fbeb00e7cad98dd5d81a3.png)
文件继承
【覆盖】
Pug 支持使用 block
和 extends
关键字进行模板的继承。一个称之为“块”(block)的代码块,可以被子模板覆盖、替换。这个过程是递归的。
Pug 的块可以提供一份默认内容,当然这是可选的
//- layout.pug html head
meta(charset="UTF-8") title 我的站点 - #{title} block scripts script(src='/jquery.js') body block content block foot #footer p 一些页脚的内容
现在来扩展这个布局:只需要简单地创建一个新文件,并如下所示用一句 extends
来指出这个被继承的模板的路径。现在可以定义若干个新的块来覆盖父模板里对应的“父块”。值得注意的是,因为这里的 foot
块 没有 被重定义,所以会依然输出“一些页脚的内容”
//- pet.pug p= petName
//- page-a.pug extends layout.pug block scripts script(src='/jquery.js') script(src='/pets.js') block content h1= title - var pets = ['猫', '狗'] each petName in pets include pet.pug
![](https://i-blog.csdnimg.cn/blog_migrate/9004a5a19d079be3b2c02efc7c3143cc.png)
同样,也可以覆盖一个块并在其中提供一些新的块。如下所示,content
块现在暴露出两个新的块 sidebar
和 primary
用来被扩展。当然,它的子模板也可以把整个 content
给覆盖掉
//- sub-layout.pug extends layout.pug block content .sidebar block sidebar p 什么都没有 .primary block primary p 什么都没有
//- page-b.pug extends sub-layout.pug block content .sidebar block sidebar p 什么都没有 .primary block primary p 什么都没有
![](https://i-blog.csdnimg.cn/blog_migrate/12bfe25f51795990b28d82da34fccb2e.png)
【扩展】
Pug 允许去替换(默认的行为)、prepend
(向头部添加内容),或者 append
(向尾部添加内容)一个块。 假设有一份默认的脚本要放在 head
块中,而且希望将它应用到 每一个页面,可以进行如下操作
//- layout.pug html head block head script(src='/vendor/jquery.js') script(src='/vendor/caustic.js') body block content
现在假设有一个页面,那是一个 JavaScript 编写的游戏。希望把一些游戏相关的脚本也像默认的那些脚本一样放进去,那么只要简单地 append
这个块:
//- page.pug extends layout.pug block prepend head script(src='/vendor/three.js') block append head script(src='/game.js')
当使用 block append
或者 block prepend
时,block
关键字是可省略的:
//- page.pug extends layout.pug prepend head script(src='/vendor/three.js') append head script(src='/game.js')
![](https://i-blog.csdnimg.cn/blog_migrate/0653357ac6e560c8b83c037292ecdb0f.png)
简易模板
//- index.pug doctype html html head meta(charset="UTF-8") title= documentTitle each val in srcStyles link(href= baseStyle +'/' + val) body header.hd nav.hd-navbar.m-navbar.m-navbar_primary .hd-navbar-tel 联系方式: #{tel} ul.hd-navbar-nav each val in mainNavItem li.Hnn-item.m-btn.m-btn_info a(href="#")= val section.main h1.main-title 我的文档 p.main-content. 这是一个很长很长而且还很无聊的段落,还没有结束,是的,非常非常地长。 突然出现了一个 #[strong 充满力量感的单词],这确实让人难以 #[em 忽视]。 footer.ft p Copyright (c) 小火柴的蓝色理想 each val in srcScripts script(src=baseScript + '/' + val)
//- data.json { "documentTitle":"测试文档", "tel":"400-888-8888", "mainNavItem":['登录','注册','关于','帮助'], "baseStyle":'style', "srcStyles":['bootstrap.css','main.css'], "baseScript":'/js', "srcScripts":['jquery.js','app.js'] }
![](https://i-blog.csdnimg.cn/blog_migrate/76bc74b1a1855e136c913625e58f93e0.png)
![](https://i-blog.csdnimg.cn/blog_migrate/f588c28c6c3b3435caa3d10c7c39ed7b.png)
转自:https://www.cnblogs.com/xiaohuochai/p/7222227.html#anchor6‘>