cainiaoblog 23.2.348 → 23.2.349
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/{app/manual.html → manual.html} +1 -1
- package/package.json +1 -1
- package/CNAME +0 -1
- package/MP_verify_o6dHCK5mIkxNpzvZ.txt +0 -1
- package/README.md +0 -8
- package/about/index.html +0 -55
- package/ads.txt +0 -1
- package/archives/2018/index.html +0 -48
- package/archives/2019/index.html +0 -48
- package/archives/2019/page/2/index.html +0 -48
- package/archives/2020/index.html +0 -48
- package/archives/2021/index.html +0 -48
- package/archives/2022/index.html +0 -48
- package/archives/2023/index.html +0 -48
- package/archives/index.html +0 -48
- package/archives/page/2/index.html +0 -48
- package/archives/page/3/index.html +0 -48
- package/article/10047.html +0 -148
- package/article/10164.html +0 -65
- package/article/10624.html +0 -436
- package/article/10745.html +0 -586
- package/article/11674.html +0 -71
- package/article/11939.html +0 -72
- package/article/12238.html +0 -86
- package/article/1230.html +0 -533
- package/article/13265.html +0 -69
- package/article/13823.html +0 -78
- package/article/14125.html +0 -72
- package/article/14192.html +0 -561
- package/article/14375.html +0 -85
- package/article/14744.html +0 -83
- package/article/14936.html +0 -451
- package/article/1518.html +0 -250
- package/article/15428.html +0 -71
- package/article/15518.html +0 -288
- package/article/15569.html +0 -418
- package/article/1566.html +0 -122
- package/article/16017.html +0 -156
- package/article/16947.html +0 -440
- package/article/17096.html +0 -82
- package/article/17246.html +0 -89
- package/article/17575.html +0 -350
- package/article/179.html +0 -757
- package/article/18039.html +0 -233
- package/article/18071.html +0 -375
- package/article/18142.html +0 -71
- package/article/19909.html +0 -160
- package/article/20014.html +0 -89
- package/article/20021.html +0 -389
- package/article/20037.html +0 -280
- package/article/20056.html +0 -95
- package/article/20093.html +0 -404
- package/article/2021.html +0 -607
- package/article/20459.html +0 -115
- package/article/20613.html +0 -263
- package/article/20635.html +0 -71
- package/article/21317.html +0 -71
- package/article/21320.html +0 -90
- package/article/21782.html +0 -548
- package/article/22230.html +0 -435
- package/article/22237.html +0 -347
- package/article/22398.html +0 -109
- package/article/22422.html +0 -270
- package/article/22565.html +0 -300
- package/article/23046.html +0 -250
- package/article/23083.html +0 -215
- package/article/23195.html +0 -297
- package/article/23301.html +0 -835
- package/article/23589.html +0 -285
- package/article/23655.html +0 -338
- package/article/23864.html +0 -76
- package/article/23914.html +0 -96
- package/article/24169.html +0 -135
- package/article/24581.html +0 -349
- package/article/2475.html +0 -500
- package/article/24826.html +0 -77
- package/article/24924.html +0 -247
- package/article/25164.html +0 -1495
- package/article/25318.html +0 -394
- package/article/25710.html +0 -1129
- package/article/25734.html +0 -83
- package/article/26083.html +0 -174
- package/article/26147.html +0 -283
- package/article/26291.html +0 -110
- package/article/26354.html +0 -71
- package/article/26624.html +0 -145
- package/article/26639.html +0 -298
- package/article/26850.html +0 -138
- package/article/26940.html +0 -258
- package/article/27796.html +0 -190
- package/article/27800.html +0 -161
- package/article/28963.html +0 -159
- package/article/28976.html +0 -247
- package/article/29042.html +0 -72
- package/article/29596.html +0 -81
- package/article/29619.html +0 -183
- package/article/29623.html +0 -329
- package/article/29829.html +0 -205
- package/article/29abbd1c.html +0 -112
- package/article/30215.html +0 -178
- package/article/30552.html +0 -78
- package/article/30818.html +0 -201
- package/article/31330.html +0 -364
- package/article/3154.html +0 -577
- package/article/31695.html +0 -348
- package/article/31826.html +0 -71
- package/article/31843.html +0 -132
- package/article/32280.html +0 -212
- package/article/32431.html +0 -74
- package/article/32443.html +0 -72
- package/article/32732.html +0 -122
- package/article/3286.html +0 -251
- package/article/32960.html +0 -198
- package/article/33713.html +0 -72
- package/article/33899.html +0 -615
- package/article/34351.html +0 -74
- package/article/34372.html +0 -89
- package/article/34410.html +0 -74
- package/article/34431.html +0 -118
- package/article/3447.html +0 -75
- package/article/34474.html +0 -142
- package/article/34871.html +0 -147
- package/article/35397.html +0 -175
- package/article/3544.html +0 -199
- package/article/35503.html +0 -115
- package/article/35624.html +0 -84
- package/article/35697.html +0 -384
- package/article/35863.html +0 -73
- package/article/36037.html +0 -253
- package/article/36118.html +0 -71
- package/article/3621.html +0 -119
- package/article/36251.html +0 -296
- package/article/36642.html +0 -352
- package/article/37102.html +0 -763
- package/article/37336.html +0 -351
- package/article/37351.html +0 -89
- package/article/3760.html +0 -294
- package/article/37749.html +0 -75
- package/article/37789.html +0 -83
- package/article/38005.html +0 -765
- package/article/38009.html +0 -284
- package/article/38269.html +0 -194
- package/article/38344.html +0 -88
- package/article/38359.html +0 -334
- package/article/38423.html +0 -379
- package/article/38530.html +0 -213
- package/article/38743.html +0 -268
- package/article/38753.html +0 -204
- package/article/38881.html +0 -71
- package/article/39087.html +0 -414
- package/article/39309.html +0 -84
- package/article/39486.html +0 -73
- package/article/39637.html +0 -306
- package/article/39839.html +0 -72
- package/article/39937.html +0 -152
- package/article/39970.html +0 -71
- package/article/402.html +0 -559
- package/article/40698.html +0 -71
- package/article/40811.html +0 -71
- package/article/40964.html +0 -462
- package/article/41011.html +0 -322
- package/article/41152.html +0 -78
- package/article/41696.html +0 -71
- package/article/41717.html +0 -281
- package/article/41777.html +0 -149
- package/article/419.html +0 -985
- package/article/4233.html +0 -136
- package/article/4292.html +0 -86
- package/article/43302.html +0 -96
- package/article/43397.html +0 -106
- package/article/43724.html +0 -281
- package/article/43999.html +0 -224
- package/article/44426.html +0 -77
- package/article/44964.html +0 -137
- package/article/45004.html +0 -123
- package/article/4510.html +0 -83
- package/article/45156.html +0 -320
- package/article/45157.html +0 -52
- package/article/45267.html +0 -87
- package/article/45641.html +0 -207
- package/article/45960.html +0 -75
- package/article/46100.html +0 -1262
- package/article/46366.html +0 -74
- package/article/46771.html +0 -96
- package/article/46911.html +0 -517
- package/article/46948.html +0 -137
- package/article/46ee4850.html +0 -349
- package/article/47019.html +0 -84
- package/article/47532.html +0 -94
- package/article/4783.html +0 -429
- package/article/47972.html +0 -72
- package/article/48216.html +0 -127
- package/article/48252.html +0 -185
- package/article/48520.html +0 -74
- package/article/48722.html +0 -75
- package/article/48807.html +0 -99
- package/article/49126.html +0 -323
- package/article/50001.html +0 -88
- package/article/50058.html +0 -151
- package/article/50343.html +0 -410
- package/article/50510.html +0 -82
- package/article/51082.html +0 -98
- package/article/51677.html +0 -111
- package/article/5204.html +0 -1085
- package/article/52500.html +0 -538
- package/article/52689.html +0 -259
- package/article/52877.html +0 -569
- package/article/53125.html +0 -191
- package/article/53428.html +0 -251
- package/article/53524.html +0 -74
- package/article/53698.html +0 -322
- package/article/53803e6.html +0 -93
- package/article/53924.html +0 -291
- package/article/53962.html +0 -253
- package/article/54006.html +0 -71
- package/article/54018.html +0 -88
- package/article/54161.html +0 -83
- package/article/54178.html +0 -69
- package/article/54258.html +0 -327
- package/article/54295.html +0 -214
- package/article/54313.html +0 -1976
- package/article/54351.html +0 -90
- package/article/54604.html +0 -80
- package/article/54632.html +0 -71
- package/article/54912.html +0 -756
- package/article/54918.html +0 -136
- package/article/55119.html +0 -136
- package/article/55756.html +0 -118
- package/article/55769.html +0 -136
- package/article/55870.html +0 -161
- package/article/56139.html +0 -92
- package/article/56557.html +0 -69
- package/article/56604.html +0 -69
- package/article/56816.html +0 -266
- package/article/56926.html +0 -153
- package/article/57747.html +0 -409
- package/article/57965.html +0 -475
- package/article/58816.html +0 -78
- package/article/59059.html +0 -435
- package/article/59095.html +0 -350
- package/article/59349.html +0 -244
- package/article/59402.html +0 -216
- package/article/59448.html +0 -55
- package/article/59870.html +0 -94
- package/article/59877.html +0 -208
- package/article/5dbb6f41.html +0 -86
- package/article/6008.html +0 -75
- package/article/60327.html +0 -126
- package/article/6035.html +0 -76
- package/article/60428.html +0 -71
- package/article/60544.html +0 -128
- package/article/61319.html +0 -95
- package/article/61367.html +0 -93
- package/article/624d1918.html +0 -292
- package/article/62543.html +0 -71
- package/article/62887.html +0 -169
- package/article/63074.html +0 -120
- package/article/63266.html +0 -311
- package/article/63351.html +0 -74
- package/article/63542.html +0 -104
- package/article/63824.html +0 -275
- package/article/64051.html +0 -653
- package/article/64189b69.html +0 -72
- package/article/64354.html +0 -75
- package/article/64869.html +0 -79
- package/article/64923.html +0 -596
- package/article/65128.html +0 -95
- package/article/65295.html +0 -79
- package/article/6888.html +0 -75
- package/article/7065.html +0 -84
- package/article/7455.html +0 -85
- package/article/7a3ef8f.html +0 -315
- package/article/8140.html +0 -188
- package/article/8190.html +0 -85
- package/article/8225.html +0 -78
- package/article/84c9ccd6.html +0 -159
- package/article/8f9a9ae3.html +0 -82
- package/article/9174.html +0 -73
- package/article/9738.html +0 -294
- package/article/9c3c56c.html +0 -682
- package/article/a4145266.html +0 -71
- package/article/bedea419.html +0 -72
- package/article/bf7e7421.html +0 -78
- package/article/c1867fbf.html +0 -103
- package/article/dcb0db28.html +0 -76
- package/article/fc3b727a.html +0 -79
- package/atom.xml +0 -441
- package/baidusitemap.xml +0 -1079
- package/blocks/dns.txt +0 -291
- package/blocks/filter.txt +0 -1068
- package/blocks/script.js +0 -42
- package/categories/CDN/index.html +0 -48
- package/categories/IDE/index.html +0 -48
- package/categories/git/index.html +0 -48
- package/categories/hexo/index.html +0 -48
- package/categories//345/205/254/345/205/261/350/212/202/346/227/245/index.html +0 -48
- package/categories//345/210/206/344/272/253/index.html +0 -48
- package/categories//345/211/215/347/253/257/index.html +0 -48
- package/categories//345/211/215/347/253/257/page/2/index.html +0 -48
- package/categories//345/211/215/347/253/257//346/265/217/350/247/210/345/231/250/index.html +0 -48
- package/categories//345/211/215/347/253/257//346/265/217/350/247/210/345/231/250//347/275/221/347/273/234/345/215/217/350/256/256/index.html +0 -48
- package/categories//345/215/232/345/256/242/index.html +0 -48
- package/categories//345/267/245/345/205/267/index.html +0 -48
- package/categories//345/271/277/345/221/212/350/277/207/346/273/244/index.html +0 -48
- package/categories//345/271/277/345/221/212/350/277/207/346/273/244//345/275/261/350/247/206/347/224/265/350/247/206/345/260/217/350/257/264/346/274/253/347/224/273/350/265/204/350/256/257/351/237/263/344/271/220/index.html +0 -48
- package/categories//345/271/277/345/221/212/350/277/207/346/273/244//350/247/206/351/242/221/347/224/265/350/247/206/345/260/217/350/257/264/346/274/253/347/224/273/350/265/204/350/256/257/351/237/263/344/271/220/index.html +0 -48
- package/categories//346/255/243/345/210/231/index.html +0 -48
- package/categories//346/265/217/350/247/210/345/231/250/index.html +0 -48
- package/categories//347/256/227/346/263/225/index.html +0 -48
- package/categories//350/265/204/350/256/257/index.html +0 -48
- package/categories//350/275/273/346/235/276/344/270/200/345/210/273/index.html +0 -48
- package/cdn/css/font-awesome.min.css +0 -4
- package/cdn/css/grids-responsive-min.css +0 -7
- package/cdn/css/normalize.css +0 -349
- package/cdn/css/pure-min.css +0 -11
- package/cdn/fonts/fontawesome-webfont.eot +0 -0
- package/cdn/fonts/fontawesome-webfont.svg +0 -2671
- package/cdn/fonts/fontawesome-webfont.ttf +0 -0
- package/cdn/fonts/fontawesome-webfont.woff +0 -0
- package/cdn/fonts/fontawesome-webfont.woff2 +0 -0
- package/cdn/js/Valine.min.js +0 -17
- package/cdn/js/canvas-nest.js +0 -1
- package/cdn/js/clipboard.min.js +0 -7
- package/cdn/js/crypto-js.js +0 -25
- package/cdn/js/jquery.min.js +0 -2
- package/css/default.css +0 -1144
- package/css/donate.css +0 -338
- package/css/hbe.style.css +0 -749
- package/css/style.css +0 -2095
- package/donate/index.html +0 -40
- package/google917dcf72f6e5c7f5.html +0 -1
- package/guestbook/index.html +0 -68
- package/hosts/ads.txt +0 -149
- package/hosts/flash.txt +0 -9
- package/hosts/github.txt +0 -15
- package/hosts/google.txt +0 -16936
- package/hosts/winrar.txt +0 -2
- package/img/alipay.svg +0 -46
- package/img/bitcoin.svg +0 -135
- package/img/blog.ico +0 -0
- package/img/blog.png +0 -0
- package/img/gaba.png +0 -0
- package/img/github.svg +0 -1
- package/img/like.svg +0 -1
- package/img/mp-mini.jpg +0 -0
- package/img/mp.png +0 -0
- package/img/paypal.svg +0 -63
- package/img/upy_logo.svg +0 -59
- package/img/wechat.svg +0 -49
- package/index.html +0 -48
- package/jd_root.txt +0 -1
- package/js/codeblock-resizer.js +0 -51
- package/js/dark.js +0 -12
- package/js/donate.js +0 -87
- package/js/fixedPage.js +0 -110
- package/js/gitment.browser.js +0 -3751
- package/js/search.js +0 -86
- package/js/share.js +0 -60
- package/js/smartresize.js +0 -32
- package/js/totop.js +0 -12
- package/kankan/index.html +0 -1323
- package/lib/hbe.js +0 -297
- package/page/10/index.html +0 -49
- package/page/11/index.html +0 -59
- package/page/12/index.html +0 -67
- package/page/13/index.html +0 -63
- package/page/14/index.html +0 -66
- package/page/15/index.html +0 -60
- package/page/16/index.html +0 -60
- package/page/17/index.html +0 -62
- package/page/18/index.html +0 -61
- package/page/19/index.html +0 -58
- package/page/2/index.html +0 -48
- package/page/20/index.html +0 -57
- package/page/21/index.html +0 -61
- package/page/22/index.html +0 -55
- package/page/23/index.html +0 -64
- package/page/24/index.html +0 -60
- package/page/25/index.html +0 -58
- package/page/26/index.html +0 -48
- package/page/27/index.html +0 -58
- package/page/3/index.html +0 -48
- package/page/4/index.html +0 -48
- package/page/5/index.html +0 -51
- package/page/6/index.html +0 -51
- package/page/7/index.html +0 -51
- package/page/8/index.html +0 -53
- package/page/9/index.html +0 -48
- package/randomcall/README.html +0 -1
- package/randomcall/lucker.html +0 -290
- package/randomcall/lucky.png +0 -0
- package/robots.txt +0 -22
- package/search.xml +0 -6728
- package/sitemap.xml +0 -2694
- package/tags//345/216/237/345/210/233/index.html +0 -48
- package/tags//345/250/261/344/271/220/index.html +0 -48
- package/tags//346/211/213/345/206/231/index.html +0 -48
- package/tags//347/226/253/346/203/205/index.html +0 -48
- package/tags//350/275/254/350/275/275/index.html +0 -48
- package/tags//350/275/254/350/275/275/page/2/index.html +0 -48
- package/v.html +0 -22
- /package/{appConfigs/config → config} +0 -0
- /package/{extConfigs/extension.json → extension.json} +0 -0
package/article/10624.html
DELETED
|
@@ -1,436 +0,0 @@
|
|
|
1
|
-
<!DOCTYPE html><html lang="zh-CN" data-dark><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" name="viewport"><meta content="yes" name="apple-mobile-web-app-capable"><meta content="black-translucent" name="apple-mobile-web-app-status-bar-style"><meta content="telephone=no" name="format-detection"><meta name="description" content="前端壹菜鸟,记录工作难题,关注前端知识,收集精彩博文,做技术的搬运工"><meta name="msvalidate.01" content="0FE4D8B3381D3D87088996B886E1E2BD"><title>【中高级前端必备】手摸手教你撸一个脚手架 | 前端壹菜鸟</title><link rel="stylesheet" type="text/css" href="//unpkg.com/cainiaoblog@latest/css/style.css"><link rel="stylesheet" type="text/css" href="//cdn.staticaly.com/gh/npljy/npljy.github.io/main/css/style.min.css"><link rel="stylesheet" type="text/css" href="//cdn.jsdelivr.net/npm/cainiaoblog@latest/css/style.min.css"><link rel="stylesheet" type="text/css" href="//cdn.jsdelivr.net/npm/normalize.css@latest/normalize.min.css"><link rel="stylesheet" type="text/css" href="//cdn.jsdelivr.net/npm/purecss@latest/build/pure-min.min.css"><link rel="stylesheet" type="text/css" href="//cdn.jsdelivr.net/npm/purecss@latest/build/grids-responsive-min.css"><link rel="stylesheet" type="text/css" href="//cdn.jsdelivr.net/npm/font-awesome@4.7.0/css/font-awesome.min.css"><link rel="icon" mask="" sizes="any" href="//cdn.staticaly.com/gh/npljy/npljy.github.io/main/img/blog.ico"><link rel="Shortcut Icon" type="image/x-icon" href="//cdn.staticaly.com/gh/npljy/npljy.github.io/main/img/blog.ico"><link rel="apple-touch-icon" href="//cdn.staticaly.com/gh/npljy/npljy.github.io/main/img/blog.png"><link rel="apple-touch-icon-precomposed" href="//cdn.staticaly.com/gh/npljy/npljy.github.io/main/img/blog.png"><link rel="alternate" type="application/atom+xml" href="/atom.xml"><script type="text/javascript" src="//cdn.jsdelivr.net/npm/jquery@latest/dist/jquery.min.js"></script><script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js?client=ca-pub-8385136408348258"></script><script src="https://busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js" async></script><script>(function(){
|
|
2
|
-
var bp = document.createElement('script');
|
|
3
|
-
var curProtocol = window.location.protocol.split(':')[0];
|
|
4
|
-
if (curProtocol === 'https'){
|
|
5
|
-
bp.src = 'https://zz.bdstatic.com/linksubmit/push.js';
|
|
6
|
-
}
|
|
7
|
-
else{
|
|
8
|
-
bp.src = 'http://push.zhanzhang.baidu.com/push.js';
|
|
9
|
-
}
|
|
10
|
-
var s = document.getElementsByTagName("script")[0];
|
|
11
|
-
s.parentNode.insertBefore(bp, s);
|
|
12
|
-
})();
|
|
13
|
-
</script><script>(function(){
|
|
14
|
-
var src = 'https://jspassport.ssl.qhimg.com/11.0.1.js?d182b3f28525f2db83acfaaf6e696dba';
|
|
15
|
-
document.write('<script src="' + src + '" id="sozz"><\/script>');
|
|
16
|
-
})();
|
|
17
|
-
</script><script>var _hmt=_hmt||[];(function(){var hm=document.createElement("script");hm.src='https://hm.baidu.com/hm.js?011f0b44e8452bfa57fbfa23c5fe7683';var s=document.getElementsByTagName("script")[0];s.parentNode.insertBefore(hm, s);})();
|
|
18
|
-
</script><script async src="https://www.googletagmanager.com/gtag/js?id=UA-150860401-1"></script><script>window.dataLayer=window.dataLayer||[];function gtag(){dataLayer.push(arguments);};gtag('js',new Date());gtag('config','UA-150860401-1');
|
|
19
|
-
</script><script type="text/javascript" src="//cdn.jsdelivr.net/npm/cainiaoblog@latest/js/fixedPage.min.js"></script><meta name="generator" content="Hexo 6.3.0"></head><body><div class="body_container"><div id="header"><div class="site-name"><a id="logo" href="/.">前端壹菜鸟</a><p class="description">关注前端知识,收集精彩博文,做技术的搬运工</p></div><div id="nav-menu"><a class="current" href="/." target="_self"><i class="fa fa-home"> 首页</i></a><a href="/archives/" target="_self"><i class="fa fa-archive"> 归档</i></a><a href="/guestbook/" target="_self"><i class="fa fa-comments"> 留言</i></a><a href="/about/" target="_self"><i class="fa fa-user"> 关于</i></a><a href="https://laonongmin.online/" target="_target"><i class="fa fa-group"> 看看</i></a><a href="https://love.xuehuayu.cn/" target="_target"><i class="fa fa-heart"> LOVE</i></a></div></div><div class="pure-g" id="layout"><div class="pure-u-1 pure-u-md-3-4"><div class="content_container"><div class="post"><h1 class="post-title c-post">【中高级前端必备】手摸手教你撸一个脚手架</h1><div class="post-meta"><span class="date">2019-09-29</span><span> | </span><span class="tag"><a href="/tags/%E8%BD%AC%E8%BD%BD/">转载 </a></span><span> | </span><span class="category"><a href="/categories/%E5%88%86%E4%BA%AB/">分享 </a></span><span id="busuanzi_container_page_pv"> | <span id="busuanzi_value_page_pv"><i class="fa fa-spinner"></i></span><span> 阅读</span></span><span class="post-time"><span class="post-meta-item-text"> | </span><span class="post-meta-item-icon"><i class="fa fa-keyboard-o"></i><span class="post-count"> 2.2k</span><span class="post-meta-item-text"> 字</span></span></span><span class="post-time"> | <span class="post-meta-item-icon"><i class="fa fa-hourglass-half"></i><span class="post-count"> 10</span><span class="post-meta-item-text"> 分钟</span></span></span></div><a class="disqus-comment-count" href="/article/10624.html#vcomment"><span class="waline-comment-count" data-path="/article/10624.html"></span><span> 条评论</span></a><div class="post-content"><p><code>原文地址:https://github.com/YvetteLau/Blog/issues/39</code></p>
|
|
20
|
-
<span id="more"></span>
|
|
21
|
-
<h3 id="脚手架"><a href="#脚手架" class="headerlink" title="脚手架"></a>脚手架</h3><p><code>vue-cli</code>, <code>create-react-app</code>、<code>react-native-cli</code> 等都是非常优秀的脚手架,通过脚手架,我们可以快速初始化一个项目,无需自己从零开始一步步配置,有效提升开发体验。尽管这些脚手架非常优秀,但是未必是符合我们的实际应用的,我们可以定制一个属于自己的脚手架(或公司通用脚手架),来提升自己的开发效率。</p>
|
|
22
|
-
<blockquote>
|
|
23
|
-
<p>脚手架的作用</p>
|
|
24
|
-
</blockquote>
|
|
25
|
-
<ul>
|
|
26
|
-
<li>减少重复性的工作,不需要复制其他项目再删除无关代码,或者从零创建一个项目和文件。</li>
|
|
27
|
-
<li>可以根据交互动态生成项目结构和配置文件。</li>
|
|
28
|
-
<li>多人协作更为方便,不需要把文件传来传去。</li>
|
|
29
|
-
</ul>
|
|
30
|
-
<h3 id="实现的功能"><a href="#实现的功能" class="headerlink" title="实现的功能"></a>实现的功能</h3><p>在开始之前,我们需要明确自己的脚手架需要哪些功能。<code>vue init template-name project-name</code> 、<code>create-react-app project-name</code>。我们这次编写的脚手架(eos-cli)具备以下能力(脚手架的名字爱叫啥叫啥,我选用了Eos黎明女神):</p>
|
|
31
|
-
<ul>
|
|
32
|
-
<li><code>eos init template-name project-name</code> 根据远程模板,初始化一个项目(远程模板可配置)</li>
|
|
33
|
-
<li><code>eos config set <key> <value></code> 修改配置信息</li>
|
|
34
|
-
<li><code>eos config get [<key>]</code> 查看配置信息</li>
|
|
35
|
-
<li><code>eos --version</code> 查看当前版本号</li>
|
|
36
|
-
<li><code>eos -h</code></li>
|
|
37
|
-
</ul>
|
|
38
|
-
<p>大家可以自行扩展其它的 <code>commander</code>,本篇文章旨在教大家如何实现一个脚手架。</p>
|
|
39
|
-
<p>本项目完整代码请戳(建议先clone代码): <a target="_blank" rel="noopener" href="https://github.com/YvetteLau/Blog/tree/master/eos-cli">https://github.com/YvetteLau/Blog/tree/master/eos-cli</a></p>
|
|
40
|
-
<blockquote>
|
|
41
|
-
<p>效果展示</p>
|
|
42
|
-
</blockquote>
|
|
43
|
-
<p><strong>初始化一个项目</strong></p>
|
|
44
|
-
<p><a target="_blank" rel="noopener" href="https://camo.githubusercontent.com/5cd8cc78579e2cd1364d420caa824928630ebecd/68747470733a2f2f757365722d676f6c642d63646e2e786974752e696f2f323031392f372f32342f313663323231353831383930393534373f773d36303626683d33333226663d67696626733d333638333532"><img src="https://camo.githubusercontent.com/5cd8cc78579e2cd1364d420caa824928630ebecd/68747470733a2f2f757365722d676f6c642d63646e2e786974752e696f2f323031392f372f32342f313663323231353831383930393534373f773d36303626683d33333226663d67696626733d333638333532" alt="xuehuayu.cn"></a></p>
|
|
45
|
-
<p><strong>修改.eosrc文件,从 vuejs-template 下载模板</strong></p>
|
|
46
|
-
<p><a target="_blank" rel="noopener" href="https://camo.githubusercontent.com/82add85eab645c0a19cf1e3220f4528f23c39c28/68747470733a2f2f757365722d676f6c642d63646e2e786974752e696f2f323031392f372f32342f313663323231353839373731653063643f773d35393226683d32383826663d67696626733d333333343738"><img src="https://camo.githubusercontent.com/82add85eab645c0a19cf1e3220f4528f23c39c28/68747470733a2f2f757365722d676f6c642d63646e2e786974752e696f2f323031392f372f32342f313663323231353839373731653063643f773d35393226683d32383826663d67696626733d333333343738" alt="xuehuayu.cn"></a></p>
|
|
47
|
-
<h3 id="需要使用的第三方库"><a href="#需要使用的第三方库" class="headerlink" title="需要使用的第三方库"></a>需要使用的第三方库</h3><ul>
|
|
48
|
-
<li>babel-cli/babel-env: 语法转换</li>
|
|
49
|
-
<li>commander: 命令行工具</li>
|
|
50
|
-
<li>download-git-repo: 用来下载远程模板</li>
|
|
51
|
-
<li>ini: 格式转换</li>
|
|
52
|
-
<li>inquirer: 交互式命令行工具</li>
|
|
53
|
-
<li>ora: 显示loading动画</li>
|
|
54
|
-
<li>chalk: 修改控制台输出内容样式</li>
|
|
55
|
-
<li>log-symbols: 显示出 √ 或 × 等的图标</li>
|
|
56
|
-
</ul>
|
|
57
|
-
<p>关于这些第三方库的说明,可以直接npm上查看相应的说明,此处不一一展开。</p>
|
|
58
|
-
<h3 id="初始化项目"><a href="#初始化项目" class="headerlink" title="初始化项目"></a>初始化项目</h3><p>创建一个空项目(eos-cli),使用 <code>npm init</code> 进行初始化。</p>
|
|
59
|
-
<h4 id="安装依赖"><a href="#安装依赖" class="headerlink" title="安装依赖"></a>安装依赖</h4><pre><code>npm install babel-cli babel-env chalk commander download-git-repo ini inquirer log-symbols ora
|
|
60
|
-
</code></pre>
|
|
61
|
-
<h4 id="目录结构"><a href="#目录结构" class="headerlink" title="目录结构"></a>目录结构</h4><pre><code>├── bin
|
|
62
|
-
│ └── www //可执行文件
|
|
63
|
-
├── dist
|
|
64
|
-
├── ...//生成文件
|
|
65
|
-
└── src
|
|
66
|
-
├── config.js//管理eos配置文件
|
|
67
|
-
├── index.js//主流程入口文件
|
|
68
|
-
├── init.js//init command
|
|
69
|
-
├── main.js//入口文件
|
|
70
|
-
└── utils
|
|
71
|
-
├── constants.js//定义常量
|
|
72
|
-
├── get.js//获取模板
|
|
73
|
-
└── rc.js//配置文件
|
|
74
|
-
├── .babelrc//babel配置文件
|
|
75
|
-
├── package.json
|
|
76
|
-
├── README.md
|
|
77
|
-
</code></pre>
|
|
78
|
-
<h4 id="babel-配置"><a href="#babel-配置" class="headerlink" title="babel 配置"></a>babel 配置</h4><p>开发使用了ES6语法,使用 <code>babel</code> 进行转义,</p>
|
|
79
|
-
<blockquote>
|
|
80
|
-
<p><code>.bablerc</code></p>
|
|
81
|
-
</blockquote>
|
|
82
|
-
<pre><code>{
|
|
83
|
-
"presets": [
|
|
84
|
-
[
|
|
85
|
-
"env",
|
|
86
|
-
{
|
|
87
|
-
"targets": {
|
|
88
|
-
"node": "current"
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
]
|
|
92
|
-
]
|
|
93
|
-
}
|
|
94
|
-
</code></pre>
|
|
95
|
-
<h3 id="eos-命令"><a href="#eos-命令" class="headerlink" title="eos 命令"></a><code>eos</code> 命令</h3><p>node.js 内置了对命令行操作的支持,<code>package.json</code> 中的 <code>bin</code> 字段可以定义命令名和关联的执行文件。在 <code>package.json</code> 中添加 <code>bin</code> 字段</p>
|
|
96
|
-
<blockquote>
|
|
97
|
-
<p>package.json</p>
|
|
98
|
-
</blockquote>
|
|
99
|
-
<pre><code>{
|
|
100
|
-
"name": "eos-cli",
|
|
101
|
-
"version": "1.0.0",
|
|
102
|
-
"description": "脚手架",
|
|
103
|
-
"main": "index.js",
|
|
104
|
-
"bin": {
|
|
105
|
-
"eos": "./bin/www"
|
|
106
|
-
},
|
|
107
|
-
"scripts": {
|
|
108
|
-
"compile": "babel src -d dist",
|
|
109
|
-
"watch": "npm run compile -- --watch"
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
</code></pre>
|
|
113
|
-
<blockquote>
|
|
114
|
-
<p>www 文件</p>
|
|
115
|
-
</blockquote>
|
|
116
|
-
<p>行首加入一行 <code>#!/usr/bin/env node</code> 指定当前脚本由node.js进行解析</p>
|
|
117
|
-
<pre><code>#! /usr/bin/env noderequire('../dist/main.js');
|
|
118
|
-
</code></pre>
|
|
119
|
-
<h4 id="链接到全局环境"><a href="#链接到全局环境" class="headerlink" title="链接到全局环境"></a>链接到全局环境</h4><p>开发过程中为了方便调试,在当前的 <code>eos-cli</code> 目录下执行 <code>npm link</code>,将 <code>eos</code> 命令链接到全局环境。</p>
|
|
120
|
-
<h4 id="启动项目"><a href="#启动项目" class="headerlink" title="启动项目"></a>启动项目</h4><pre><code>npm run watch
|
|
121
|
-
</code></pre>
|
|
122
|
-
<h3 id="处理命令行"><a href="#处理命令行" class="headerlink" title="处理命令行"></a>处理命令行</h3><p>利用 <code>commander</code> 来处理命令行。</p>
|
|
123
|
-
<blockquote>
|
|
124
|
-
<p>main</p>
|
|
125
|
-
</blockquote>
|
|
126
|
-
<pre><code>importprogramfrom'commander';
|
|
127
|
-
import { VERSION } from'./utils/constants';
|
|
128
|
-
importapplyfrom'./index';
|
|
129
|
-
importchalkfrom'chalk';
|
|
130
|
-
|
|
131
|
-
/** * eos commands * - config * - init */let actionMap = {
|
|
132
|
-
init: {
|
|
133
|
-
description:'generate a new project from a template',
|
|
134
|
-
usages: [
|
|
135
|
-
'eos init templateName projectName'
|
|
136
|
-
]
|
|
137
|
-
},
|
|
138
|
-
config: {
|
|
139
|
-
alias:'cfg',
|
|
140
|
-
description:'config .eosrc',
|
|
141
|
-
usages: [
|
|
142
|
-
'eos config set <k> <v>',
|
|
143
|
-
'eos config get <k>',
|
|
144
|
-
'eos config remove <k>'
|
|
145
|
-
]
|
|
146
|
-
|
|
147
|
-
},
|
|
148
|
-
//other commands
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
// 添加 init / config 命令Object.keys(actionMap).forEach((action) => {
|
|
152
|
-
program.command(action)
|
|
153
|
-
.description(actionMap[action].description)
|
|
154
|
-
.alias(actionMap[action].alias) //别名
|
|
155
|
-
.action(() => {
|
|
156
|
-
switch (action) {
|
|
157
|
-
case'config':
|
|
158
|
-
//配置apply(action, ...process.argv.slice(3));
|
|
159
|
-
break;
|
|
160
|
-
case'init':
|
|
161
|
-
apply(action, ...process.argv.slice(3));
|
|
162
|
-
break;
|
|
163
|
-
default:
|
|
164
|
-
break;
|
|
165
|
-
}
|
|
166
|
-
});
|
|
167
|
-
});
|
|
168
|
-
|
|
169
|
-
functionhelp() {
|
|
170
|
-
console.log('\r\nUsage:');
|
|
171
|
-
Object.keys(actionMap).forEach((action) => {
|
|
172
|
-
actionMap[action].usages.forEach(usage=> {
|
|
173
|
-
console.log(' - '+ usage);
|
|
174
|
-
});
|
|
175
|
-
});
|
|
176
|
-
console.log('\r');
|
|
177
|
-
}
|
|
178
|
-
program.usage('<command> [options]');
|
|
179
|
-
// eos -h program.on('-h', help);
|
|
180
|
-
program.on('--help', help);
|
|
181
|
-
// eos -V VERSION 为 package.json 中的版本号program.version(VERSION, '-V --version').parse(process.argv);
|
|
182
|
-
|
|
183
|
-
// eos 不带参数时if (!process.argv.slice(2).length) {
|
|
184
|
-
program.outputHelp(make_green);
|
|
185
|
-
}
|
|
186
|
-
functionmake_green(txt) {
|
|
187
|
-
returnchalk.green(txt);
|
|
188
|
-
}
|
|
189
|
-
</code></pre>
|
|
190
|
-
<h3 id="下载模板"><a href="#下载模板" class="headerlink" title="下载模板"></a>下载模板</h3><p><code>download-git-repo</code> 支持从 Github、Gitlab 下载远程仓库到本地。</p>
|
|
191
|
-
<blockquote>
|
|
192
|
-
<p>get.js</p>
|
|
193
|
-
</blockquote>
|
|
194
|
-
<pre><code>import { getAll } from'./rc';
|
|
195
|
-
importdownloadGitfrom'download-git-repo';
|
|
196
|
-
|
|
197
|
-
exportconstdownloadLocal=async (templateName, projectName) => {
|
|
198
|
-
let config =awaitgetAll();
|
|
199
|
-
let api =`${config.registry}/${templateName}`;
|
|
200
|
-
returnnewPromise((resolve, reject) => {
|
|
201
|
-
//projectName 为下载到的本地目录downloadGit(api, projectName, (err) => {
|
|
202
|
-
if (err) {
|
|
203
|
-
reject(err);
|
|
204
|
-
}
|
|
205
|
-
resolve();
|
|
206
|
-
});
|
|
207
|
-
});
|
|
208
|
-
}
|
|
209
|
-
</code></pre>
|
|
210
|
-
<h3 id="init-命令"><a href="#init-命令" class="headerlink" title="init 命令"></a><code>init</code> 命令</h3><h4 id="命令行交互"><a href="#命令行交互" class="headerlink" title="命令行交互"></a>命令行交互</h4><p>在用户执行 init 命令后,向用户提出问题,接收用户的输入并作出相应的处理。命令行交互利用 <code>inquirer</code> 来实现:</p>
|
|
211
|
-
<pre><code>inquirer.prompt([
|
|
212
|
-
{
|
|
213
|
-
name:'description',
|
|
214
|
-
message:'Please enter the project description: '
|
|
215
|
-
},
|
|
216
|
-
{
|
|
217
|
-
name:'author',
|
|
218
|
-
message:'Please enter the author name: '
|
|
219
|
-
}
|
|
220
|
-
]).then((answer) => {
|
|
221
|
-
//...
|
|
222
|
-
});
|
|
223
|
-
</code></pre>
|
|
224
|
-
<p><a target="_blank" rel="noopener" href="https://camo.githubusercontent.com/683b9c52b6ff83636df4d72e042ac4fa1ea67b09/68747470733a2f2f757365722d676f6c642d63646e2e786974752e696f2f323031392f372f32342f313663323263643938363037333861613f773d39383826683d31363626663d6a70656726733d313732383739"><img src="https://camo.githubusercontent.com/683b9c52b6ff83636df4d72e042ac4fa1ea67b09/68747470733a2f2f757365722d676f6c642d63646e2e786974752e696f2f323031392f372f32342f313663323263643938363037333861613f773d39383826683d31363626663d6a70656726733d313732383739" alt="xuehuayu.cn"></a></p>
|
|
225
|
-
<h4 id="视觉美化"><a href="#视觉美化" class="headerlink" title="视觉美化"></a>视觉美化</h4><p>在用户输入之后,开始下载模板,这时候使用 <code>ora</code> 来提示用户正在下载模板,下载结束之后,也给出提示。</p>
|
|
226
|
-
<pre><code>importorafrom'ora';
|
|
227
|
-
let loading =ora('downloading template ...');
|
|
228
|
-
loading.start();
|
|
229
|
-
//downloadloading.succeed(); //或 loading.fail();
|
|
230
|
-
</code></pre>
|
|
231
|
-
<p><a target="_blank" rel="noopener" href="https://camo.githubusercontent.com/70ed40fac983355be196ef4da44bfab0d1e9ad87/68747470733a2f2f757365722d676f6c642d63646e2e786974752e696f2f323031392f372f32342f313663323263666534623431623735643f773d39373026683d32323626663d6a70656726733d323437393634"><img src="https://camo.githubusercontent.com/70ed40fac983355be196ef4da44bfab0d1e9ad87/68747470733a2f2f757365722d676f6c642d63646e2e786974752e696f2f323031392f372f32342f313663323263666534623431623735643f773d39373026683d32323626663d6a70656726733d323437393634" alt="xuehuayu.cn"></a></p>
|
|
232
|
-
<blockquote>
|
|
233
|
-
<p>init.js</p>
|
|
234
|
-
</blockquote>
|
|
235
|
-
<pre><code>import { downloadLocal } from'./utils/get';
|
|
236
|
-
importorafrom'ora';
|
|
237
|
-
importinquirerfrom'inquirer';
|
|
238
|
-
importfsfrom'fs';
|
|
239
|
-
importchalkfrom'chalk';
|
|
240
|
-
importsymbolfrom'log-symbols';
|
|
241
|
-
|
|
242
|
-
let init =async (templateName, projectName) => {
|
|
243
|
-
//项目不存在if (!fs.existsSync(projectName)) {
|
|
244
|
-
//命令行交互inquirer.prompt([
|
|
245
|
-
{
|
|
246
|
-
name:'description',
|
|
247
|
-
message:'Please enter the project description: '
|
|
248
|
-
},
|
|
249
|
-
{
|
|
250
|
-
name:'author',
|
|
251
|
-
message:'Please enter the author name: '
|
|
252
|
-
}
|
|
253
|
-
]).then(async (answer) => {
|
|
254
|
-
//下载模板 选择模板//通过配置文件,获取模板信息let loading =ora('downloading template ...');
|
|
255
|
-
loading.start();
|
|
256
|
-
downloadLocal(templateName, projectName).then(() => {
|
|
257
|
-
loading.succeed();
|
|
258
|
-
constfileName=`${projectName}/package.json`;
|
|
259
|
-
if(fs.existsSync(fileName)){
|
|
260
|
-
constdata=fs.readFileSync(fileName).toString();
|
|
261
|
-
let json =JSON.parse(data);
|
|
262
|
-
json.name= projectName;
|
|
263
|
-
json.author=answer.author;
|
|
264
|
-
json.description=answer.description;
|
|
265
|
-
//修改项目文件夹中 package.json 文件fs.writeFileSync(fileName, JSON.stringify(json, null, '\t'), 'utf-8');
|
|
266
|
-
console.log(symbol.success, chalk.green('Project initialization finished!'));
|
|
267
|
-
}
|
|
268
|
-
}, () => {
|
|
269
|
-
loading.fail();
|
|
270
|
-
});
|
|
271
|
-
});
|
|
272
|
-
}else {
|
|
273
|
-
//项目已经存在console.log(symbol.error, chalk.red('The project already exists'));
|
|
274
|
-
}
|
|
275
|
-
}
|
|
276
|
-
module.exports= init;
|
|
277
|
-
</code></pre>
|
|
278
|
-
<h3 id="config-配置"><a href="#config-配置" class="headerlink" title="config 配置"></a><code>config</code> 配置</h3><pre><code>eos config set registry vuejs-templates
|
|
279
|
-
</code></pre>
|
|
280
|
-
<p>config 配置,支持我们使用其它仓库的模板,例如,我们可以使用 vuejs-templates 中的仓库作为模板。这样有一个好处:更新模板无需重新发布脚手架,使用者无需重新安装,并且可以自由选择下载目标。</p>
|
|
281
|
-
<blockquote>
|
|
282
|
-
<p>config.js</p>
|
|
283
|
-
</blockquote>
|
|
284
|
-
<pre><code>// 管理 .eosrc 文件 (当前用户目录下)import { get, set, getAll, remove } from'./utils/rc';
|
|
285
|
-
|
|
286
|
-
let config =async (action, key, value) => {
|
|
287
|
-
switch (action) {
|
|
288
|
-
case'get':
|
|
289
|
-
if (key) {
|
|
290
|
-
let result =awaitget(key);
|
|
291
|
-
console.log(result);
|
|
292
|
-
} else {
|
|
293
|
-
let obj =awaitgetAll();
|
|
294
|
-
Object.keys(obj).forEach(key=> {
|
|
295
|
-
console.log(`${key}=${obj[key]}`);
|
|
296
|
-
})
|
|
297
|
-
}
|
|
298
|
-
break;
|
|
299
|
-
case'set':
|
|
300
|
-
set(key, value);
|
|
301
|
-
break;
|
|
302
|
-
case'remove':
|
|
303
|
-
remove(key);
|
|
304
|
-
break;
|
|
305
|
-
default:
|
|
306
|
-
break;
|
|
307
|
-
}
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
module.exports= config;
|
|
311
|
-
</code></pre>
|
|
312
|
-
<blockquote>
|
|
313
|
-
<p>rc.js</p>
|
|
314
|
-
</blockquote>
|
|
315
|
-
<p>.eosrc 文件的增删改查</p>
|
|
316
|
-
<pre><code>import { RC, DEFAULTS } from'./constants';
|
|
317
|
-
import { decode, encode } from'ini';
|
|
318
|
-
import { promisify } from'util';
|
|
319
|
-
importchalkfrom'chalk';
|
|
320
|
-
importfsfrom'fs';
|
|
321
|
-
|
|
322
|
-
constexits=promisify(fs.exists);
|
|
323
|
-
constreadFile=promisify(fs.readFile);
|
|
324
|
-
constwriteFile=promisify(fs.writeFile);
|
|
325
|
-
|
|
326
|
-
//RC 是配置文件//DEFAULTS 是默认的配置exportconstget=async (key) => {
|
|
327
|
-
constexit=awaitexits(RC);
|
|
328
|
-
let opts;
|
|
329
|
-
if (exit) {
|
|
330
|
-
opts =awaitreadFile(RC, 'utf8');
|
|
331
|
-
opts =decode(opts);
|
|
332
|
-
return opts[key];
|
|
333
|
-
}
|
|
334
|
-
return'';
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
exportconstgetAll=async () => {
|
|
338
|
-
constexit=awaitexits(RC);
|
|
339
|
-
let opts;
|
|
340
|
-
if (exit) {
|
|
341
|
-
opts =awaitreadFile(RC, 'utf8');
|
|
342
|
-
opts =decode(opts);
|
|
343
|
-
return opts;
|
|
344
|
-
}
|
|
345
|
-
return {};
|
|
346
|
-
}
|
|
347
|
-
|
|
348
|
-
exportconstset=async (key, value) => {
|
|
349
|
-
constexit=awaitexits(RC);
|
|
350
|
-
let opts;
|
|
351
|
-
if (exit) {
|
|
352
|
-
opts =awaitreadFile(RC, 'utf8');
|
|
353
|
-
opts =decode(opts);
|
|
354
|
-
if(!key) {
|
|
355
|
-
console.log(chalk.red(chalk.bold('Error:')), chalk.red('key is required'));
|
|
356
|
-
return;
|
|
357
|
-
}
|
|
358
|
-
if(!value) {
|
|
359
|
-
console.log(chalk.red(chalk.bold('Error:')), chalk.red('value is required'));
|
|
360
|
-
return;
|
|
361
|
-
}
|
|
362
|
-
Object.assign(opts, { [key]: value });
|
|
363
|
-
} else {
|
|
364
|
-
opts =Object.assign(DEFAULTS, { [key]: value });
|
|
365
|
-
}
|
|
366
|
-
awaitwriteFile(RC, encode(opts), 'utf8');
|
|
367
|
-
}
|
|
368
|
-
|
|
369
|
-
exportconstremove=async (key) => {
|
|
370
|
-
constexit=awaitexits(RC);
|
|
371
|
-
let opts;
|
|
372
|
-
if (exit) {
|
|
373
|
-
opts =awaitreadFile(RC, 'utf8');
|
|
374
|
-
opts =decode(opts);
|
|
375
|
-
delete opts[key];
|
|
376
|
-
awaitwriteFile(RC, encode(opts), 'utf8');
|
|
377
|
-
}
|
|
378
|
-
}
|
|
379
|
-
</code></pre>
|
|
380
|
-
<h3 id="发布"><a href="#发布" class="headerlink" title="发布"></a>发布</h3><p><code>npm publish</code> 将本脚手架发布至npm上。其它用户可以通过 <code>npm install eos-cli -g</code> 全局安装。</p>
|
|
381
|
-
<p>即可使用 <code>eos</code> 命令。</p>
|
|
382
|
-
<h3 id="项目地址"><a href="#项目地址" class="headerlink" title="项目地址"></a>项目地址</h3><p>本项目完整代码请戳: <a target="_blank" rel="noopener" href="https://github.com/YvetteLau/Blog/tree/master/eos-cli">https://github.com/YvetteLau/Blog/tree/master/eos-cli</a></p>
|
|
383
|
-
<p><a target="_blank" rel="noopener" href="https://camo.githubusercontent.com/587be9822f9355bb5fbfe308d8840056ed7c27fa/68747470733a2f2f757365722d676f6c642d63646e2e786974752e696f2f323031392f372f32342f313663323264326462643339366232393f773d32353526683d32353526663d6a70656726733d38353832"><img src="https://camo.githubusercontent.com/587be9822f9355bb5fbfe308d8840056ed7c27fa/68747470733a2f2f757365722d676f6c642d63646e2e786974752e696f2f323031392f372f32342f313663323264326462643339366232393f773d32353526683d32353526663d6a70656726733d38353832" alt="xuehuayu.cn"></a></p>
|
|
384
|
-
<p>编写本文,虽然花费了一定时间,但是在这个过程中,我也学习到了很多知识,谢谢各位小伙伴愿意花费宝贵的时间阅读本文,如果本文给了您一点帮助或者是启发,请不要吝啬你的赞和Star,您的肯定是我前进的最大动力。<br><a target="_blank" rel="noopener" href="https://github.com/YvetteLau/Blog">https://github.com/YvetteLau/Blog</a></p>
|
|
385
|
-
<h3 id="参考文章:"><a href="#参考文章:" class="headerlink" title="参考文章:"></a>参考文章:</h3><p>[1] <a target="_blank" rel="noopener" href="http://www.zhufengpeixun.cn/main/course/index.html">珠峰架构课(墙裂推荐)</a></p>
|
|
386
|
-
<p>[2] npm依赖文档(<a target="_blank" rel="noopener" href="https://www.npmjs.com/package/download-git-repo">https://www.npmjs.com/package/download-git-repo</a>)</p>
|
|
387
|
-
</div><div><ul class="post-copyright"><li class="post-copyright-author"><strong>本文作者:</strong>雪花雨</li><li class="post-copyright-link"><strong>本文链接:</strong><a href="/article/10624.html">https://xuehuayu.cn/article/10624.html</a></li><li class="post-copyright-license"><strong>版权声明:</strong>① 标为原创的文章为博主原创,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接。② 转载文章来自网络,已标明出处,<a href="mailto:cainiaoblog@126.com">侵删</a>。</li></ul></div><br><div class="tags"><a href="/tags/%E8%BD%AC%E8%BD%BD/">转载</a></div><div class="post-nav"><a class="pre" href="/article/23195.html">细说JS异步发展历程</a><a class="next" href="/article/3544.html">深入理解全能的 Reducer</a></div><div id="vcomment"></div><link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@waline/client@v2/dist/waline.min.css"><script src="//cdn.jsdelivr.net/npm/@waline/client@v2/dist/waline.js"></script><script>const origin = window.location.origin
|
|
388
|
-
const serverURL = origin.includes('cainiaoblog') ? 'https://cmts.cainiaoblog.cn' : 'https://cmts.xuehuayu.cn'
|
|
389
|
-
const locale = {
|
|
390
|
-
placeholder: '请正确填写昵称和邮箱,方便接收回复通知~',
|
|
391
|
-
sofa: '沙发空缺中,还不快抢~',
|
|
392
|
-
};
|
|
393
|
-
Waline.init({
|
|
394
|
-
el: '#vcomment',
|
|
395
|
-
serverURL: serverURL,
|
|
396
|
-
pageSize: '20',
|
|
397
|
-
visitor: true, // 阅读量统计
|
|
398
|
-
requiredMeta: ['nick', 'mail'],
|
|
399
|
-
emoji: [
|
|
400
|
-
'https://cdn.jsdelivr.net/gh/walinejs/emojis@1.0.0/weibo',
|
|
401
|
-
'https://cdn.jsdelivr.net/gh/walinejs/emojis@1.0.0/qq',
|
|
402
|
-
'https://cdn.jsdelivr.net/gh/walinejs/emojis@1.0.0/tw-emoji',
|
|
403
|
-
],
|
|
404
|
-
locale,
|
|
405
|
-
pageview: true
|
|
406
|
-
})
|
|
407
|
-
</script></div></div></div><div class="pure-u-1 pure-u-md-1-4 fixed-search hidden_mid_and_down"><div id="sidebar"><script type="text/javascript" src="//cdn.jsdelivr.net/npm/cainiaoblog@latest/js/search.min.js"></script><div class="widget"><div class="widget-search"><input class="search" type="radio" name="search" value="baidu" id="baidu" checked="checked"/><label class="label" for="baidu" title="百度全站搜索">百度</label><input class="search" type="radio" name="search" value="google" id="google"/><label class="label" for="google" title="谷歌全站搜索">谷歌</label><input class="search" type="radio" name="search" value="self" id="self"/><label class="label" for="self" title="使用站内搜索">站内</label></div><div class="widget" id="search"><form class="search-form" action="//www.baidu.com/baidu" method="get" accept-charset="utf-8" target="_blank"><input type="search" name="word" maxlength="30" placeholder="百度全站搜索"/><input type="hidden" name="si" value="xuehuayu.cn"/><input type="hidden" name="cl" value="3"/><input type="hidden" name="ct" value="2097152"/><input type="hidden" name="s" value="on"/><input class="search-submit" type="submit" value=""/></form></div></div><script>$('input[type=radio][name=search]').change(function() {
|
|
408
|
-
var val = $(this).val()
|
|
409
|
-
var self = '<div class="search-form"><input id="local-search-input" placeholder="站内搜索,首次慢" type="search" name="q" results="0"><input class="search-submit" type="submit" value=""/><div id="local-search-result"></div></div>'
|
|
410
|
-
var google = '<form class="search-form" action="//www.google.com/search" method="get" accept-charset="utf-8" target="_blank"><input type="search" name="q" maxlength="30" placeholder="谷歌全站搜索"><input type="hidden" name="sitesearch" value="xuehuayu.cn"><input class="search-submit" type="submit" value=""/></form>'
|
|
411
|
-
var baidu = '<form class="search-form" action="//www.baidu.com/baidu" method="get" accept-charset="utf-8" target="_blank"><input type="search" name="word" maxlength="30" placeholder="百度全站搜索"><input type="hidden" name="si" value="xuehuayu.cn"><input type="hidden" name="cl" value="3"><input type="hidden" name="ct" value="2097152"><input type="hidden" name="s" value="on"><input class="search-submit" type="submit" value=""/></form>'
|
|
412
|
-
|
|
413
|
-
if (val === 'self') {
|
|
414
|
-
$('#search').html(self)
|
|
415
|
-
var search_path = 'search.xml';
|
|
416
|
-
if (search_path.length == 0) {
|
|
417
|
-
search_path = 'search.xml';
|
|
418
|
-
}
|
|
419
|
-
var path = 'https://cdn.staticaly.com/gh/npljy/npljy.github.io/main/' + search_path;
|
|
420
|
-
searchFunc(path, 'local-search-input', 'local-search-result');
|
|
421
|
-
} else if (val === 'baidu') {
|
|
422
|
-
$('#search').html(baidu)
|
|
423
|
-
} else if (val === 'google') {
|
|
424
|
-
$('#search').html(google)
|
|
425
|
-
}
|
|
426
|
-
})</script><div class="widget widget-wxmp"><img alt="微信公众号" width="100%" src="//cdn.staticaly.com/gh/npljy/npljy.github.io/main/img/mp-mini.jpg"/></div><div class="widget widget-categories"><div class="widget-title"><i class="fa fa-folder-o"> 分类</i></div><ul class="category-list"><li class="category-list-item"><a class="category-list-link" href="/categories/CDN/">CDN</a><span class="category-list-count">2</span></li><li class="category-list-item"><a class="category-list-link" href="/categories/IDE/">IDE</a><span class="category-list-count">1</span></li><li class="category-list-item"><a class="category-list-link" href="/categories/git/">git</a><span class="category-list-count">2</span></li><li class="category-list-item"><a class="category-list-link" href="/categories/hexo/">hexo</a><span class="category-list-count">1</span></li><li class="category-list-item"><a class="category-list-link" href="/categories/%E5%85%AC%E5%85%B1%E8%8A%82%E6%97%A5/">公共节日</a><span class="category-list-count">1</span></li><li class="category-list-item"><a class="category-list-link" href="/categories/%E5%88%86%E4%BA%AB/">分享</a><span class="category-list-count">29</span></li><li class="category-list-item"><a class="category-list-link" href="/categories/%E5%89%8D%E7%AB%AF/">前端</a><span class="category-list-count">190</span><ul class="category-list-child"><li class="category-list-item"><a class="category-list-link" href="/categories/%E5%89%8D%E7%AB%AF/%E6%B5%8F%E8%A7%88%E5%99%A8/">浏览器</a><span class="category-list-count">1</span><ul class="category-list-child"><li class="category-list-item"><a class="category-list-link" href="/categories/%E5%89%8D%E7%AB%AF/%E6%B5%8F%E8%A7%88%E5%99%A8/%E7%BD%91%E7%BB%9C%E5%8D%8F%E8%AE%AE/">网络协议</a><span class="category-list-count">1</span></li></ul></li></ul></li><li class="category-list-item"><a class="category-list-link" href="/categories/%E5%8D%9A%E5%AE%A2/">博客</a><span class="category-list-count">3</span></li><li class="category-list-item"><a class="category-list-link" href="/categories/%E5%B7%A5%E5%85%B7/">工具</a><span class="category-list-count">2</span></li><li class="category-list-item"><a class="category-list-link" href="/categories/%E5%B9%BF%E5%91%8A%E8%BF%87%E6%BB%A4/">广告过滤</a><span class="category-list-count">8</span><ul class="category-list-child"><li class="category-list-item"><a class="category-list-link" href="/categories/%E5%B9%BF%E5%91%8A%E8%BF%87%E6%BB%A4/%E5%BD%B1%E8%A7%86%E7%94%B5%E8%A7%86%E5%B0%8F%E8%AF%B4%E6%BC%AB%E7%94%BB%E8%B5%84%E8%AE%AF%E9%9F%B3%E4%B9%90/">影视电视小说漫画资讯音乐</a><span class="category-list-count">1</span></li><li class="category-list-item"><a class="category-list-link" href="/categories/%E5%B9%BF%E5%91%8A%E8%BF%87%E6%BB%A4/%E8%A7%86%E9%A2%91%E7%94%B5%E8%A7%86%E5%B0%8F%E8%AF%B4%E6%BC%AB%E7%94%BB%E8%B5%84%E8%AE%AF%E9%9F%B3%E4%B9%90/">视频电视小说漫画资讯音乐</a><span class="category-list-count">1</span></li></ul></li><li class="category-list-item"><a class="category-list-link" href="/categories/%E6%AD%A3%E5%88%99/">正则</a><span class="category-list-count">5</span></li><li class="category-list-item"><a class="category-list-link" href="/categories/%E6%B5%8F%E8%A7%88%E5%99%A8/">浏览器</a><span class="category-list-count">5</span></li><li class="category-list-item"><a class="category-list-link" href="/categories/%E7%AE%97%E6%B3%95/">算法</a><span class="category-list-count">2</span></li><li class="category-list-item"><a class="category-list-link" href="/categories/%E8%B5%84%E8%AE%AF/">资讯</a><span class="category-list-count">16</span></li><li class="category-list-item"><a class="category-list-link" href="/categories/%E8%BD%BB%E6%9D%BE%E4%B8%80%E5%88%BB/">轻松一刻</a><span class="category-list-count">1</span></li></ul></div><div class="widget widget-tags"><div class="widget-title"><i class="fa fa-star-o"> 标签</i></div><div class="tagcloud"><a href="/tags/%E5%8E%9F%E5%88%9B/" style="font-size: 15px;">原创</a> <a href="/tags/%E8%BD%AC%E8%BD%BD/" style="font-size: 15px;">转载</a> <a href="/tags/%E6%89%8B%E5%86%99/" style="font-size: 15px;">手写</a> <a href="/tags/%E7%96%AB%E6%83%85/" style="font-size: 15px;">疫情</a> <a href="/tags/%E5%A8%B1%E4%B9%90/" style="font-size: 15px;">娱乐</a></div></div><div class="widget widget-recent-posts"><div class="widget-title"><i class="fa fa-file-o"> 最近文章</i></div><ul class="post-list"><li class="post-list-item"><a class="post-list-link" href="/article/9c3c56c.html">vue、react、webpack、babel</a></li><li class="post-list-item"><a class="post-list-link" href="/article/84c9ccd6.html">精读《SolidJS》</a></li><li class="post-list-item"><a class="post-list-link" href="/article/53803e6.html">git提交注释规范</a></li><li class="post-list-item"><a class="post-list-link" href="/article/a4145266.html">前端数组拍平flat一行代码</a></li><li class="post-list-item"><a class="post-list-link" href="/article/bedea419.html">一道前端this面试题</a></li><li class="post-list-item"><a class="post-list-link" href="/article/bf7e7421.html">git多账号配置</a></li></ul></div><div class="widget widget-links"><div class="widget-title"><i class="fa fa-external-link"> 友情链接</i></div><ul></ul><a href="https://github.com/npljy?utm_source=xuehuayu.cn" title="GitHub" target="_blank">GitHub</a><ul></ul><a href="https://laonongmin.online?utm_source=xuehuayu.cn" title="看看" target="_blank">看看</a><ul></ul><a href="https://cainiaoblog.cn?utm_source=xuehuayu.cn" title="菜鸟博客" target="_blank">菜鸟博客</a><ul></ul><a href="mailto:cainiaoblog@126.com" title="友链联系" target="_blank">友链联系</a></div></div></div><div class="pure-u-1 pure-u-md-3-4"><div id="footer"><div class="flex-block justify-center align-center flex-wrap"><a class="gxba-link" id="gxba" rel="nofollow" target="_blank" href="http://beian.miit.gov.cn/">京ICP备20007647号-2</a><a class="gaba-link" id="gaba-link" rel="nofollow" target="_blank" href="http://www.beian.gov.cn/portal/registerSystemInfo?recordcode=11010802031264"><img class="nofancybox" src="//cdn.staticaly.com/gh/npljy/npljy.github.io/main/img/gaba.png" alt=""/><span id="gaba">京公网安备 11010802031264号</span><span style="padding-right: 10px;"></span></a><span>Copyright © 2023 </span><a href="/." rel="nofollow">前端壹菜鸟. </a><script>(function(){
|
|
427
|
-
var cnb =window.location.origin.indexOf('cainiaoblog') !==-1
|
|
428
|
-
if (cnb) {
|
|
429
|
-
var gxba =document.getElementById('gxba')
|
|
430
|
-
var gaba =document.getElementById('gaba')
|
|
431
|
-
var gabaLink =document.getElementById('gaba-link')
|
|
432
|
-
gxba.innerText ='京ICP备20007647号-1'
|
|
433
|
-
gaba.innerText ='京公网安备 11010802031254号'
|
|
434
|
-
gabaLink.setAttribute('href','http://www.beian.gov.cn/portal/registerSystemInfo?recordcode=11010802031254')
|
|
435
|
-
}
|
|
436
|
-
})()</script></div><div class="flex-block justify-center align-center flex-wrap"><a rel="nofollow" target="_blank" href="https://v6.51.la/s/Guz3lwHCsVme9Cu"><div class="busuanzi_container" id="busuanzi_container"><span class="busuanzi_container_site_pv" id="busuanzi_container_site_pv">访问量:<span id="busuanzi_value_site_pv"><i class="fa fa-spinner"></i></span></span><span class="busuanzi_container_site_uv" id="busuanzi_container_site_uv">访客数:<span id="busuanzi_value_site_uv"><i class="fa fa-spinner"></i></span></span><span style="padding-right: 10px;"></span></div></a><a rel="nofollow" target="_blank" href="https://www.upyun.com/?utm_source=lianmeng&utm_medium=referral"><span style="font-weight:bold;letter-spacing: 1px;">本网站由 </span><img class="nofancybox" height="32" style="vertical-align: middle" src="//cdn.staticaly.com/gh/npljy/npljy.github.io/main/img/upy_logo.min.svg" alt=""/><span style="font-weight:bold;letter-spacing: 1px;">提供CDN加速/云存储服务</span></a><span style="padding-right: 10px;"></span><a rel="nofollow" style="font-size:18px;font-weight:bold;vertical-align: middle" target="_blank" title="注册就送代金券可直接使用" href="https://console.upyun.com/register/?invite=HyDsjZHIL">注册</a></div></div></div></div><a class="show" id="rocket" href="#top"></a><div class="darkmode-toggle">🌓</div><script type="text/javascript" src="//cdn.jsdelivr.net/npm/cainiaoblog@latest/js/totop.min.js" async></script><script type="text/javascript" src="//cdn.jsdelivr.net/npm/cainiaoblog@latest/js/dark.min.js" async></script><script type="text/javascript" src="//cdn.jsdelivr.net/npm/cainiaoblog@latest/js/codeblock-resizer.min.js"></script><script type="text/javascript" src="//cdn.jsdelivr.net/npm/cainiaoblog@latest/js/smartresize.min.js"></script></div></body></html>
|