-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathindex.html
2269 lines (1895 loc) · 240 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
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=2">
<meta name="theme-color" content="#222">
<meta name="generator" content="Hexo 3.9.0">
<link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-next.ico">
<link rel="icon" type="image/png" sizes="32x32" href="/favicon.ico">
<link rel="icon" type="image/png" sizes="16x16" href="/favicon.ico">
<link rel="mask-icon" href="/logo.svg" color="#222">
<link rel="stylesheet" href="/css/main.css">
<link rel="stylesheet" href="/lib/font-awesome/css/all.min.css">
<script id="hexo-configurations">
var NexT = window.NexT || {};
var CONFIG = {"hostname":"adispring.github.io","root":"/","scheme":"Muse","version":"7.8.0","exturl":false,"sidebar":{"position":"left","display":"post","padding":18,"offset":12,"onmobile":false},"copycode":{"enable":false,"show_result":false,"style":null},"back2top":{"enable":true,"sidebar":false,"scrollpercent":false},"bookmark":{"enable":false,"color":"#222","save":"auto"},"fancybox":false,"mediumzoom":false,"lazyload":false,"pangu":false,"comments":{"style":"tabs","active":null,"storage":true,"lazyload":false,"nav":null},"algolia":{"hits":{"per_page":10},"labels":{"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}},"localsearch":{"enable":false,"trigger":"auto","top_n_per_article":1,"unescape":false,"preload":false},"motion":{"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}}};
</script>
<meta name="description" content="[email protected]">
<meta property="og:type" content="website">
<meta property="og:title" content="wangzengdi's Blog">
<meta property="og:url" content="https://adispring.github.io/index.html">
<meta property="og:site_name" content="wangzengdi's Blog">
<meta property="og:description" content="[email protected]">
<meta property="og:locale" content="en">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="wangzengdi's Blog">
<meta name="twitter:description" content="[email protected]">
<link rel="canonical" href="https://adispring.github.io/">
<script id="page-configurations">
// https://hexo.io/docs/variables.html
CONFIG.page = {
sidebar: "",
isHome : true,
isPost : false,
lang : 'en'
};
</script>
<title>wangzengdi's Blog</title>
<noscript>
<style>
.use-motion .brand,
.use-motion .menu-item,
.sidebar-inner,
.use-motion .post-block,
.use-motion .pagination,
.use-motion .comments,
.use-motion .post-header,
.use-motion .post-body,
.use-motion .collection-header { opacity: initial; }
.use-motion .site-title,
.use-motion .site-subtitle {
opacity: initial;
top: initial;
}
.use-motion .logo-line-before i { left: initial; }
.use-motion .logo-line-after i { right: initial; }
</style>
</noscript>
</head>
<body itemscope itemtype="http://schema.org/WebPage">
<div class="container use-motion">
<div class="headband"></div>
<header class="header" itemscope itemtype="http://schema.org/WPHeader">
<div class="header-inner"><div class="site-brand-container">
<div class="site-nav-toggle">
<div class="toggle" aria-label="Toggle navigation bar">
<span class="toggle-line toggle-line-first"></span>
<span class="toggle-line toggle-line-middle"></span>
<span class="toggle-line toggle-line-last"></span>
</div>
</div>
<div class="site-meta">
<a href="/" class="brand" rel="start">
<span class="logo-line-before"><i></i></span>
<h1 class="site-title">wangzengdi's Blog</h1>
<span class="logo-line-after"><i></i></span>
</a>
<p class="site-subtitle" itemprop="description">Functional Programming</p>
</div>
<div class="site-nav-right">
<div class="toggle popup-trigger">
</div>
</div>
</div>
<nav class="site-nav">
<ul id="menu" class="main-menu menu">
<li class="menu-item menu-item-home">
<a href="/" rel="section"><i class="fa fa-home fa-fw"></i>Home</a>
</li>
<li class="menu-item menu-item-archives">
<a href="/archives/" rel="section"><i class="fa fa-archive fa-fw"></i>Archives</a>
</li>
</ul>
</nav>
</div>
</header>
<div class="back-to-top">
<i class="fa fa-arrow-up"></i>
<span>0%</span>
</div>
<main class="main">
<div class="main-inner">
<div class="content-wrap">
<div class="content index posts-expand">
<article itemscope itemtype="http://schema.org/Article" class="post-block" lang="en">
<link itemprop="mainEntityOfPage" href="https://adispring.github.io/2022/04/27/Hexo-Workflow/">
<span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
<meta itemprop="image" content="/images/avatar.gif">
<meta itemprop="name" content="wangzengdi">
<meta itemprop="description" content="[email protected]">
</span>
<span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
<meta itemprop="name" content="wangzengdi's Blog">
</span>
<header class="post-header">
<h2 class="post-title" itemprop="name headline">
<a href="/2022/04/27/Hexo-Workflow/" class="post-title-link" itemprop="url">Hexo Workflow</a>
</h2>
<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">Posted on</span>
<time title="Created: 2022-04-27 12:20:36" itemprop="dateCreated datePublished" datetime="2022-04-27T12:20:36+00:00">2022-04-27</time>
</span>
</div>
</header>
<div class="post-body" itemprop="articleBody">
<p>Welcome to <a href="https://hexo.io/" target="_blank" rel="noopener">Hexo</a>! This is your very first post. Check <a href="https://hexo.io/docs/" target="_blank" rel="noopener">documentation</a> for more info. If you get any problems when using Hexo, you can find the answer in <a href="https://hexo.io/docs/troubleshooting.html" target="_blank" rel="noopener">troubleshooting</a> or you can ask me on <a href="https://github.com/hexojs/hexo/issues" target="_blank" rel="noopener">GitHub</a>.</p>
<h2 id="quick-start">Quick Start</h2>
<h3 id="create-a-new-post">Create a new post</h3>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ hexo new <span class="string">"My New Post"</span></span><br></pre></td></tr></table></figure>
<p>More info: <a href="https://hexo.io/docs/writing.html" target="_blank" rel="noopener">Writing</a></p>
<h3 id="run-server">Run server</h3>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ hexo server</span><br></pre></td></tr></table></figure>
<p>More info: <a href="https://hexo.io/docs/server.html" target="_blank" rel="noopener">Server</a></p>
<h3 id="generate-static-files">Generate static files</h3>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ hexo generate</span><br></pre></td></tr></table></figure>
<p>More info: <a href="https://hexo.io/docs/generating.html" target="_blank" rel="noopener">Generating</a></p>
<h3 id="deploy-to-remote-sites">Deploy to remote sites</h3>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ hexo deploy</span><br></pre></td></tr></table></figure>
<h3 id="generate-amp-deploy-together">Generate & Deploy together</h3>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ hexo d -g</span><br></pre></td></tr></table></figure>
<p>More info: <a href="https://hexo.io/docs/deployment.html" target="_blank" rel="noopener">Deployment</a></p>
<h3 id="hexo-zi-dong-hua-bu-shu">Hexo 自动化部署</h3>
<ul>
<li>官方自动化部署文档 – Hexo + Travis: <a href="https://hexo.io/docs/github-pages.html" target="_blank" rel="noopener">https://hexo.io/docs/github-pages.html</a></li>
<li>空白页问题的解决方案:<a href="http://magicse7en.github.io/2016/03/27/travis-ci-auto-deploy-hexo-github/" target="_blank" rel="noopener">http://magicse7en.github.io/2016/03/27/travis-ci-auto-deploy-hexo-github/</a></li>
</ul>
<p>自动化部署工作流:</p>
<p>本地开发使用 hexo-source 分支,开发完成后,推导 github 仓库,会触发自动化部署,自动部署在 master 分支上生成最新的文档并部署。</p>
</div>
<footer class="post-footer">
<div class="post-eof"></div>
</footer>
</article>
<article itemscope itemtype="http://schema.org/Article" class="post-block" lang="en">
<link itemprop="mainEntityOfPage" href="https://adispring.github.io/2022/03/24/Write-Vue2-with-TypeScript/">
<span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
<meta itemprop="image" content="/images/avatar.gif">
<meta itemprop="name" content="wangzengdi">
<meta itemprop="description" content="[email protected]">
</span>
<span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
<meta itemprop="name" content="wangzengdi's Blog">
</span>
<header class="post-header">
<h2 class="post-title" itemprop="name headline">
<a href="/2022/03/24/Write-Vue2-with-TypeScript/" class="post-title-link" itemprop="url">TypeScript 开发 Vue2</a>
</h2>
<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">Posted on</span>
<time title="Created: 2022-03-24 15:28:37" itemprop="dateCreated datePublished" datetime="2022-03-24T15:28:37+00:00">2022-03-24</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-calendar-check"></i>
</span>
<span class="post-meta-item-text">Edited on</span>
<time title="Modified: 2022-04-27 12:20:36" itemprop="dateModified" datetime="2022-04-27T12:20:36+00:00">2022-04-27</time>
</span>
</div>
</header>
<div class="post-body" itemprop="articleBody">
<h2 id="yuan-li-jian-jie">原理简介</h2>
<p>在 Vue2 中,我们编写的 单文件组件(SCF,也即 Single-File Components),其实是 vue 自创的前端领域语言(类比各互联网厂的小程序开发语言,也是各自造(抄)的领域语言),形式如下所示:</p>
<figure class="highlight plain"><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><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br></pre></td><td class="code"><pre><span class="line"><template></span><br><span class="line"> <div class="title" @click="onClick">{{ title }}</div></span><br><span class="line"></template></span><br><span class="line"></span><br><span class="line"><script></span><br><span class="line">export default {</span><br><span class="line"> props: {</span><br><span class="line"> // 基础的类型检查 (`null` 和 `undefined` 会通过任何类型验证)</span><br><span class="line"> propA: Number,</span><br><span class="line"> // 多个可能的类型</span><br><span class="line"> propB: [String, Number],</span><br><span class="line"> // 必填的字符串</span><br><span class="line"> propC: {</span><br><span class="line"> type: String,</span><br><span class="line"> required: true</span><br><span class="line"> },</span><br><span class="line"> },</span><br><span class="line"></span><br><span class="line"> data() {</span><br><span class="line"> return {</span><br><span class="line"> title: 'hello, vue',</span><br><span class="line"> }</span><br><span class="line"> },</span><br><span class="line"></span><br><span class="line"> methods: {</span><br><span class="line"> onClick() {</span><br><span class="line"> console.log('click');</span><br><span class="line"> }</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></script></span><br><span class="line"></span><br><span class="line"><style></span><br><span class="line">.title {</span><br><span class="line"> color: red;</span><br><span class="line">}</span><br><span class="line"></style></span><br></pre></td></tr></table></figure>
<p>其中 <code><script> ... </script></code> 标签内包含了一个使用 JavaScript 编写的、 Vue 组件的配置对象,配置对象中包含 props、data、methods 等内容。</p>
<p>从上面的示例可以看出,原始的 Vue 配置对象,只能够对 props 进行有限的类型检查,不能对 data、methods 等其他配置项做类型声明和类型检查。并且在对 props 进行类型声明时,只能使用下列原生构造函数:String Number Boolean Array Object Date Function Symbol 来做类型校验,不能进行更具体、深入的类型声明,可以说是非常鸡肋。</p>
<p>对一个对象进行 TypeScript 类型声明是比较困难的,而对 <code>class</code> 进行 TypeScript 类型声明是相对简单、自然的:我们可以很方便地对 class 的属性和方法添加类型,还可以通过 <code>extends</code> 继承父类的类型。如下所示:</p>
<figure class="highlight ts"><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">class</span> Animal {</span><br><span class="line"> name: <span class="built_in">string</span>;</span><br><span class="line"></span><br><span class="line"> <span class="keyword">constructor</span>(<span class="params">theName: <span class="built_in">string</span></span>) {</span><br><span class="line"> <span class="keyword">this</span>.name = theName;</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> move(distanceInMeters: <span class="built_in">number</span> = <span class="number">0</span>) {</span><br><span class="line"> <span class="built_in">console</span>.log(<span class="string">`<span class="subst">${<span class="keyword">this</span>.name}</span> moved <span class="subst">${distanceInMeters}</span>m.`</span>);</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"> </span><br><span class="line"><span class="keyword">class</span> Horse <span class="keyword">extends</span> Animal {</span><br><span class="line"> <span class="keyword">constructor</span>(<span class="params">name: <span class="built_in">string</span></span>) {</span><br><span class="line"> <span class="keyword">super</span>(name);</span><br><span class="line"> }</span><br><span class="line"></span><br><span class="line"> move(distanceInMeters = <span class="number">45</span>) {</span><br><span class="line"> <span class="built_in">console</span>.log(<span class="string">"Galloping..."</span>);</span><br><span class="line"> <span class="keyword">super</span>.move(distanceInMeters);</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>那么我们是否可以使用 class 来写 Vue 组件呢?这就是 <a href="https://www.typescriptlang.org/docs/handbook/decorators.html" target="_blank" rel="noopener">Decorators (装饰器)</a>。</p>
<p>本质上,装饰器就是一个函数。函数能做的事情,装饰器都能做。函数可以做任何类型的数据转换,装饰器也是一样的。</p>
<p>有了装饰器,我们就可以使用 <code>class</code> 和 TypeScript 来开发 Vue 组件;然后在运行时,使用装饰器将我们定义的 <code>class</code> 转换为 Vue 引擎能够识别的原生的 Vue 配置对象,如下所示。</p>
<p>开发时:</p>
<figure class="highlight ts"><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> { Vue, Component, Prop } <span class="keyword">from</span> <span class="string">'vue-property-decorator'</span></span><br><span class="line"></span><br><span class="line"><span class="meta">@Component</span></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> <span class="keyword">class</span> YourComponent <span class="keyword">extends</span> Vue {</span><br><span class="line"> <span class="meta">@Prop</span>({ <span class="keyword">default</span>: <span class="string">'default value'</span> }) readonly title!: <span class="built_in">string</span></span><br><span class="line"></span><br><span class="line"> message: <span class="built_in">string</span> = <span class="string">'hello, world'</span>;</span><br><span class="line"></span><br><span class="line"> onClick(): <span class="built_in">void</span> {}</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>运行时,@Component 将自定义的组件 <code>YourComponent</code> 转换为 Vue 配置对象:</p>
<figure class="highlight js"><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"><span class="keyword">export</span> <span class="keyword">default</span> {</span><br><span class="line"> props: {</span><br><span class="line"> title: {</span><br><span class="line"> <span class="keyword">default</span>: <span class="string">'default value'</span>,</span><br><span class="line"> },</span><br><span class="line"> },</span><br><span class="line"></span><br><span class="line"> data() {</span><br><span class="line"> message: <span class="string">'hello, world'</span>,</span><br><span class="line"> },</span><br><span class="line"></span><br><span class="line"> methods: {</span><br><span class="line"> onClick() {}</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>Vue2 使用 TypeScript 开发,原理就是这么简单。下面来详细讲一下 Vue2 使用 TypeScript 开发原理。</p>
<h2 id="yi-lai-bao-jie-shao">依赖包介绍</h2>
<p>Vue2 使用 TypeScript 开发,依赖三个库:</p>
<ul>
<li>vue-property-decorator: 提供所有的装饰器;开发时会直接用到的库;依赖 vue-class-component 和 vue;</li>
<li>vue-class-component: 提供 @Component 装饰器 和 基本的装饰器工厂函数 <code>createDecorator</code>;开发时不会直接用到;依赖 vue;vue-property-decorator 中暴露的 @Component,其实是 vue-class-component 提供的;vue-property-decorator 中其他的装饰器,都是由 <code>createDecorator</code> 创建的;</li>
<li>vue: Vue 基础库,提供 Vue 的类型声明,vue-property-decorator 中暴露的 Vue,其实就是 vue 中的 Vue 类;</li>
</ul>
<p>我们来具体看一下这三个库对外暴露的接口:</p>
<p>vue-property-decorator:</p>
<figure class="highlight ts"><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> Vue <span class="keyword">from</span> <span class="string">'vue'</span></span><br><span class="line"><span class="keyword">import</span> Component, { mixins } <span class="keyword">from</span> <span class="string">'vue-class-component'</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">export</span> { Component, Vue, mixins <span class="keyword">as</span> Mixins }</span><br><span class="line"></span><br><span class="line"><span class="keyword">export</span> { Emit } <span class="keyword">from</span> <span class="string">'./decorators/Emit'</span></span><br><span class="line"><span class="keyword">export</span> { Prop } <span class="keyword">from</span> <span class="string">'./decorators/Prop'</span></span><br><span class="line"><span class="keyword">export</span> { Ref } <span class="keyword">from</span> <span class="string">'./decorators/Ref'</span></span><br><span class="line"><span class="keyword">export</span> { Watch } <span class="keyword">from</span> <span class="string">'./decorators/Watch'</span></span><br><span class="line"><span class="comment">// ...</span></span><br></pre></td></tr></table></figure>
<p>vue-class-component</p>
<figure class="highlight ts"><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> Vue, { ComponentOptions } <span class="keyword">from</span> <span class="string">'vue'</span></span><br><span class="line"><span class="keyword">import</span> { VueClass } <span class="keyword">from</span> <span class="string">'./declarations'</span></span><br><span class="line"><span class="keyword">import</span> { componentFactory, $internalHooks } <span class="keyword">from</span> <span class="string">'./component'</span></span><br><span class="line"></span><br><span class="line"><span class="keyword">export</span> { createDecorator, VueDecorator, mixins } <span class="keyword">from</span> <span class="string">'./util'</span></span><br><span class="line"></span><br><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">Component</span> <<span class="title">V</span> <span class="title">extends</span> <span class="title">Vue</span>>(<span class="params">options: ComponentOptions<V> & ThisType<V></span>): <<span class="title">VC</span> <span class="title">extends</span> <span class="title">VueClass</span><<span class="title">V</span>>>(<span class="params">target: VC</span>) => <span class="title">VC</span></span></span><br><span class="line"><span class="function"><span class="function"><span class="keyword">function</span> <span class="title">Component</span> <<span class="title">VC</span> <span class="title">extends</span> <span class="title">VueClass</span><<span class="title">Vue</span>>>(<span class="params">target: VC</span>): <span class="title">VC</span></span></span></span><br><span class="line"><span class="function"><span class="function"><span class="function"><span class="keyword">function</span> <span class="title">Component</span> (<span class="params">options: ComponentOptions<Vue> | VueClass<Vue></span>): <span class="title">any</span> </span>{</span></span></span><br><span class="line"><span class="function"><span class="function"> <span class="title">if</span> (<span class="params"><span class="keyword">typeof</span> options === '<span class="keyword">function</span>'</span>) </span>{</span></span><br><span class="line"><span class="function"> <span class="title">return</span> <span class="title">componentFactory</span>(<span class="params">options</span>)</span></span><br><span class="line"><span class="function"> }</span></span><br><span class="line"><span class="function"> <span class="title">return</span> <span class="function"><span class="keyword">function</span> (<span class="params">Component: VueClass<Vue></span>) </span>{</span></span><br><span class="line"><span class="function"> <span class="title">return</span> <span class="title">componentFactory</span>(<span class="params">Component, options</span>)</span></span><br><span class="line"><span class="function"> }</span></span><br><span class="line"><span class="function">}</span></span><br><span class="line"><span class="function"></span></span><br><span class="line"><span class="function"><span class="title">Component</span>.<span class="title">registerHooks</span> = <span class="function"><span class="keyword">function</span> <span class="title">registerHooks</span> (<span class="params">keys: <span class="built_in">string</span>[]</span>): <span class="title">void</span> </span>{</span></span><br><span class="line"><span class="function"> <span class="title">$internalHooks</span>.<span class="title">push</span>(<span class="params">...keys</span>)</span></span><br><span class="line"><span class="function">}</span></span><br><span class="line"><span class="function"></span></span><br><span class="line"><span class="function"><span class="title">export</span> <span class="title">default</span> <span class="title">Component</span></span></span><br></pre></td></tr></table></figure>
<p>vue</p>
<figure class="highlight ts"><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"><span class="keyword">import</span> { Vue } <span class="keyword">from</span> <span class="string">"./vue"</span>;</span><br><span class="line"><span class="keyword">import</span> <span class="string">"./umd"</span>;</span><br><span class="line"></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> Vue;</span><br><span class="line"></span><br><span class="line"><span class="keyword">export</span> {</span><br><span class="line"> CreateElement,</span><br><span class="line"> VueConstructor</span><br><span class="line">} <span class="keyword">from</span> <span class="string">"./vue"</span>;</span><br><span class="line"></span><br><span class="line"><span class="comment">// ...</span></span><br></pre></td></tr></table></figure>
<p>通过展示三个库对外暴露接口的 index.ts 文件,我们就可以很清晰看到它们暴露的内容,以及依赖关系。</p>
<p>我们再来看一下如何使用 装饰器、class 和 TypeScript 来写 Vue 组件:</p>
<figure class="highlight ts"><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">import</span> { Vue, Component, Prop } <span class="keyword">from</span> <span class="string">'vue-property-decorator'</span></span><br><span class="line"></span><br><span class="line"><span class="meta">@Component</span></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> <span class="keyword">class</span> YourComponent <span class="keyword">extends</span> Vue {</span><br><span class="line"> <span class="meta">@Prop</span>({ <span class="keyword">default</span>: <span class="string">'default value'</span> }) readonly title!: <span class="built_in">string</span></span><br><span class="line"></span><br><span class="line"> message: <span class="built_in">string</span> = <span class="string">'hello, world'</span>;</span><br><span class="line"></span><br><span class="line"> onClick(): <span class="built_in">void</span> {}</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p><code>YourComponent extends Vue</code> 就可以继承 Vue 上面所有的属性和方法,方法包括实例方法和静态方法,YourComponent 可以直接通过 this 调用 Vue 上的实例方法,在开发时,编辑器也会自动提示。我们来看一下 Vue 的类型声明:</p>
<p>下面是 Vue 实例上的属性和方法的声明</p>
<figure class="highlight ts"><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><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">export</span> <span class="keyword">interface</span> Vue {</span><br><span class="line"> readonly $el: Element;</span><br><span class="line"> readonly $options: ComponentOptions<Vue>;</span><br><span class="line"> readonly $parent: Vue;</span><br><span class="line"> readonly $root: Vue;</span><br><span class="line"> readonly $children: Vue[];</span><br><span class="line"> readonly $refs: { [key: <span class="built_in">string</span>]: Vue | Element | (Vue | Element)[] | <span class="literal">undefined</span> };</span><br><span class="line"> readonly $slots: { [key: <span class="built_in">string</span>]: VNode[] | <span class="literal">undefined</span> };</span><br><span class="line"> readonly $scopedSlots: { [key: <span class="built_in">string</span>]: NormalizedScopedSlot | <span class="literal">undefined</span> };</span><br><span class="line"> readonly $isServer: <span class="built_in">boolean</span>;</span><br><span class="line"> readonly $data: Record<<span class="built_in">string</span>, <span class="built_in">any</span>>;</span><br><span class="line"> readonly $props: Record<<span class="built_in">string</span>, <span class="built_in">any</span>>;</span><br><span class="line"> readonly $ssrContext: <span class="built_in">any</span>;</span><br><span class="line"> readonly $vnode: VNode;</span><br><span class="line"> readonly $attrs: Record<<span class="built_in">string</span>, <span class="built_in">string</span>>;</span><br><span class="line"> readonly $listeners: Record<<span class="built_in">string</span>, <span class="built_in">Function</span> | <span class="built_in">Function</span>[]>;</span><br><span class="line"></span><br><span class="line"> $mount(elementOrSelector?: Element | <span class="built_in">string</span>, hydrating?: <span class="built_in">boolean</span>): <span class="keyword">this</span>;</span><br><span class="line"> $forceUpdate(): <span class="built_in">void</span>;</span><br><span class="line"> $destroy(): <span class="built_in">void</span>;</span><br><span class="line"> $<span class="keyword">set</span>: <span class="keyword">typeof</span> Vue.set;</span><br><span class="line"> $<span class="keyword">delete</span>: <span class="keyword">typeof</span> Vue.delete;</span><br><span class="line"> $watch(</span><br><span class="line"> expOrFn: <span class="built_in">string</span>,</span><br><span class="line"> callback: <span class="function">(<span class="params"><span class="keyword">this</span>: <span class="keyword">this</span>, n: <span class="built_in">any</span>, o: <span class="built_in">any</span></span>) =></span> <span class="built_in">void</span>,</span><br><span class="line"> options?: WatchOptions</span><br><span class="line"> ): <span class="function">(<span class="params">(<span class="params"></span>) => <span class="built_in">void</span></span>);</span></span><br><span class="line"><span class="function"> $<span class="params">watch</span><<span class="params">T</span>>(<span class="params"></span></span></span><br><span class="line"><span class="function"><span class="params"> expOrFn: (<span class="params"><span class="keyword">this</span>: <span class="keyword">this</span></span>) => T,</span></span></span><br><span class="line"><span class="function"><span class="params"> callback: (<span class="params"><span class="keyword">this</span>: <span class="keyword">this</span>, n: T, o: T</span>) => <span class="built_in">void</span>,</span></span></span><br><span class="line"><span class="function"><span class="params"> options?: WatchOptions</span></span></span><br><span class="line"><span class="function"><span class="params"> </span>): (<span class="params">(<span class="params"></span>) => <span class="built_in">void</span></span>);</span></span><br><span class="line"><span class="function"> $<span class="params">on</span>(<span class="params">event: <span class="built_in">string</span> | <span class="built_in">string</span>[], callback: <span class="built_in">Function</span></span>): <span class="params">this</span>;</span></span><br><span class="line"><span class="function"> $<span class="params">once</span>(<span class="params">event: <span class="built_in">string</span> | <span class="built_in">string</span>[], callback: <span class="built_in">Function</span></span>): <span class="params">this</span>;</span></span><br><span class="line"><span class="function"> $<span class="params">off</span>(<span class="params">event?: <span class="built_in">string</span> | <span class="built_in">string</span>[], callback?: <span class="built_in">Function</span></span>): <span class="params">this</span>;</span></span><br><span class="line"><span class="function"> $<span class="params">emit</span>(<span class="params">event: <span class="built_in">string</span>, ...args: <span class="built_in">any</span>[]</span>): <span class="params">this</span>;</span></span><br><span class="line"><span class="function"> $<span class="params">nextTick</span>(<span class="params">callback: (<span class="params"><span class="keyword">this</span>: <span class="keyword">this</span></span>) => <span class="built_in">void</span></span>): <span class="params">void</span>;</span></span><br><span class="line"><span class="function"> $<span class="params">nextTick</span><span class="params">()</span>: <span class="params">Promise</span><<span class="params">void</span>>;</span></span><br><span class="line"><span class="function"> $<span class="params">createElement</span>: <span class="params">CreateElement</span>;</span></span><br><span class="line"><span class="function">}</span></span><br></pre></td></tr></table></figure>
<p>下面是 Vue 的静态属性和静态方法,也即 Vue 构造函数上的属性和方法:</p>
<figure class="highlight ts"><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><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">export</span> <span class="keyword">interface</span> VueConstructor<V <span class="keyword">extends</span> Vue = Vue> {</span><br><span class="line"> <span class="keyword">new</span> <Data = object, Methods = object, Computed = object, PropNames <span class="keyword">extends</span> <span class="built_in">string</span> = never>(options?: ThisTypedComponentOptionsWithArrayProps<V, Data, Methods, Computed, PropNames>): CombinedVueInstance<V, Data, Methods, Computed, Record<PropNames, <span class="built_in">any</span>>>;</span><br><span class="line"> <span class="comment">// ideally, the return type should just contain Props, not Record<keyof Props, any>. But TS requires to have Base constructors with the same return type.</span></span><br><span class="line"> <span class="keyword">new</span> <Data = object, Methods = object, Computed = object, Props = object>(options?: ThisTypedComponentOptionsWithRecordProps<V, Data, Methods, Computed, Props>): CombinedVueInstance<V, Data, Methods, Computed, Record<keyof Props, <span class="built_in">any</span>>>;</span><br><span class="line"> <span class="keyword">new</span> (options?: ComponentOptions<V>): CombinedVueInstance<V, object, object, object, Record<keyof object, <span class="built_in">any</span>>>;</span><br><span class="line"></span><br><span class="line"> extend<Data, Methods, Computed, PropNames <span class="keyword">extends</span> <span class="built_in">string</span> = never>(options?: ThisTypedComponentOptionsWithArrayProps<V, Data, Methods, Computed, PropNames>): ExtendedVue<V, Data, Methods, Computed, Record<PropNames, <span class="built_in">any</span>>>;</span><br><span class="line"> extend<Data, Methods, Computed, Props>(options?: ThisTypedComponentOptionsWithRecordProps<V, Data, Methods, Computed, Props>): ExtendedVue<V, Data, Methods, Computed, Props>;</span><br><span class="line"> extend<PropNames <span class="keyword">extends</span> <span class="built_in">string</span> = never>(definition: FunctionalComponentOptions<Record<PropNames, <span class="built_in">any</span>>, PropNames[]>): ExtendedVue<V, {}, {}, {}, Record<PropNames, <span class="built_in">any</span>>>;</span><br><span class="line"> extend<Props>(definition: FunctionalComponentOptions<Props, RecordPropsDefinition<Props>>): ExtendedVue<V, {}, {}, {}, Props>;</span><br><span class="line"> extend(options?: ComponentOptions<V>): ExtendedVue<V, {}, {}, {}, {}>;</span><br><span class="line"></span><br><span class="line"> nextTick<T><span class="function">(<span class="params">callback: (<span class="params"><span class="keyword">this</span>: T</span>) => <span class="built_in">void</span>, context?: T</span>): <span class="params">void</span>;</span></span><br><span class="line"><span class="function"> <span class="params">nextTick</span><span class="params">()</span>: <span class="params">Promise</span><<span class="params">void</span>></span></span><br><span class="line"><span class="function"> <span class="params">set</span><<span class="params">T</span>>(<span class="params">object: object, key: <span class="built_in">string</span> | <span class="built_in">number</span>, value: T</span>): <span class="params">T</span>;</span></span><br><span class="line"><span class="function"> <span class="params">set</span><<span class="params">T</span>>(<span class="params">array: T[], key: <span class="built_in">number</span>, value: T</span>): <span class="params">T</span>;</span></span><br><span class="line"><span class="function"> <span class="params">delete</span>(<span class="params">object: object, key: <span class="built_in">string</span> | <span class="built_in">number</span></span>): <span class="params">void</span>;</span></span><br><span class="line"><span class="function"> <span class="params">delete</span><<span class="params">T</span>>(<span class="params">array: T[], key: <span class="built_in">number</span></span>): <span class="params">void</span>;</span></span><br><span class="line"><span class="function"></span></span><br><span class="line"><span class="function"> <span class="params">directive</span>(<span class="params"></span></span></span><br><span class="line"><span class="function"><span class="params"> id: <span class="built_in">string</span>,</span></span></span><br><span class="line"><span class="function"><span class="params"> definition?: DirectiveOptions | DirectiveFunction</span></span></span><br><span class="line"><span class="function"><span class="params"> </span>): <span class="params">DirectiveOptions</span>;</span></span><br><span class="line"><span class="function"> <span class="params">filter</span>(<span class="params">id: <span class="built_in">string</span>, definition?: <span class="built_in">Function</span></span>): <span class="params">Function</span>;</span></span><br><span class="line"><span class="function"></span></span><br><span class="line"><span class="function"> <span class="params">component</span>(<span class="params">id: <span class="built_in">string</span></span>): <span class="params">VueConstructor</span>;</span></span><br><span class="line"><span class="function"> <span class="params">component</span><<span class="params">VC</span> <span class="params">extends</span> <span class="params">VueConstructor</span>>(<span class="params">id: <span class="built_in">string</span>, constructor: VC</span>): <span class="params">VC</span>;</span></span><br><span class="line"><span class="function"> <span class="params">component</span><<span class="params">Data</span>, <span class="params">Methods</span>, <span class="params">Computed</span>, <span class="params">Props</span>>(<span class="params">id: <span class="built_in">string</span>, definition: AsyncComponent<Data, Methods, Computed, Props></span>): <span class="params">ExtendedVue</span><<span class="params">V</span>, <span class="params">Data</span>, <span class="params">Methods</span>, <span class="params">Computed</span>, <span class="params">Props</span>>;</span></span><br><span class="line"><span class="function"> <span class="params">component</span><<span class="params">Data</span>, <span class="params">Methods</span>, <span class="params">Computed</span>, <span class="params">PropNames</span> <span class="params">extends</span> <span class="params">string</span> = <span class="params">never</span>>(<span class="params">id: <span class="built_in">string</span>, definition?: ThisTypedComponentOptionsWithArrayProps<V, Data, Methods, Computed, PropNames></span>): <span class="params">ExtendedVue</span><<span class="params">V</span>, <span class="params">Data</span>, <span class="params">Methods</span>, <span class="params">Computed</span>, <span class="params">Record</span><<span class="params">PropNames</span>, <span class="params">any</span>>>;</span></span><br><span class="line"><span class="function"> <span class="params">component</span><<span class="params">Data</span>, <span class="params">Methods</span>, <span class="params">Computed</span>, <span class="params">Props</span>>(<span class="params">id: <span class="built_in">string</span>, definition?: ThisTypedComponentOptionsWithRecordProps<V, Data, Methods, Computed, Props></span>): <span class="params">ExtendedVue</span><<span class="params">V</span>, <span class="params">Data</span>, <span class="params">Methods</span>, <span class="params">Computed</span>, <span class="params">Props</span>>;</span></span><br><span class="line"><span class="function"> <span class="params">component</span><<span class="params">PropNames</span> <span class="params">extends</span> <span class="params">string</span>>(<span class="params">id: <span class="built_in">string</span>, definition: FunctionalComponentOptions<Record<PropNames, <span class="built_in">any</span>>, PropNames[]></span>): <span class="params">ExtendedVue</span><<span class="params">V</span>, {}, {}, {}, <span class="params">Record</span><<span class="params">PropNames</span>, <span class="params">any</span>>>;</span></span><br><span class="line"><span class="function"> <span class="params">component</span><<span class="params">Props</span>>(<span class="params">id: <span class="built_in">string</span>, definition: FunctionalComponentOptions<Props, RecordPropsDefinition<Props>></span>): <span class="params">ExtendedVue</span><<span class="params">V</span>, {}, {}, {}, <span class="params">Props</span>>;</span></span><br><span class="line"><span class="function"> <span class="params">component</span>(<span class="params">id: <span class="built_in">string</span>, definition?: ComponentOptions<V></span>): <span class="params">ExtendedVue</span><<span class="params">V</span>, {}, {}, {}, {}>;</span></span><br><span class="line"><span class="function"></span></span><br><span class="line"><span class="function"> <span class="params">use</span><<span class="params">T</span>>(<span class="params">plugin: PluginObject<T> | PluginFunction<T>, options?: T</span>): <span class="params">VueConstructor</span><<span class="params">V</span>>;</span></span><br><span class="line"><span class="function"> <span class="params">use</span>(<span class="params">plugin: PluginObject<<span class="built_in">any</span>> | PluginFunction<<span class="built_in">any</span>>, ...options: <span class="built_in">any</span>[]</span>): <span class="params">VueConstructor</span><<span class="params">V</span>>;</span></span><br><span class="line"><span class="function"> <span class="params">mixin</span>(<span class="params">mixin: VueConstructor | ComponentOptions<Vue></span>): <span class="params">VueConstructor</span><<span class="params">V</span>>;</span></span><br><span class="line"><span class="function"> <span class="params">compile</span>(<span class="params">template: <span class="built_in">string</span></span>): {</span></span><br><span class="line"><span class="function"> <span class="params">render</span>(<span class="params">createElement: <span class="keyword">typeof</span> Vue.prototype.$createElement</span>): <span class="params">VNode</span>;</span></span><br><span class="line"><span class="function"> <span class="params">staticRenderFns</span>: (<span class="params">(<span class="params"></span>) => VNode</span>)[];</span></span><br><span class="line"><span class="function"> };</span></span><br><span class="line"><span class="function"></span></span><br><span class="line"><span class="function"> <span class="params">observable</span><<span class="params">T</span>>(<span class="params">obj: T</span>): <span class="params">T</span>;</span></span><br><span class="line"><span class="function"></span></span><br><span class="line"><span class="function"> <span class="params">util</span>: {</span></span><br><span class="line"><span class="function"> <span class="params">warn</span>(<span class="params">msg: <span class="built_in">string</span>, vm?: InstanceType<VueConstructor></span>): <span class="params">void</span>;</span></span><br><span class="line"><span class="function"> };</span></span><br><span class="line"><span class="function"></span></span><br><span class="line"><span class="function"> <span class="params">config</span>: <span class="params">VueConfiguration</span>;</span></span><br><span class="line"><span class="function"> <span class="params">version</span>: <span class="params">string</span>;</span></span><br><span class="line"><span class="function">}</span></span><br></pre></td></tr></table></figure>
<h2 id="zhuang-shi-qi-jiang-vue-class-zhuan-huan-wei-pei-zhi-dui-xiang-de-guo-cheng">装饰器将 vue class 转换为配置对象的过程</h2>
<p>下面我们讲一下 vue 的装饰器是如何将 vue class 形式的组件,转换为 vue 引擎能识别的传统的配置对象的。</p>
<h3 id="zhuang-shi-qi-ding-yi">装饰器定义</h3>
<p>装饰器的定义如下:</p>
<blockquote>
<p>装饰器是一种特殊类型的声明,它能够被附加到类声明,方法, 访问符,属性或参数上。 装饰器使用 @expression这种形式,expression求值后必须为一个函数,它会在运行时被调用,被装饰的声明信息做为参数传入。</p>
</blockquote>
<p>简单示例如下:</p>
<figure class="highlight ts"><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></pre></td><td class="code"><pre><span class="line"><span class="function"><span class="keyword">function</span> <span class="title">red</span>(<span class="params">target</span>) </span>{</span><br><span class="line"> target.color = <span class="string">'red'</span>;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="meta">@red</span></span><br><span class="line"><span class="keyword">class</span> MyComponent {</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line">MyComponent.color <span class="comment">// 'red'</span></span><br></pre></td></tr></table></figure>
<p>我们定义了一个 red 装饰器,作用是给被装饰类添加一个值为 <code>'red'</code> 的 color 属性。</p>
<p>我们看到,装饰器本质上就是一个函数,可以对数据做一定的转换(修饰)。</p>
<p>我们还可以利用装饰器工厂,来提高装饰器的复用性,例如我们想要一个可以给组件添加任意颜色的装饰器,则可以这样写:</p>
<figure class="highlight ts"><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"><span class="function"><span class="keyword">function</span> <span class="title">addColor</span>(<span class="params">color</span>) </span>{</span><br><span class="line"> <span class="keyword">return</span> (target) {</span><br><span class="line"> target.color;</span><br><span class="line"> }</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="meta">@addColor</span>(<span class="string">'red'</span>)</span><br><span class="line"><span class="keyword">class</span> MyComponent1 {</span><br><span class="line">}</span><br><span class="line">MyComponent1.color <span class="comment">// 'red'</span></span><br><span class="line"></span><br><span class="line"><span class="meta">@addColor</span>(<span class="string">'blue'</span>)</span><br><span class="line"><span class="keyword">class</span> MyComponent2 {</span><br><span class="line">}</span><br><span class="line">MyComponent2.color <span class="comment">// 'blue'</span></span><br></pre></td></tr></table></figure>
<p>装饰器工厂,说白了,就是一个生成装饰器的函数</p>
<p>装饰器的概念,就简单介绍到这里。</p>
<h3 id="zhuang-shi-qi-de-zhi-xing-shun-xu">装饰器的执行顺序</h3>
<p>在TypeScript中,装饰器的执行顺序为:</p>
<ol>
<li>类成员装饰器,一般按书写顺序从前往后执行;</li>
<li>类装饰器;</li>
</ol>
<p>关于装饰器调用顺序,网上几乎所有中文资料都是错的!</p>
<p>因此对于下面使用装饰器的 Vue class 组件:</p>
<figure class="highlight ts"><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"><span class="keyword">import</span> { Vue, Component, Prop, Ref } <span class="keyword">from</span> <span class="string">'vue-property-decorator'</span></span><br><span class="line"></span><br><span class="line"><span class="meta">@Component</span></span><br><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> <span class="keyword">class</span> YourComponent <span class="keyword">extends</span> Vue {</span><br><span class="line"> <span class="meta">@Ref</span> readonly elementRef!: HTMLElement;</span><br><span class="line"> <span class="meta">@Prop</span>({ <span class="keyword">default</span>: <span class="string">'default value'</span> }) readonly title!: <span class="built_in">string</span></span><br><span class="line"></span><br><span class="line"> message: <span class="built_in">string</span> = <span class="string">'hello, world'</span>;</span><br><span class="line"></span><br><span class="line"> onClick(): <span class="built_in">void</span> {}</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>会先执行类属性上的装饰器,如 @Ref、@Prop,这两个装饰器,会将被修饰的属性收集到对应类型的数组中(refs 数组,props 数组),然后是方法的装饰器,最后会执行 @Component ,对刚才装饰器收集的属性、方法,以及为修饰的属性、方法做分类处理,最终转成 Vue 引擎能识别的、原始的 vue 组件配置对象:</p>
<figure class="highlight ts"><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></pre></td><td class="code"><pre><span class="line"><span class="keyword">export</span> <span class="keyword">default</span> {</span><br><span class="line"> props: {</span><br><span class="line"> title: {</span><br><span class="line"> <span class="keyword">default</span>: <span class="string">'default value'</span>,</span><br><span class="line"> },</span><br><span class="line"> },</span><br><span class="line"></span><br><span class="line"> data() {</span><br><span class="line"> message: <span class="string">'hello, world'</span>,</span><br><span class="line"> },</span><br><span class="line"></span><br><span class="line"> methods: {</span><br><span class="line"> onClick() {}</span><br><span class="line"> },</span><br><span class="line"></span><br><span class="line"> computed: {</span><br><span class="line"> elementRef: {</span><br><span class="line"> cache: <span class="literal">false</span>,</span><br><span class="line"> <span class="keyword">get</span>(<span class="keyword">this</span>: Vue) {</span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">this</span>.$refs[<span class="string">'elementRef'</span>]</span><br><span class="line"> },</span><br><span class="line"> }</span><br><span class="line"> }</span><br></pre></td></tr></table></figure>
<p>使用 vue-property-decorator 装饰器,将 vue class 转换为 vue 配置对象的过程,就解释完了。</p>
<h2 id="can-kao">参考</h2>
<ul>
<li><a href="https://www.tslang.cn/docs/handbook/decorators.html" target="_blank" rel="noopener">装饰器</a></li>
</ul>
</div>
<footer class="post-footer">
<div class="post-eof"></div>
</footer>
</article>
<article itemscope itemtype="http://schema.org/Article" class="post-block" lang="en">
<link itemprop="mainEntityOfPage" href="https://adispring.github.io/2021/11/15/Lerna-Cheatsheet/">
<span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
<meta itemprop="image" content="/images/avatar.gif">
<meta itemprop="name" content="wangzengdi">
<meta itemprop="description" content="[email protected]">
</span>
<span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
<meta itemprop="name" content="wangzengdi's Blog">
</span>
<header class="post-header">
<h2 class="post-title" itemprop="name headline">
<a href="/2021/11/15/Lerna-Cheatsheet/" class="post-title-link" itemprop="url">Lerna 备忘录</a>
</h2>
<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">Posted on</span>
<time title="Created: 2021-11-15 15:35:12" itemprop="dateCreated datePublished" datetime="2021-11-15T15:35:12+00:00">2021-11-15</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-calendar-check"></i>
</span>
<span class="post-meta-item-text">Edited on</span>
<time title="Modified: 2022-04-27 12:20:36" itemprop="dateModified" datetime="2022-04-27T12:20:36+00:00">2022-04-27</time>
</span>
</div>
</header>
<div class="post-body" itemprop="articleBody">
<p><a href="https://github.com/lerna/lerna" target="_blank" rel="noopener">Lerna</a> 本身是一个非常好的 monorepo (单仓库-多项目)管理工具,当经常会因为时间久了不用,而导致生疏,因此总结一些常用的 Lerna 操作,以备后续用到时参考。</p>
</div>
<footer class="post-footer">
<div class="post-eof"></div>
</footer>
</article>
<article itemscope itemtype="http://schema.org/Article" class="post-block" lang="en">
<link itemprop="mainEntityOfPage" href="https://adispring.github.io/2021/09/10/nvm-cli-advance-guide/">
<span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
<meta itemprop="image" content="/images/avatar.gif">
<meta itemprop="name" content="wangzengdi">
<meta itemprop="description" content="[email protected]">
</span>
<span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
<meta itemprop="name" content="wangzengdi's Blog">
</span>
<header class="post-header">
<h2 class="post-title" itemprop="name headline">
<a href="/2021/09/10/nvm-cli-advance-guide/" class="post-title-link" itemprop="url">nvm 高级命令指南</a>
</h2>
<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">Posted on</span>
<time title="Created: 2021-09-10 10:30:56" itemprop="dateCreated datePublished" datetime="2021-09-10T10:30:56+00:00">2021-09-10</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-calendar-check"></i>
</span>
<span class="post-meta-item-text">Edited on</span>
<time title="Modified: 2022-04-27 12:20:36" itemprop="dateModified" datetime="2022-04-27T12:20:36+00:00">2022-04-27</time>
</span>
</div>
</header>
<div class="post-body" itemprop="articleBody">
<p>本文整理了一些 nvm 不常用、但非常有用的命令。主要分为以下几大类:</p>
<ul>
<li>reinstall-packages <version> Reinstall global <code>npm</code> packages contained in <version> to current version</version></version></li>
</ul>
<p>由于使用 npm install -g <package> 安装全局 npm 包,是安装到当前使用的版本的 node 下面,在安装新版本的 node 或者 切换 node 版本后,之前安装的全局 npm 包往往就不生效了,比如,切换 node 版本后,<code>yarn</code> 命令失效。</package></p>
<p>这时可以用 <code>nvm reinstall-packages <version></code> 来将之前 node 下面所有的全局 npm 包都重新安装到当前使用的 node 版本中。</p>
<p>若想查看当前 node 版本中都安装了哪些全局 npm 包,可以使用 <code>npm ls -g</code> 来查看。</p>
</div>
<footer class="post-footer">
<div class="post-eof"></div>
</footer>
</article>
<article itemscope itemtype="http://schema.org/Article" class="post-block" lang="en">
<link itemprop="mainEntityOfPage" href="https://adispring.github.io/2021/07/25/VSCode-Cheat-Sheet/">
<span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
<meta itemprop="image" content="/images/avatar.gif">
<meta itemprop="name" content="wangzengdi">
<meta itemprop="description" content="[email protected]">
</span>
<span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
<meta itemprop="name" content="wangzengdi's Blog">
</span>
<header class="post-header">
<h2 class="post-title" itemprop="name headline">
<a href="/2021/07/25/VSCode-Cheat-Sheet/" class="post-title-link" itemprop="url">VSCode Cheat Sheet -- 备忘录</a>
</h2>
<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">Posted on</span>
<time title="Created: 2021-07-25 10:07:23" itemprop="dateCreated datePublished" datetime="2021-07-25T10:07:23+00:00">2021-07-25</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-calendar-check"></i>
</span>
<span class="post-meta-item-text">Edited on</span>
<time title="Modified: 2022-04-27 12:20:36" itemprop="dateModified" datetime="2022-04-27T12:20:36+00:00">2022-04-27</time>
</span>
</div>
</header>
<div class="post-body" itemprop="articleBody">
<p>VSCode 入门简单、操作方便、扩展灵活的特点,让 VSCode 在编程届(尤其是前端)越来越流行;</p>
<p>而相比之下,Emacs 学习和维护成本都很高,导致用户群较小,开发和维护面临后继无人的局面。Emacs 相对于 VSCode 的优势已经不明显。Emacs 的优势:快捷键、magit 等,在 VSCode 上也都有相应的实现,因此从 Emacs 迁移到 VSCode 的成本也没有想象的那么大。</p>
<p>而缺点却比较多:</p>
<ul>
<li>出问题时,提示不友好,不知道错在哪里;</li>
<li>各种小问题不断,每个小问题可能都要查半天,时间成本比较高;</li>
<li>Emacs 配置比较复杂,需要学习 elisp 语言;</li>
</ul>
<p>鉴于上述几点,本人也要从使用了多年的 Emacs 迁移到 VSCode 了。在此想到了几句话:唯一不变的是变化,选择比努力更重要。</p>
<p>本文将是本人学习 VSCode 总结的备忘录,后面遇到之前用过、总结过、但不熟悉的地方,可以快速查找到解决方法。主要是快捷键</p>
<h2 id="mac-os-kuai-jie-jian">macOS 快捷键</h2>
<h3 id="ming-ci-jie-shi">名词解释</h3>
<ul>
<li>Explorer: 左侧边栏;</li>
<li>Editor: 编辑区;</li>
<li>Editor Group: 编辑组,一个编辑组可以包含多个打开的文件。可以使用 <code>CMD + \</code> 来分割编辑组;</li>
</ul>
<h3 id="ge-qu-yu-qie-huan">各区域切换</h3>
<table>
<thead>
<tr>
<th>快捷键</th>
<th>解释</th>
</tr>
</thead>
<tbody>
<tr>
<td>CMD + 0</td>
<td>左侧边栏</td>
</tr>
<tr>
<td>CMD + 1, CMD + 2, CMD + 3…</td>
<td>聚焦 1st,2nd,3rd editor group</td>
</tr>
<tr>
<td>CMD + B</td>
<td>切换左侧边栏是否可见</td>
</tr>
</tbody>
</table>
<h3 id="she-zhi">设置</h3>
<!-- | ⌘k ⌘s | 调出快捷键设置面板 | -->
</div>
<footer class="post-footer">
<div class="post-eof"></div>
</footer>
</article>
<article itemscope itemtype="http://schema.org/Article" class="post-block" lang="en">
<link itemprop="mainEntityOfPage" href="https://adispring.github.io/2021/04/30/npm-cli-advance-guide/">
<span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
<meta itemprop="image" content="/images/avatar.gif">
<meta itemprop="name" content="wangzengdi">
<meta itemprop="description" content="[email protected]">
</span>
<span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
<meta itemprop="name" content="wangzengdi's Blog">
</span>
<header class="post-header">
<h2 class="post-title" itemprop="name headline">
<a href="/2021/04/30/npm-cli-advance-guide/" class="post-title-link" itemprop="url">npm 命令高级指南</a>
</h2>
<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">Posted on</span>
<time title="Created: 2021-04-30 11:23:56" itemprop="dateCreated datePublished" datetime="2021-04-30T11:23:56+00:00">2021-04-30</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-calendar-check"></i>
</span>
<span class="post-meta-item-text">Edited on</span>
<time title="Modified: 2022-04-27 12:20:36" itemprop="dateModified" datetime="2022-04-27T12:20:36+00:00">2022-04-27</time>
</span>
</div>
</header>
<div class="post-body" itemprop="articleBody">
<p>本文整理了一些 npm 不常用、但非常有用的命令。主要分为以下几大类:</p>
<ul>
<li>
<p>查看 npm 源(registry) 上的 npm 包信息</p>
<ul>
<li>npm view</li>
</ul>
</li>
<li>
<p>开发 npm 包时,用到的命令</p>
<ul>
<li>npm publish</li>
<li>npm pack</li>
<li>npm link & npm unlink</li>
<li>npm set-script</li>
</ul>
</li>
<li>
<p>查看已安装的 npm 包的本地信息</p>
<ul>
<li>npm ls</li>
<li>npm edit</li>
<li>npm explore</li>
<li>npm explain | npm why</li>
</ul>
</li>
<li>
<p>浏览器查看 npm 包信息</p>
<ul>
<li>npm docs</li>
<li>npm repo</li>
</ul>
</li>
<li>
<p>使用 npm 包开发其他项目时,用到的命令</p>
<ul>
<li>npm outdated</li>
<li>npm update</li>
</ul>
</li>
<li>
<p>其他 npm 命令</p>
<ul>
<li>npm config</li>
<li>npm bin</li>
<li>npm completion</li>
</ul>
</li>
</ul>
<h1 id="cha-kan-npm-yuan-registry-shang-de-npm-bao-xin-xi">查看 npm 源(registry) 上的 npm 包信息</h1>
<ul>
<li>npm view: 最为灵活、最为强大的 查看 npm 包信息的命令;</li>
</ul>
<p>由于 <code>npm view</code> 太灵活,所以需要单独一小节进行讲解。</p>
<h2 id="npm-view">npm view</h2>
<p>查看 npm 源上包的信息</p>
<figure class="highlight bash"><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">npm view [<@scope>/]<name>[@<version>] [<field>[.<subfield>]...]</span><br><span class="line"></span><br><span class="line">aliases: info, show, v</span><br></pre></td></tr></table></figure>
<h3 id="cha-kan-bao-de-ji-ben-xin-xi">查看包的基本信息</h3>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm view <pkg></span><br></pre></td></tr></table></figure>
<p>示例:</p>
<figure class="highlight bash"><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></pre></td><td class="code"><pre><span class="line">› npm view ramda</span><br><span class="line"></span><br><span class="line">[email protected] | MIT | deps: none | versions: 52</span><br><span class="line">A practical functional library <span class="keyword">for</span> JavaScript programmers.</span><br><span class="line">https://ramdajs.com/</span><br><span class="line"></span><br><span class="line">dist</span><br><span class="line">.tarball: http://r.npm.sankuai.com/ramda/download/ramda-0.27.1.tgz</span><br><span class="line">.shasum: 66fc2df3ef873874ffc2da6aa8984658abacf5c9</span><br><span class="line"></span><br><span class="line">maintainers:</span><br><span class="line">- aromano <[email protected]></span><br><span class="line">- bradcomp <[email protected]></span><br><span class="line">- ...</span><br><span class="line"></span><br><span class="line">dist-tags:</span><br><span class="line">0.2.0: 0.2.0 es-rc: 0.24.1-es.rc3 latest: 0.27.1</span><br><span class="line"></span><br><span class="line">published 9 months ago by davidchambers <[email protected]></span><br></pre></td></tr></table></figure>
<h3 id="geng-jia-ling-huo-de-cha-kan-bao-de-xiang-xi-xin-xi">更加灵活的查看包的详细信息</h3>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm view <pkg>@<version> <field>[.<subfield>]...</span><br></pre></td></tr></table></figure>
<h4 id="cha-kan-bao-de-yi-lai">查看包的依赖</h4>
<figure class="highlight bash"><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">› npm view http-server dependencies</span><br><span class="line">{</span><br><span class="line"> <span class="string">'basic-auth'</span>: <span class="string">'^1.0.3'</span>,</span><br><span class="line"> colors: <span class="string">'^1.4.0'</span>,</span><br><span class="line"> corser: <span class="string">'^2.0.1'</span>,</span><br><span class="line"> ecstatic: <span class="string">'^3.3.2'</span>,</span><br><span class="line"> <span class="string">'http-proxy'</span>: <span class="string">'^1.18.0'</span>,</span><br><span class="line"> minimist: <span class="string">'^1.2.5'</span>,</span><br><span class="line"> opener: <span class="string">'^1.5.1'</span>,</span><br><span class="line"> portfinder: <span class="string">'^1.0.25'</span>,</span><br><span class="line"> <span class="string">'secure-compare'</span>: <span class="string">'3.0.1'</span>,</span><br><span class="line"> union: <span class="string">'~0.5.0'</span></span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<h4 id="cha-kan-bao-de-zui-xin-ban-ben">查看包的最新版本</h4>
<figure class="highlight bash"><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">› npm view ramda version</span><br><span class="line">0.27.1</span><br></pre></td></tr></table></figure>
<h4 id="cha-kan-bao-fa-bu-de-suo-you-ban-ben">查看包发布的所有版本</h4>
<figure class="highlight bash"><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">› npm view ramda versions</span><br><span class="line">[</span><br><span class="line"> <span class="string">'0.1.0'</span>, <span class="string">'0.1.1'</span>, <span class="string">'0.1.2'</span>,</span><br><span class="line"> <span class="string">'0.1.4'</span>, <span class="string">'0.1.5'</span>, <span class="string">'0.2.0'</span>,</span><br><span class="line"> <span class="string">'0.2.1'</span>, <span class="string">'0.2.2'</span>, <span class="string">'0.2.3'</span>,</span><br><span class="line"> <span class="string">'0.2.4'</span>, <span class="string">'0.3.0'</span>, <span class="string">'0.4.0'</span>,</span><br><span class="line"> <span class="string">'0.4.1'</span>, <span class="string">'0.4.2'</span>, <span class="string">'0.4.3'</span>,</span><br><span class="line"> <span class="string">'0.5.0'</span>, <span class="string">'0.6.0'</span>, <span class="string">'0.7.0'</span>,</span><br><span class="line"> <span class="string">'0.7.1'</span>, <span class="string">'0.7.2'</span>, <span class="string">'0.8.0'</span>,</span><br><span class="line"> <span class="string">'0.9.0'</span>, <span class="string">'0.9.1'</span>, <span class="string">'0.10.0'</span>,</span><br><span class="line"> <span class="string">'0.11.0'</span>, <span class="string">'0.12.0'</span>, <span class="string">'0.13.0'</span>,</span><br><span class="line"> <span class="string">'0.14.0'</span>, <span class="string">'0.15.0'</span>, <span class="string">'0.15.1'</span>,</span><br><span class="line"> <span class="string">'0.16.0'</span>, <span class="string">'0.17.0'</span>, <span class="string">'0.17.1'</span>,</span><br><span class="line"> <span class="string">'0.18.0'</span>, <span class="string">'0.19.0'</span>, <span class="string">'0.19.1'</span>,</span><br><span class="line"> <span class="string">'0.20.0'</span>, <span class="string">'0.20.1'</span>, <span class="string">'0.21.0'</span>,</span><br><span class="line"> <span class="string">'0.22.0'</span>, <span class="string">'0.22.1'</span>, <span class="string">'0.23.0'</span>,</span><br><span class="line"> <span class="string">'0.24.0'</span>, <span class="string">'0.24.1-es.rc1'</span>, <span class="string">'0.24.1-es.rc2'</span>,</span><br><span class="line"> <span class="string">'0.24.1-es.rc3'</span>, <span class="string">'0.24.1'</span>, <span class="string">'0.25.0'</span>,</span><br><span class="line"> <span class="string">'0.26.0'</span>, <span class="string">'0.26.1'</span>, <span class="string">'0.27.0'</span>,</span><br><span class="line"> <span class="string">'0.27.1'</span></span><br><span class="line">]</span><br></pre></td></tr></table></figure>
<h4 id="cha-kan-zhi-ding-ban-ben-fan-wei-nei-de-bao-de-fa-bu-qing-kuang">查看指定版本范围内的包的发布情况</h4>
<p>查看自 0.25.0 以来,所有版本 ramda 包的信息</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm view ramda@<span class="string">'>=0.25.0'</span></span><br></pre></td></tr></table></figure>
<h4 id="cha-kan-npm-bao-guan-wang-di-zhi">查看 npm 包官网地址</h4>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm view ramda homepage</span><br></pre></td></tr></table></figure>
<h4 id="cha-kan-npm-bao-cang-ku-di-zhi">查看 npm 包仓库地址</h4>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm view ramda repository.url</span><br></pre></td></tr></table></figure>
<h4 id="tong-guo-shell-jiao-ben-zu-he-chu-ling-huo-de-cha-xun-ming-ling">通过 shell 脚本,组合出灵活的查询命令</h4>
<p>可以通过一些 Shell 脚本轻松查看有关依赖项的信息。例如,要查看有关ronn所依赖的opts版本的所有数据,如下所示:</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm view opts@$(npm view ronn dependencies.opts)</span><br></pre></td></tr></table></figure>
<p>更多 <code>npm view</code> 的高级用法,可以查看 <a href="https://docs.npmjs.com/cli/v7/commands/npm-view" target="_blank" rel="noopener">npm view 官方文档</a></p>
<h1 id="kai-fa-npm-bao-she-ji-de-ming-ling">开发 npm 包涉及的命令</h1>
<ul>
<li>
<p>npm publish: 将包发布到 npm 源(registry) 上去;</p>
</li>
<li>
<p>npm pack: 打包;</p>
</li>
<li>
<p>npm link: 将当前 package 文件夹软链到全局 npm 环境中;</p>
</li>
<li>
<p>npm unlink: 断开全局软链时,其实就是 npm uninstall 的别名;</p>
</li>
<li>
<p>npm set-script: 在 package.json 的 <code>"scripts"</code> 字段中设置任务;</p>
</li>
</ul>
<h2 id="npm-publish-fa-bao">npm publish – 发包</h2>
<p>将包发布到 npm 源(registry) 上去。</p>
<h3 id="mo-ni-fa-bao">模拟发包</h3>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm publish --dry-run</span><br></pre></td></tr></table></figure>
<p><code>npm publish --dry-run</code> 只是模拟发包,并不会真正发包。会将发包过程中的所有信息都打印出来,用作发包前进行信息确认。也可以使用 <code>npm pack --dry-run</code></p>
<h3 id="fa-bu-de-bao-zhong-bao-han-de-wen-jian">发布的包中包含的文件</h3>
<p>要查看软件包中将包含的内容,请运行 <code>npx npm-packlist</code>。默认情况下,所有文件都包括在内,但以下情况除外:</p>
<ul>
<li>
<p>始终包含与软件包安装和分发相关的某些文件。例如,<code>package.json</code>,<code>README.md</code>,<code>LICENSE</code> 等。</p>
</li>
<li>
<p>如果 <code>package.json</code> 中有一个 <code>"files"</code> 列表字段,则仅包含 <code>"files"</code> 指定的文件。(如果指定了目录,则将遵循相同的忽略规则,以递归方式遍历目录并包含目录的内容。)</p>
</li>
<li>
<p>如果存在 <code>.gitignore</code> 或 <code>.npmignore</code> 文件,则其中的被忽略文件以及所有子目录都将从软件包中排除。如果两个文件都存在,则将忽略 <code>.gitignore</code>,而仅使用 <code>.npmignore</code>。</p>
<p><code>.npmignore</code> 文件遵循与 <code>.gitignore</code> 文件相同的模式规则</p>
</li>
<li>
<p><strong>需要特别注意的是:如果文件匹配某些模式,则除非明确将其添加到 <code>package.json</code> 的 “files” 列表中,否则将永远不会将其包括在内,或者在 <code>.npmignore</code> 或 <code>.gitignore</code> 文件中使用 <code>!</code> ,来强制包含需要发布的文件</strong>。</p>
<p>例如,npm 发包,默认是会忽略 <code>.npmrc</code> 文件的,如果我确实需要将 <code>.npmrc</code> 包含进发布的包中,则需要使用在 <code>.npmignore</code> 或 <code>.gitignore</code> 中写入规则 <code>!.npmrc</code>,<code>!.npmrc</code> 表示强制包含 <code>.npmrc</code>。</p>
</li>
<li>
<p>符号链接永远不会包含在 npm 软件包中。</p>
</li>
</ul>
<p>有关已发布的软件包中包含的内容以及如何构建该软件包的详细信息,请查看 <a href="https://docs.npmjs.com/cli/v7/using-npm/developers" target="_blank" rel="noopener">开发者须知</a> 。</p>
<h2 id="npm-pack-da-bao">npm pack – 打包</h2>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm pack [[<@scope>/]<pkg>...] [--dry-run]</span><br></pre></td></tr></table></figure>
<p>一般会用到 <code>npm pack --dry-run</code> ,看一下即将发布的包的打包情况。加了 <code>--dry-run</code> 会后,命令不会真正的执行,只是把之间结果打印出来,以供调试使用。</p>
<h2 id="npm-link-amp-npm-unlink-ben-di-kai-fa">npm link & npm unlink - 本地开发</h2>
<p>本地调试利器</p>
<h3 id="npm-link">npm link</h3>
<p>将当前 package 文件夹软链到全局 npm 环境中。开发某个 npm 包时,本地调试非常好用。避免了在开发过程中不断重复发包的困扰。</p>
<p>npm link 分两步:</p>
<ul>
<li>
<p>软链当前的 package;</p>
</li>
<li>
<p>使用软链过的 package;</p>
</li>
</ul>
<p>如下所示:</p>
<figure class="highlight bash"><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"><span class="built_in">cd</span> ~/projects/node-redis <span class="comment"># go into the package directory</span></span><br><span class="line">npm link <span class="comment"># creates global link</span></span><br><span class="line"><span class="built_in">cd</span> ~/projects/node-bloggy <span class="comment"># go into some other package directory.</span></span><br><span class="line">npm link redis <span class="comment"># link-install the package</span></span><br></pre></td></tr></table></figure>
<h3 id="npm-unlink">npm unlink</h3>
<p>当本地调试完成,想要断开全局软链时,运行下面命令:</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm unlink <pkg> -g</span><br></pre></td></tr></table></figure>
<p><code>npm unlink</code> 会将 <pkg> 从全局的 npm 环境中移除(断开软链)。</pkg></p>
<p>注:<code>npm unlink</code> 其实是 <code>npm uninstall</code> 的别名,所以运行 <code>npm unlink <pkg> -g</code> 等价于 <code>npm uninstall <pkg> -g</code> 。</p>
<h3 id="npm-set-script">npm set-script</h3>
<p>在 package.json 的 <code>"scripts"</code> 字段中设置任务。</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm <span class="built_in">set</span>-script [<script>] [<<span class="built_in">command</span>>]</span><br></pre></td></tr></table></figure>
<p>如果开发的 npm 包在安装时,需要动态修改项目中 <code>package.json</code> 文件的 <code>"scripts"</code> ,则可以使用该命令进行设置。</p>
<p>示例:</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm <span class="built_in">set</span>-script start <span class="string">"http-server ."</span></span><br></pre></td></tr></table></figure>
<figure class="highlight json"><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></pre></td><td class="code"><pre><span class="line">{</span><br><span class="line"> <span class="attr">"name"</span>: <span class="string">"my-project"</span>,</span><br><span class="line"> <span class="attr">"scripts"</span>: {</span><br><span class="line"> <span class="attr">"start"</span>: <span class="string">"http-server ."</span>,</span><br><span class="line"> <span class="attr">"test"</span>: <span class="string">"some existing value"</span></span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure>
<p>向 <code>"scripts"</code> 中添加 <code>"start"</code> 脚本。</p>
<h1 id="cha-kan-yi-an-zhuang-de-npm-bao-de-ben-di-xin-xi">查看已安装的 npm 包的本地信息</h1>
<ul>
<li>
<p>npm ls: 列出安装的 packages,或者指定 package 的依赖树;</p>
</li>
<li>
<p>npm edit: 使用默认的编辑器打开当前项目中指定的 npm 包;</p>
</li>
<li>
<p>npm explore: 进入指定的被安装的 npm 包的目录;</p>
</li>
<li>
<p>npm explain | npm why: 解释 packages 被安装的原因。主要是把指定包的依赖链条打印出来;</p>
</li>
</ul>
<h2 id="npm-ls">npm ls</h2>
<p>列出安装的 packages。</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm ls [<pkg> -g]</span><br></pre></td></tr></table></figure>
<h3 id="da-yin-chu-dang-qian-xiang-mu-yi-an-zhuang-de-shou-ceng-packages">打印出当前项目已安装的首层 packages</h3>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm ls</span><br></pre></td></tr></table></figure>
<h3 id="suo-you-de-yi-lai-yi-yi-lai-shu-de-xing-shi-da-yin-chu-lai">所有的依赖以依赖树的形式打印出来</h3>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm ls -all</span><br></pre></td></tr></table></figure>
<p>当使用 <code>--all</code> 时,会将所有的依赖以依赖树的形式打印出来。</p>
<h3 id="da-yin-quan-ju-an-zhuang-de-packages">打印全局安装的 packages</h3>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm ls -g</span><br></pre></td></tr></table></figure>
<h3 id="da-yin-zhi-ding-packages-de-an-zhuang-qing-kuang">打印指定 packages 的安装情况</h3>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm ls name@version-range</span><br></pre></td></tr></table></figure>
<p><code>npm ls name@version-range</code> 可以以结构树的形式打印出指定 package 在项目中的安装情况。</p>
<p>也可以使用 <code>npm explain</code> 查看指定的 package 为什么会被安装,作用相当于 <code>npm ls</code> ,只不过展示的顺序是反向的。</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm explain name</span><br></pre></td></tr></table></figure>
<h2 id="npm-edit">npm edit</h2>
<p>使用默认的编辑器,直接打开当前项目已经安装的 package 的文件夹。可以省去手动到 node_modules 中查找 package 的麻烦。</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm edit <pkg></span><br></pre></td></tr></table></figure>
<p>例如:</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm edit prettier</span><br></pre></td></tr></table></figure>
<p>会打开当前项目下的 <code>./node_modules/prettier</code> 目录。</p>
<h3 id="zhi-ding-mo-ren-de-bian-ji-qi-xiu-gai-code-editor-code-bian-liang">指定默认的编辑器,修改 <code>$EDITOR</code> 变量</h3>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line"><span class="built_in">echo</span> <span class="built_in">export</span> EDITOR=<span class="string">"emacsclient -t"</span> >> ~/.zshrc</span><br></pre></td></tr></table></figure>
<h2 id="npm-explore">npm explore</h2>
<p>在命令行中,进入指定的被安装的 package 文件夹中。</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm explore <pkg> [ -- <<span class="built_in">command</span>>]</span><br></pre></td></tr></table></figure>
<p>示例:</p>
<ol>
<li>进入当前项目中某 package 的目录</li>
</ol>
<figure class="highlight bash"><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">// 进入当前项目中安装的 prettier 目录</span><br><span class="line">npm explore prettier</span><br><span class="line"></span><br><span class="line"><span class="built_in">pwd</span></span><br><span class="line">// project/node_modules/prettier</span><br></pre></td></tr></table></figure>
<ol start="2">
<li>进入全局安装的某 package 目录</li>
</ol>
<figure class="highlight bash"><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">// 进入全局安装的 prettier 目录</span><br><span class="line">npm explore prettier -g</span><br><span class="line"></span><br><span class="line"><span class="built_in">pwd</span></span><br><span class="line">// /Users/wangzengdi/.nvm/versions/node/v14.15.4/lib/node_modules/prettier</span><br></pre></td></tr></table></figure>
<h2 id="npm-explain-npm-why">npm explain | npm why</h2>
<p>解释已安装的 packages,被安装的原因。</p>
<p>会将当前指定包的依赖关系打印出来(哪些包依赖的指定的包),可以用于解释为什么一个依赖为什么会被安装多次。</p>
<figure class="highlight bash"><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">npm explain <folder | specifier></span><br><span class="line"></span><br><span class="line"><span class="built_in">alias</span>: why</span><br></pre></td></tr></table></figure>
<p>例如:</p>
<figure class="highlight bash"><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">› npm explain eslint</span><br><span class="line"></span><br><span class="line">[email protected] dev</span><br><span class="line">node_modules/eslint</span><br><span class="line"> dev eslint@<span class="string">"^7.25.0"</span> from the root project</span><br><span class="line"> peer eslint@<span class="string">">= 4.12.1"</span> from [email protected]</span><br><span class="line"> node_modules/babel-eslint</span><br><span class="line"> dev babel-eslint@<span class="string">"^10.1.0"</span> from the root project</span><br><span class="line"> peer eslint@<span class="string">">=7.0.0"</span> from [email protected]</span><br><span class="line"> node_modules/eslint-config-prettier</span><br><span class="line"> dev eslint-config-prettier@<span class="string">"^8.3.0"</span> from the root project</span><br><span class="line"> ...</span><br></pre></td></tr></table></figure>
<p>表示当前项目在 devDependencies 中安装了 7.25.0 版本的 eslint,安装的位置为 <code>node_modules/eslint</code> 。后面的部分表明是哪些包的依赖,导致了 eslint 的安装。</p>
<h1 id="liu-lan-qi-cha-kan-npm-bao-xin-xi">浏览器查看 npm 包信息</h1>
<ul>
<li>
<p>npm docs | npm home: 在浏览器中打开 npm 包官网;</p>
</li>
<li>
<p>npm repo: 在浏览器中打开 npm 包仓库地址;</p>
</li>
</ul>
<h2 id="npm-docs">npm docs</h2>
<p>在浏览器中打开指定 npm 包的官方网站。</p>
<figure class="highlight bash"><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">npm docs [pakname]</span><br><span class="line"></span><br><span class="line">aliases: home</span><br></pre></td></tr></table></figure>
<p>例如</p>
<figure class="highlight bash"><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"><span class="comment"># 会打开 react 官网: https://reactjs.org/</span></span><br><span class="line">npm docs react</span><br><span class="line"></span><br><span class="line"><span class="comment"># 会打开 ramda 官网: https://ramdajs.com/</span></span><br><span class="line">npm docs ramda</span><br></pre></td></tr></table></figure>
<p>npm 的官方网站一般写在 package.json 中的 “homepage” 字段中。</p>
<h2 id="npm-repo">npm repo</h2>
<p>在浏览器中打开指定 npm 包的仓库(一般为 github 仓库)地址。</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm repo [<pkgname> [<pkgname> ...]]</span><br></pre></td></tr></table></figure>
<p>例如</p>
<figure class="highlight bash"><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"><span class="comment"># 会打开 ramda github 仓库: https://github.com/ramda/ramda</span></span><br><span class="line">npm repo ramda</span><br></pre></td></tr></table></figure>
<h1 id="shi-yong-npm-bao-kai-fa-qi-ta-xiang-mu-shi-yong-dao-de-ming-ling">使用 npm 包开发其他项目时,用到的命令</h1>
<h2 id="npm-outdated-vs-npm-update">npm outdated vs npm update</h2>
<h3 id="npm-outdated">npm outdated</h3>
<p>查看项目中是否存在过期的 packages,或者指定的 packages 是否过期</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm outdated [<pkg> ...]</span><br></pre></td></tr></table></figure>
<p>举例</p>
<figure class="highlight bash"><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">› npm outdated</span><br><span class="line">Package Current Wanted Latest Location Depended by</span><br><span class="line">semver-regex 3.1.2 3.1.2 4.0.0 node_modules/semver-regex fe.cli</span><br></pre></td></tr></table></figure>
<p>在某一项目下运行 <code>npm outdated</code>,便可以列出当前项目中所有已经过期的依赖。</p>
<p>如上所示,semver-regex 已经过期了,当前版本为 <code>3.1.2</code>,最新版本为 <code>4.0.0</code>。</p>
<p>想要查看 package 的详细信息,可以使用<code>npm view <pkg></code>,如查看 semver-regex: <code>npm view semver-regex</code>。</p>
<h4 id="cha-kan-quan-ju-yi-jing-guo-qi-de-package">查看全局已经过期的 package</h4>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm outdated -g</span><br></pre></td></tr></table></figure>
<h3 id="npm-update-amp-npm-upgrade">npm update & npm upgrade</h3>
<p>更新 packages,npm update 会将 package 更新到当前已发布的 <strong>最新版本</strong>。</p>
<figure class="highlight bash"><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">npm update [-g] [<pkg>...]</span><br><span class="line"></span><br><span class="line">aliases: up, upgrade</span><br></pre></td></tr></table></figure>
<p>在上文中,我们已经介绍了使用 <code>npm outdated</code> 查看过期的 packages。本段将介绍如何使用 <code>npm update</code> 更新过期的 packages</p>
<h4 id="geng-xin-dang-qian-xiang-mu-zhong-suo-you-guo-qi-de-xiang-mu">更新当前项目中所有过期的项目</h4>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm update</span><br></pre></td></tr></table></figure>
<h4 id="geng-xin-quan-ju-de-guo-qi-xiang-mu">更新全局的过期项目</h4>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm update -g</span><br></pre></td></tr></table></figure>
<h4 id="geng-xin-zhi-ding-de-packages">更新指定的 packages</h4>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm update pkg1 pkg2 ...</span><br></pre></td></tr></table></figure>
<h1 id="qi-ta-npm-ming-ling">其他 npm 命令</h1>
<ul>
<li>
<p>npm config: npm 配置</p>
</li>
<li>
<p>npm bin: 打印 npm 可执行命令 bin 的文件夹</p>
</li>
<li>
<p>npm completion: npm 补全脚本</p>
</li>
</ul>
<h2 id="npm-config">npm config</h2>
<p>npm 配置。用于列出当前 npm 环境的配置信息,或管理 npm 配置文件,一般是 .npmrc。</p>
<h3 id="lie-chu-dang-qian-de-npm-pei-zhi">列出当前的 npm 配置</h3>
<figure class="highlight bash"><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">npm config list</span><br><span class="line"></span><br><span class="line"><span class="comment"># 列出详细配置</span></span><br><span class="line">npm config list -l</span><br></pre></td></tr></table></figure>
<h2 id="npm-bin">npm bin</h2>
<p>打印 npm 可执行命令 bin 的文件夹</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">npm bin [-g | --global]</span><br></pre></td></tr></table></figure>
<h2 id="npm-completion">npm completion</h2>
<p>npm 补全命令脚本, 可以通过下列命令将命令补全脚本注入到 .bashrc 或 .zshrc 中,这样即可以在终端的任何地方使用。</p>
<figure class="highlight bash"><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">npm completion >> ~/.bashrc</span><br><span class="line">npm completion >> ~/.zshrc</span><br></pre></td></tr></table></figure>
</div>
<footer class="post-footer">
<div class="post-eof"></div>
</footer>
</article>
<article itemscope itemtype="http://schema.org/Article" class="post-block" lang="en">
<link itemprop="mainEntityOfPage" href="https://adispring.github.io/2018/09/09/Hexo-Init/">
<span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
<meta itemprop="image" content="/images/avatar.gif">
<meta itemprop="name" content="wangzengdi">
<meta itemprop="description" content="[email protected]">
</span>
<span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
<meta itemprop="name" content="wangzengdi's Blog">
</span>
<header class="post-header">
<h2 class="post-title" itemprop="name headline">
<a href="/2018/09/09/Hexo-Init/" class="post-title-link" itemprop="url">Hexo-Init</a>
</h2>
<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">Posted on</span>
<time title="Created: 2018-09-09 08:54:45" itemprop="dateCreated datePublished" datetime="2018-09-09T08:54:45+00:00">2018-09-09</time>
</span>
<span class="post-meta-item">
<span class="post-meta-item-icon">
<i class="far fa-calendar-check"></i>
</span>
<span class="post-meta-item-text">Edited on</span>
<time title="Modified: 2022-04-27 12:20:36" itemprop="dateModified" datetime="2022-04-27T12:20:36+00:00">2022-04-27</time>
</span>
</div>
</header>
<div class="post-body" itemprop="articleBody">
<h2 id="hexo-cai-keng-zhi-nan">Hexo 踩坑指南</h2>
<h3 id="an-zhuang-zhu-ti">安装主题</h3>
<p>我选用 <a href="https://github.com/theme-next/hexo-theme-next" target="_blank" rel="noopener">next</a> 主题,简洁、素雅</p>
<p>安装指南:</p>
<figure class="highlight bash"><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">$ <span class="built_in">cd</span> hexo</span><br><span class="line">$ git <span class="built_in">clone</span> https://github.com/theme-next/hexo-theme-next themes/next</span><br></pre></td></tr></table></figure>
<h3 id="favicon-pei-zhi">favicon 配置</h3>
<p>需要在 <code>themes/next/_config.yml</code> 中对 favicon 进行配置,我的配置如下</p>
<figure class="highlight bash"><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></pre></td><td class="code"><pre><span class="line"><span class="comment"># ---------------------------------------------------------------</span></span><br><span class="line"><span class="comment"># Site Information Settings</span></span><br><span class="line"><span class="comment"># ---------------------------------------------------------------</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># To get or check favicons visit: https://realfavicongenerator.net</span></span><br><span class="line"><span class="comment"># Put your favicons into `hexo-site/source/` (recommend) or `hexo-site/themes/next/source/images/` directory.</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># Default NexT favicons placed in `hexo-site/themes/next/source/images/` directory.</span></span><br><span class="line"><span class="comment"># And if you want to place your icons in `hexo-site/source/` root directory, you must remove `/images` prefix from pathes.</span></span><br><span class="line"></span><br><span class="line"><span class="comment"># For example, you put your favicons into `hexo-site/source/images` directory.</span></span><br><span class="line"><span class="comment"># Then need to rename & redefine they on any other names, otherwise icons from Next will rewrite your custom icons in Hexo.</span></span><br><span class="line">favicon:</span><br><span class="line"> small: /favicon.ico</span><br><span class="line"> medium: /favicon.ico</span><br><span class="line"> apple_touch_icon: /images/apple-touch-icon-next.ico</span><br><span class="line"> safari_pinned_tab: /logo.svg</span><br><span class="line"> <span class="comment">#android_manifest: /images/manifest.json</span></span><br><span class="line"> <span class="comment">#ms_browserconfig: /images/browserconfig.xml</span></span><br></pre></td></tr></table></figure>
<h3 id="guan-yu-mao-dian-shi-xiao-wen-ti">关于锚点失效问题</h3>
<p>这是 <a href="https://github.com/hexojs/hexo-renderer-markdown-it" target="_blank" rel="noopener">hexo-renderer-markdown-it</a> 的一个 bug,但作者不想修复,认为是其他库的坑,所以我们要参考这个 <a href="https://github.com/hexojs/hexo-renderer-markdown-it/issues/40" target="_blank" rel="noopener">issue</a> ,手动到 node_modules 中修改该库,具体如下:</p>