-
Notifications
You must be signed in to change notification settings - Fork 0
/
index.html
512 lines (370 loc) · 44.9 KB
/
index.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width">
<meta name="theme-color" content="#222" media="(prefers-color-scheme: light)">
<meta name="theme-color" content="#222" media="(prefers-color-scheme: dark)">
<meta name="generator" content="Hexo 5.4.0">
<link rel="apple-touch-icon" sizes="180x180" href="/images/favicon%20(1).ico">
<link rel="icon" type="image/png" sizes="32x32" href="/images/favicon%20(1).ico">
<link rel="icon" type="image/png" sizes="16x16" href="/images/favicon%20(1).ico">
<link rel="mask-icon" href="/images/logo.svg" color="#222">
<link rel="stylesheet" href="/css/main.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@fortawesome/[email protected]/css/all.min.css" integrity="sha256-mUZM63G8m73Mcidfrv5E+Y61y7a12O5mW4ezU3bxqW4=" crossorigin="anonymous">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/animate.min.css" integrity="sha256-PR7ttpcvz8qrF57fur/yAx1qXMFJeJFiA6pSzWi0OIE=" crossorigin="anonymous">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/[email protected]/themes/pink/pace-theme-bounce.css">
<script src="https://cdn.jsdelivr.net/npm/[email protected]/pace.min.js" integrity="sha256-gqd7YTjg/BtfqWSwsJOvndl0Bxc8gFImLEkXQT8+qj0=" crossorigin="anonymous"></script>
<script class="next-config" data-name="main" type="application/json">{"hostname":"example.com","root":"/","images":"/images","scheme":"Pisces","darkmode":true,"version":"8.9.0","exturl":false,"sidebar":{"position":"left","display":"post","padding":18,"offset":12},"copycode":false,"bookmark":{"enable":false,"color":"#222","save":"auto"},"mediumzoom":false,"lazyload":false,"pangu":false,"comments":{"style":"tabs","active":null,"storage":true,"lazyload":false,"nav":null},"stickytabs":false,"motion":{"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"fadeInDown","post_body":"fadeInDown","coll_header":"fadeInLeft","sidebar":"fadeInUp"}},"prism":false,"i18n":{"placeholder":"搜索...","empty":"没有找到任何搜索结果:${query}","hits_time":"找到 ${hits} 个搜索结果(用时 ${time} 毫秒)","hits":"找到 ${hits} 个搜索结果"}}</script><script src="/js/config.js"></script>
<meta name="description" content="fly me to the moon ~~~">
<meta property="og:type" content="website">
<meta property="og:title" content="吴青鹤">
<meta property="og:url" content="http:https://example.com/index.html">
<meta property="og:site_name" content="吴青鹤">
<meta property="og:description" content="fly me to the moon ~~~">
<meta property="og:locale" content="zh_CN">
<meta property="article:author" content="picasuo">
<meta name="twitter:card" content="summary">
<link rel="canonical" href="http:https://example.com/">
<script class="next-config" data-name="page" type="application/json">{"sidebar":"","isHome":true,"isPost":false,"lang":"zh-CN","comments":"","permalink":"","path":"index.html","title":""}</script>
<script class="next-config" data-name="calendar" type="application/json">""</script>
<title>吴青鹤</title>
<noscript>
<link rel="stylesheet" href="/css/noscript.css">
</noscript>
</head>
<body itemscope itemtype="http:https://schema.org/WebPage" class="use-motion">
<div class="headband"></div>
<main class="main">
<header class="header" itemscope itemtype="http:https://schema.org/WPHeader">
<div class="header-inner"><div class="site-brand-container">
<div class="site-nav-toggle">
<div class="toggle" aria-label="切换导航栏" role="button">
<span class="toggle-line"></span>
<span class="toggle-line"></span>
<span class="toggle-line"></span>
</div>
</div>
<div class="site-meta">
<a href="/" class="brand" rel="start">
<i class="logo-line"></i>
<h1 class="site-title">吴青鹤</h1>
<i class="logo-line"></i>
</a>
<p class="site-subtitle" itemprop="description">Undefined Man</p>
</div>
<div class="site-nav-right">
<div class="toggle popup-trigger">
</div>
</div>
</div>
<nav class="site-nav">
<ul class="main-menu menu">
<li class="menu-item menu-item-home"><a href="/home/" rel="section">首页</a></li>
<li class="menu-item menu-item-about"><a href="/about/" rel="section">关于</a></li>
<li class="menu-item menu-item-tags"><a href="/tags/" rel="section">标签<span class="badge">0</span></a></li>
<li class="menu-item menu-item-categories"><a href="/categories/" rel="section">分类<span class="badge">0</span></a></li>
<li class="menu-item menu-item-archives"><a href="/archives/" rel="section">归档<span class="badge">2</span></a></li>
</ul>
</nav>
</div>
<div class="toggle sidebar-toggle" role="button">
<span class="toggle-line"></span>
<span class="toggle-line"></span>
<span class="toggle-line"></span>
</div>
<aside class="sidebar">
<div class="sidebar-inner sidebar-overview-active">
<ul class="sidebar-nav">
<li class="sidebar-nav-toc">
文章目录
</li>
<li class="sidebar-nav-overview">
站点概览
</li>
</ul>
<div class="sidebar-panel-container">
<!--noindex-->
<div class="post-toc-wrap sidebar-panel">
</div>
<!--/noindex-->
<div class="site-overview-wrap sidebar-panel">
<div class="site-author site-overview-item animated" itemprop="author" itemscope itemtype="http:https://schema.org/Person">
<img class="site-author-image" itemprop="image" alt="picasuo"
src="/images/picasuo.png">
<p class="site-author-name" itemprop="name">picasuo</p>
<div class="site-description" itemprop="description">fly me to the moon ~~~</div>
</div>
<div class="site-state-wrap site-overview-item animated">
<nav class="site-state">
<div class="site-state-item site-state-posts">
<a href="/archives/">
<span class="site-state-item-count">2</span>
<span class="site-state-item-name">日志</span>
</a>
</div>
</nav>
</div>
</div>
</div>
<link rel="stylesheet" href="/dist/APlayer.min.css">
<meting-js
server="netease"
type="playlist"
id="7171146562"
theme="#282828"
list-folded=true
fixed=true
>
</meting-js>
<script src="/dist/APlayer.min.js"></script>
<script src="/dist/Meting.min.js"></script>
</div>
</aside>
<div class="sidebar-dimmer"></div>
</header>
<div class="back-to-top" role="button" aria-label="返回顶部">
<i class="fa fa-arrow-up"></i>
<span>0%</span>
</div>
<div class="reading-progress-bar"></div>
<noscript>
<div class="noscript-warning">Theme NexT works best with JavaScript enabled</div>
</noscript>
<div class="main-inner index posts-expand">
<div class="post-block">
<article itemscope itemtype="http:https://schema.org/Article" class="post-content" lang="">
<link itemprop="mainEntityOfPage" href="http:https://example.com/2022/01/20/typeof%E4%B8%8Einstanceof%E7%94%A8%E6%B3%95%E5%8F%8A%E5%8C%BA%E5%88%AB/">
<span hidden itemprop="author" itemscope itemtype="http:https://schema.org/Person">
<meta itemprop="image" content="/images/picasuo.png">
<meta itemprop="name" content="picasuo">
<meta itemprop="description" content="fly me to the moon ~~~">
</span>
<span hidden itemprop="publisher" itemscope itemtype="http:https://schema.org/Organization">
<meta itemprop="name" content="吴青鹤">
</span>
<header class="post-header">
<h2 class="post-title" itemprop="name headline">
<a href="/2022/01/20/typeof%E4%B8%8Einstanceof%E7%94%A8%E6%B3%95%E5%8F%8A%E5%8C%BA%E5%88%AB/" class="post-title-link" itemprop="url">typeof与instanceof用法及区别</a>
</h2>
<div class="post-meta-container">
<div class="post-meta">
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-calendar"></i>
</span>
<span class="post-meta-item-text">发表于</span>
<time title="创建时间:2022-01-20 09:54:07 / 修改时间:09:55:51" itemprop="dateCreated datePublished" datetime="2022-01-20T09:54:07+08:00">2022-01-20</time>
</span>
</div>
</div>
</header>
<div class="post-body" itemprop="articleBody">
<ul>
<li><p>typeof 操作符:返回一个字符串,表示未经计算的操作数的类型</p>
<p>引用类型数据,用<code>typeof</code>来判断的话,除了<code>function</code>会被识别出来之外,其余的都输出<code>object</code>.</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line">typeof 1 // 'number'</span><br><span class="line">typeof '1' // 'string'</span><br><span class="line">typeof undefined // 'undefined'</span><br><span class="line">typeof true // 'boolean'</span><br><span class="line">typeof Symbol() // 'symbol'</span><br><span class="line">typeof null // 'object' ~~JavaScript存在的一个悠久Bug,直接使用(===null)判断~~</span><br><span class="line">typeof [] // 'object'</span><br><span class="line">typeof {} // 'object'</span><br><span class="line">typeof console // 'object'</span><br><span class="line">typeof console.log // 'function'</span><br><span class="line"></span><br></pre></td></tr></table></figure>
<p>想要判断一个变量是否存在,可以使用<code>typeof</code>,不能使用<code>if(a)</code>, 若 a 未声明,则报错.</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">if(typeof a != 'undefined'){</span><br><span class="line"> //变量存在</span><br><span class="line">}</span><br></pre></td></tr></table></figure></li>
<li><p><code>instanceof</code>运算符:用于检测构造函数的<code>prototype</code>属性是否出现在某个实例对象的原型链上</p>
<p>使用如下:</p>
<p><code>object instanceof constructor</code></p>
<p><code>object</code>为实例对象,<code>constructor</code>为构造函数</p>
<p>构造函数通过<code>new</code>可以实例对象,<code>instanceof</code>能判断这个对象是否是之前那个构造函数生成的对象</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">// 定义构建函数</span><br><span class="line">let Car = function() {}</span><br><span class="line">let benz = new Car()</span><br><span class="line">benz instanceof Car // true</span><br><span class="line">let car = new String('xxx')</span><br><span class="line">car instanceof String // true</span><br><span class="line">let str = 'xxx'</span><br><span class="line">str instanceof String // false</span><br></pre></td></tr></table></figure>
<p>关于 instanceof 的实现原理,可以参考下面:</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"> function myInstanceof(left, right) {</span><br><span class="line"> // 这里先用typeof来判断基础数据类型,如果是,直接返回false</span><br><span class="line"> if(typeof left !== 'object' || left === null) return false;</span><br><span class="line"> // getProtypeOf是Object对象自带的API,能够拿到参数的原型对象</span><br><span class="line"> let proto = Object.getPrototypeOf(left);</span><br><span class="line"></span><br><span class="line"> while(true) {</span><br><span class="line"> if(proto === null) return false;</span><br><span class="line"> if(proto === right.prototype) return true;//找到相同原型对象,返回true</span><br><span class="line"> proto = Object.getPrototypeof(proto);</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>也就是顺着原型链去找,直到找到相同的原型对象,返回<code>true</code>,否则为<code>false</code></p>
</li>
<li><p>区别</p>
<p><code>typeof</code>会返回一个变量的基本类型,<code>instanceof</code>返回的是一个布尔值.</p>
<p><code>instanceof</code>可以准确地判断复杂引用数据类型,但是不能正确判断基础数据类型.</p>
<p>而<code>typeof</code>也存在弊端,它虽然可以判断基础数据类型(<code>null</code>除外),但是引用数据类型中,除了<code>function</code>类型以外,其他的也无法判断.</p>
</li>
<li><p>通用检测数据类型方法<code>Object.prototype.toString</code></p>
<p>调用该方法,统一返回格式“[object Xxx]” 的字符串,如下:</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">Object.prototype.toString({}) // "[object Object]"</span><br><span class="line">Object.prototype.toString.call({}) // 同上结果,加上call也ok</span><br><span class="line">Object.prototype.toString.call(1) // "[object Number]"</span><br><span class="line">Object.prototype.toString.call('1') // "[object String]"</span><br><span class="line">Object.prototype.toString.call(true) // "[object Boolean]"</span><br><span class="line">Object.prototype.toString.call(function(){}) // "[object Function]"</span><br><span class="line">Object.prototype.toString.call(null) //"[object Null]"</span><br><span class="line">Object.prototype.toString.call(undefined) //"[object Undefined]"</span><br><span class="line">Object.prototype.toString.call(/123/g) //"[object RegExp]"</span><br><span class="line">Object.prototype.toString.call(new Date()) //"[object Date]"</span><br><span class="line">Object.prototype.toString.call([]) //"[object Array]"</span><br><span class="line">Object.prototype.toString.call(document) //"[object HTMLDocument]"</span><br><span class="line">Object.prototype.toString.call(window) //"[object Window]"</span><br></pre></td></tr></table></figure>
<p>实现一个全局通用的数据类型判断方法</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">function getType(obj){</span><br><span class="line"> let type = typeof obj;</span><br><span class="line"> if (type !== "object") { // 先进行typeof判断,如果是基础数据类型,直接返回</span><br><span class="line"> return type;</span><br><span class="line"> }</span><br><span class="line"> // 对于typeof返回结果是object的,再进行如下的判断,正则返回结果</span><br><span class="line"> return Object.prototype.toString.call(obj).replace(/^\[object (\S+)\]$/, '$1');</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>使用如下</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">getType([]) // "Array" typeof []是object,因此toString返回</span><br><span class="line">getType('123') // "string" typeof 直接返回</span><br><span class="line">getType(window) // "Window" toString返回</span><br><span class="line">getType(null) // "Null"首字母大写,typeof null是object,需toString来判断</span><br><span class="line">getType(undefined) // "undefined" typeof 直接返回</span><br><span class="line">getType() // "undefined" typeof 直接返回</span><br><span class="line">getType(function(){}) // "function" typeof能判断,因此首字母小写</span><br><span class="line">getType(/123/g) //"RegExp" toString返回</span><br></pre></td></tr></table></figure></li>
</ul>
</div>
<footer class="post-footer">
<div class="post-eof"></div>
</footer>
</article>
</div>
<div class="post-block">
<article itemscope itemtype="http:https://schema.org/Article" class="post-content" lang="">
<link itemprop="mainEntityOfPage" href="http:https://example.com/2022/01/19/gulp%E5%9F%BA%E7%A1%80%E4%BD%BF%E7%94%A8%E6%B5%81%E7%A8%8B/">
<span hidden itemprop="author" itemscope itemtype="http:https://schema.org/Person">
<meta itemprop="image" content="/images/picasuo.png">
<meta itemprop="name" content="picasuo">
<meta itemprop="description" content="fly me to the moon ~~~">
</span>
<span hidden itemprop="publisher" itemscope itemtype="http:https://schema.org/Organization">
<meta itemprop="name" content="吴青鹤">
</span>
<header class="post-header">
<h2 class="post-title" itemprop="name headline">
<a href="/2022/01/19/gulp%E5%9F%BA%E7%A1%80%E4%BD%BF%E7%94%A8%E6%B5%81%E7%A8%8B/" class="post-title-link" itemprop="url">gulp基础使用流程</a>
</h2>
<div class="post-meta-container">
<div class="post-meta">
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-calendar"></i>
</span>
<span class="post-meta-item-text">发表于</span>
<time title="创建时间:2022-01-19 19:22:46 / 修改时间:19:23:05" itemprop="dateCreated datePublished" datetime="2022-01-19T19:22:46+08:00">2022-01-19</time>
</span>
</div>
</div>
</header>
<div class="post-body" itemprop="articleBody">
<ol>
<li><p>目标:创建一个自动化的工作流程。制作以下任务:</p>
<ul>
<li>从其他来源(如 Sass)编译 CSS 文件</li>
<li>为静态页面生成 HTML</li>
<li>测试应用程序代码</li>
<li>使用 linter 分析代码</li>
<li>启动并在更改时自动重新加载应用程序</li>
</ul>
</li>
<li><p>基本使用</p>
<ul>
<li><p>创建程序:使用 express-generator</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">$ npx express-generator -v ejs --git gulp-project</span><br><span class="line">$ cd gulp-project</span><br><span class="line">$ npm install</span><br></pre></td></tr></table></figure></li>
<li><p>全局安装 gulp</p>
<p><code>$ sudo npm install -g gulp-cli</code></p>
</li>
<li><p>项目里下载 gulp 及其插件</p>
<p><code> $ npm install --save-dev gulp</code></p>
</li>
<li><p>在项目根目录新建 gulpfile.js 文件,在其中进行 gulp 配置</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">// 加载使用到的gulp插件</span><br><span class="line">// src:读取文件和目录并创建数据流以供进一步处理。Src函数支持通配符和过滤器以更好地选择文件</span><br><span class="line">// dest:获取一个目录并将传入流的内容作为文件写入。默认情况下,dest 会覆盖现有文件</span><br><span class="line">const { src, dest } = require("gulp");</span><br><span class="line"></span><br></pre></td></tr></table></figure></li>
<li><p>编写任务</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">// src:从中读取 JavaScript 文件routes/并将其内容传递到管道中</span><br><span class="line">// pipe:将前一个命令的输出作为管道作为下一个的输入</span><br><span class="line">// dest:将先前命令的输出写入copies/目录</span><br><span class="line">function copy(cb) {</span><br><span class="line"> src('routes/*.js')</span><br><span class="line"> .pipe(dest('copies'));</span><br><span class="line"> cb();</span><br><span class="line">}</span><br><span class="line">// 暴露函数以供调用</span><br><span class="line">exports.copy = copy;</span><br><span class="line"></span><br></pre></td></tr></table></figure></li>
<li><p>终端调用任务</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ gulp copy</span><br></pre></td></tr></table></figure></li>
</ul>
</li>
<li><p>编译 css 文件</p>
<ul>
<li><p>目的:创建一个任务来处理 sass/style.scss 然后可以在我们的 HTML 文件中使用。</p>
</li>
<li><p>安装插件</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ npm install --save-dev gulp-sass</span><br></pre></td></tr></table></figure></li>
<li><p>加载 gulpfile.js</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line">const sass = require('gulp-sass');</span><br><span class="line"></span><br><span class="line">// 将所有*.scss文件通过管道传送到sass函数,最后传送到public/stylesheets目录</span><br><span class="line"></span><br><span class="line">function generateCSS(cb) {</span><br><span class="line"> src('./sass/**/*.scss')</span><br><span class="line"> .pipe(sass().on('error', sass.logError))</span><br><span class="line"> .pipe(dest('public/stylesheets'));</span><br><span class="line"> cb();</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">exports.css = generateCSS;</span><br></pre></td></tr></table></figure></li>
<li><p>运行任务</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ gulp css</span><br></pre></td></tr></table></figure></li>
<li><p>结果</p>
<p>会生成新的文件 public/stylesheets/style.css</p>
</li>
</ul>
</li>
<li><p>处理 ejs 模板,生成 html</p>
<ul>
<li><p>安装插件</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ npm install --save-dev gulp-ejs gulp-rename</span><br></pre></td></tr></table></figure></li>
<li><p>加载 gulpfile.js</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br></pre></td><td class="code"><pre><span class="line">const ejs = require("gulp-ejs");</span><br><span class="line">const rename = require("gulp-rename");</span><br><span class="line"></span><br><span class="line"></span><br><span class="line">function generateHTML(cb) {</span><br><span class="line"> // step1:从 views/ 中读取 *.ejs</span><br><span class="line"> src("./views/index.ejs")</span><br><span class="line"> // step2:通过pipe将它们gulp-ejs替换为我们提供的值的变量以获得纯 HTML</span><br><span class="line"> .pipe(ejs({</span><br><span class="line"> title: "Hello Semaphore!",</span><br><span class="line"> }))</span><br><span class="line"> // step3:通过pipe将文件导入gulp-rename以更改文件扩展名</span><br><span class="line"> .pipe(rename({</span><br><span class="line"> extname: ".html"</span><br><span class="line"> }))</span><br><span class="line"> // step4:将所有内容通过管道传输到 public/ 目录中。</span><br><span class="line"> .pipe(dest("public"));</span><br><span class="line"> cb();</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">exports.html = generateHTML;</span><br></pre></td></tr></table></figure></li>
<li><p>运行任务</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ gulp html</span><br></pre></td></tr></table></figure></li>
</ul>
</li>
<li><p>整理代码,规范格式</p>
<ul>
<li><p>安装插件</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ npm install --save-dev gulp-eslint</span><br></pre></td></tr></table></figure></li>
<li><p>加载 gulpfile.js</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br></pre></td><td class="code"><pre><span class="line">const eslint = require("gulp-eslint");</span><br><span class="line"></span><br><span class="line">function runLinter(cb) {</span><br><span class="line"> return src(['**/*.js', '!node_modules/**'])</span><br><span class="line"> .pipe(eslint())</span><br><span class="line"> .pipe(eslint.format())</span><br><span class="line"> // gulp-eslint 提供了一个failAfterError()函数来强制 Gulp 停止并错误退出</span><br><span class="line"> .pipe(eslint.failAfterError())</span><br><span class="line"> // gulp流可以使用on关键字触发事件</span><br><span class="line"> .on('end', function() {</span><br><span class="line"> cb();</span><br><span class="line"> });</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">exports.lint = runLinter;</span><br></pre></td></tr></table></figure></li>
<li><p>注意 ⚠️:必须在项目根目录创建一个 .eslintrc.json 文件提供配置,不然会失败哦</p>
<p>eg:</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br></pre></td><td class="code"><pre><span class="line"> {</span><br><span class="line"> "parserOptions": {</span><br><span class="line"> "ecmaVersion": 6,</span><br><span class="line"> "sourceType": "module",</span><br><span class="line"> "ecmaFeatures": {</span><br><span class="line"> "jsx": true</span><br><span class="line"> }</span><br><span class="line"> },</span><br><span class="line"> "rules": {</span><br><span class="line"> "semi": "error"</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure></li>
<li><p>运行任务</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ gulp lint</span><br></pre></td></tr></table></figure></li>
</ul>
</li>
<li><p>使用 Mocha 测试</p>
<ul>
<li><p>介绍:Mocha 是一种流行的测试框架,可在 Node 和浏览器上运行。我们可以将测试作为 Gulp 管道的一部分运行。了解更多关于<a target="_blank" rel="noopener" href="https://semaphoreci.com/community/tutorials/getting-started-with-node-js-and-mocha">Node.js 和 Mocha 入门</a></p>
</li>
<li><p>使用 *.test.js 形式来确定测试文件,创建 app.test.js 测试 express 应用程序的文件<br>eg:</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br></pre></td><td class="code"><pre><span class="line">const app = require('./app');</span><br><span class="line">const request = require('supertest');</span><br><span class="line"></span><br><span class="line">describe('test', function() {</span><br><span class="line"></span><br><span class="line"> let server = null;</span><br><span class="line"></span><br><span class="line"> beforeEach(function(done) {</span><br><span class="line"> server = app.listen(0, function(err) {</span><br><span class="line"> if(err) { return done(err); }</span><br><span class="line"> done();</span><br><span class="line"> });</span><br><span class="line"> });</span><br><span class="line"></span><br><span class="line"> afterEach(function() {</span><br><span class="line"> server.close();</span><br><span class="line"> });</span><br><span class="line"></span><br><span class="line"> it('Status code should be 200', function(done) {</span><br><span class="line"> request(app)</span><br><span class="line"> .get('/')</span><br><span class="line"> .expect(200, done);</span><br><span class="line"> });</span><br><span class="line"></span><br><span class="line"> it('Test /users response', function(done) {</span><br><span class="line"> request(app)</span><br><span class="line"> .get('/users')</span><br><span class="line"> .expect(200)</span><br><span class="line"> .expect('respond with a resource', done);</span><br><span class="line"> });</span><br><span class="line"></span><br><span class="line">});</span><br></pre></td></tr></table></figure></li>
<li><p>加载 gulpfile.js</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line"> const mocha = require("gulp-mocha");</span><br><span class="line"></span><br><span class="line"> function runTests(cb) {</span><br><span class="line"> return src(['**/*.test.js'])</span><br><span class="line"> .pipe(mocha())</span><br><span class="line">//.on('error')使用 Error 实例捕获错误事件并调用回调。随着return我们确保gulp捕获错误并退出失败</span><br><span class="line"> on('error', function() {</span><br><span class="line"> cb(new Error('Test failed'));</span><br><span class="line"> })</span><br><span class="line"> .on('end', function() {</span><br><span class="line"> cb();</span><br><span class="line"> });</span><br><span class="line"> }</span><br><span class="line"> exports.test = runTests;</span><br></pre></td></tr></table></figure></li>
</ul>
</li>
<li><p>监视文件更改</p>
<ul>
<li><p>任务描述:是在代码发生更改时自动执行所有处理任务。我们用 watch 方法完成这个;它是 Gulp 的标准部分,因此无需加载新模块。但是,我们必须在 gulpfile.js 中导入关键字.</p>
</li>
<li><p>加载组件时导入关键字</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">//注意⚠️:这里还导入了并行函数parallel</span><br><span class="line">const { src, dest, watch, parallel } = require("gulp");</span><br><span class="line"></span><br></pre></td></tr></table></figure></li>
<li><p>加载 gulpfile.js</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br></pre></td><td class="code"><pre><span class="line">//watch()参数:1. 监听的文件; 2. 监听到文件更改后触发的回调</span><br><span class="line">function watchFiles(cb) {</span><br><span class="line"> // 监听html变化</span><br><span class="line"> watch('views/**.ejs', generateHTML);</span><br><span class="line"> // 监听scss变化</span><br><span class="line"> watch('sass/**.scss', generateCSS);</span><br><span class="line"> // 监听js变化</span><br><span class="line"> watch([ '**/*.js', '!node_modules/**'], parallel(runLinter, runTests));</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">exports.watch = watchFiles;</span><br></pre></td></tr></table></figure></li>
<li><p>运行任务</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ gulp watch</span><br></pre></td></tr></table></figure></li>
</ul>
</li>
<li><p>为实时重载创建服务器</p>
<ul>
<li><p>任务描述:最终任务是在浏览器上设置实时重新加载.该任务为位于 public/ 上的静态文件启动一个本地服务器,并像我们之前所做的那样监听 Sass 和模板的变化。之后,我们可以将所有任务整合到一个高效的工作流程中。</p>
</li>
<li><p>安装插件</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ npm install --save-dev browser-sync</span><br></pre></td></tr></table></figure></li>
<li><p>加载 gulpfile.js</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br></pre></td><td class="code"><pre><span class="line">const sync = require("browser-sync").create();</span><br><span class="line"></span><br><span class="line">function browserSync(cb) {</span><br><span class="line"> sync.init({</span><br><span class="line"> server: {</span><br><span class="line"> baseDir: "./public"</span><br><span class="line"> }</span><br><span class="line"> });</span><br><span class="line"></span><br><span class="line"> watch('views/**.ejs', generateHTML);</span><br><span class="line"> watch('sass/**.scss', generateCSS);</span><br><span class="line"> watch("./public/**.html").on('change', sync.reload);</span><br><span class="line"> watch('./public/stylesheets/**.css').on('change', sync.reload)</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">exports.sync = browserSync;</span><br></pre></td></tr></table></figure></li>
<li><p>运行任务</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br></pre></td><td class="code"><pre><span class="line">$ gulp sync</span><br><span class="line"></span><br><span class="line">//终端返回结果</span><br><span class="line">[12:28:47] Using gulpfile ~/r/gulp-project/gulpfile.js</span><br><span class="line">[12:28:47] Starting 'sync'...</span><br><span class="line">[Browsersync] Access URLs:</span><br><span class="line">-------------------------------------</span><br><span class="line"> Local: http:https://localhost:3000</span><br><span class="line"> External: http:https://192.168.0.14:3000</span><br><span class="line">-------------------------------------</span><br><span class="line"> UI: http:https://localhost:3001</span><br><span class="line">UI External: http:https://localhost:3001</span><br><span class="line">-------------------------------------</span><br><span class="line">[Browsersync] Serving files from: ./public</span><br></pre></td></tr></table></figure></li>
<li><p>预期内结果:返回浏览器,发现页面重新加载了新样式。对 views/ 上的任何模板进行更改都会产生相同的效果。</p>
</li>
</ul>
</li>
<li><p>添加默认任务</p>
<ul>
<li><p>导入 series 串联函数</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">const { src, dest, watch, parallel, series } = require("gulp");</span><br><span class="line"></span><br></pre></td></tr></table></figure></li>
<li><p>结合串联、并联来构建一个完整的构建流程,作为 gulp 默认任务</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">exports.default = series(runLinter,parallel(generateCSS,generateHTML),runTests);</span><br></pre></td></tr></table></figure></li>
<li><p>执行</p>
<figure class="highlight plaintext"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br></pre></td><td class="code"><pre><span class="line">$ gulp</span><br><span class="line"></span><br><span class="line">//使用 --tasks 获取可用任务的列表:</span><br><span class="line">$ gulp --tasks</span><br></pre></td></tr></table></figure></li>
</ul>
</li>
</ol>
<p><strong>extra</strong>:推荐一些 npm 包,可以作为工具。<code>fancy-log</code>可以在打印信息前加上时间戳。</p>
</div>
<footer class="post-footer">
<div class="post-eof"></div>
</footer>
</article>
</div>
</div>
</main>
<footer class="footer">
<div class="footer-inner">
<div class="copyright">
©
<span itemprop="copyrightYear">2022</span>
<span class="with-love">
<i class="fa fa-heart"></i>
</span>
<span class="author" itemprop="copyrightHolder">picasuo</span>
</div>
<div class="powered-by">由 <a href="https://hexo.io/" rel="noopener" target="_blank">Hexo</a> & <a href="https://theme-next.js.org/pisces/" rel="noopener" target="_blank">NexT.Pisces</a> 强力驱动
</div><script color="0,0,255" opacity="0.5" zIndex="-1" count="99" src="https://cdn.jsdelivr.net/npm/canvas-nest.js@1/dist/canvas-nest.js"></script>
</div>
</footer>
<script size="60" alpha="0.8" zIndex="-1" src="https://cdn.jsdelivr.net/npm/[email protected]/dist/ribbon.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/lib/anime.min.js" integrity="sha256-XL2inqUJaslATFnHdJOi9GfQ60on8Wx1C2H8DYiN1xY=" crossorigin="anonymous"></script>
<script src="/js/comments.js"></script><script src="/js/utils.js"></script><script src="/js/motion.js"></script><script src="/js/next-boot.js"></script>
<script src="/js/third-party/pace.js"></script>
<canvas class="fireworks" style="position: fixed;left: 0;top: 0;z-index: 1; pointer-events: none;" ></canvas>
<script src="//cdn.bootcss.com/animejs/2.2.0/anime.min.js"></script>
<script src="/js/cursor/explosion.min.js"></script>
<script src="/live2dw/lib/L2Dwidget.min.js?094cbace49a39548bed64abff5988b05"></script><script>L2Dwidget.init({"pluginModelPath":"assets/","model":{"jsonPath":"/live2dw/assets/koharu.model.json"},"display":{"position":"right","width":300,"height":500},"mobile":{"show":false},"rect":"opacity:0.7","log":false,"pluginJsPath":"lib/","pluginRootPath":"live2dw/","tagMode":false});</script></body>
</html>