cainiaoblog 23.2.171
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/CNAME +1 -0
- package/MP_verify_o6dHCK5mIkxNpzvZ.txt +1 -0
- package/README.md +8 -0
- package/about/index.html +54 -0
- package/ads.txt +1 -0
- package/app/manual.html +104 -0
- package/appConfigs/config +1 -0
- package/archives/2018/index.html +48 -0
- package/archives/2019/index.html +48 -0
- package/archives/2019/page/2/index.html +48 -0
- package/archives/2020/index.html +48 -0
- package/archives/2021/index.html +48 -0
- package/archives/2022/index.html +48 -0
- package/archives/2023/index.html +48 -0
- package/archives/index.html +48 -0
- package/archives/page/2/index.html +48 -0
- package/archives/page/3/index.html +48 -0
- package/article/10047.html +148 -0
- package/article/10164.html +64 -0
- package/article/10624.html +436 -0
- package/article/10745.html +586 -0
- package/article/11674.html +71 -0
- package/article/11939.html +72 -0
- package/article/12238.html +86 -0
- package/article/1230.html +533 -0
- package/article/13265.html +69 -0
- package/article/13823.html +78 -0
- package/article/14125.html +72 -0
- package/article/14192.html +561 -0
- package/article/14375.html +85 -0
- package/article/14744.html +83 -0
- package/article/14936.html +451 -0
- package/article/1518.html +250 -0
- package/article/15428.html +71 -0
- package/article/15518.html +288 -0
- package/article/15569.html +418 -0
- package/article/1566.html +122 -0
- package/article/16017.html +156 -0
- package/article/16947.html +440 -0
- package/article/17096.html +82 -0
- package/article/17246.html +89 -0
- package/article/17575.html +350 -0
- package/article/179.html +757 -0
- package/article/18039.html +233 -0
- package/article/18071.html +375 -0
- package/article/18142.html +71 -0
- package/article/19909.html +160 -0
- package/article/20014.html +89 -0
- package/article/20021.html +389 -0
- package/article/20037.html +280 -0
- package/article/20056.html +95 -0
- package/article/20093.html +404 -0
- package/article/2021.html +607 -0
- package/article/20459.html +115 -0
- package/article/20613.html +263 -0
- package/article/20635.html +71 -0
- package/article/21317.html +71 -0
- package/article/21320.html +90 -0
- package/article/21782.html +548 -0
- package/article/22230.html +435 -0
- package/article/22237.html +347 -0
- package/article/22398.html +109 -0
- package/article/22422.html +270 -0
- package/article/22565.html +300 -0
- package/article/23046.html +250 -0
- package/article/23083.html +215 -0
- package/article/23195.html +297 -0
- package/article/23301.html +835 -0
- package/article/23589.html +285 -0
- package/article/23655.html +338 -0
- package/article/23864.html +76 -0
- package/article/23914.html +96 -0
- package/article/24169.html +135 -0
- package/article/24581.html +349 -0
- package/article/2475.html +500 -0
- package/article/24826.html +77 -0
- package/article/24924.html +247 -0
- package/article/25164.html +1495 -0
- package/article/25318.html +394 -0
- package/article/25710.html +1129 -0
- package/article/25734.html +83 -0
- package/article/26083.html +174 -0
- package/article/26147.html +283 -0
- package/article/26291.html +110 -0
- package/article/26354.html +71 -0
- package/article/26624.html +145 -0
- package/article/26639.html +298 -0
- package/article/26850.html +138 -0
- package/article/26940.html +258 -0
- package/article/27796.html +190 -0
- package/article/27800.html +161 -0
- package/article/28963.html +159 -0
- package/article/28976.html +247 -0
- package/article/29042.html +72 -0
- package/article/29596.html +81 -0
- package/article/29619.html +183 -0
- package/article/29623.html +329 -0
- package/article/29829.html +205 -0
- package/article/29abbd1c.html +112 -0
- package/article/30215.html +178 -0
- package/article/30552.html +78 -0
- package/article/30818.html +201 -0
- package/article/31330.html +364 -0
- package/article/3154.html +577 -0
- package/article/31695.html +348 -0
- package/article/31826.html +71 -0
- package/article/31843.html +132 -0
- package/article/32280.html +212 -0
- package/article/32431.html +74 -0
- package/article/32443.html +72 -0
- package/article/32732.html +122 -0
- package/article/3286.html +251 -0
- package/article/32960.html +198 -0
- package/article/33713.html +72 -0
- package/article/33899.html +615 -0
- package/article/34351.html +74 -0
- package/article/34372.html +89 -0
- package/article/34410.html +74 -0
- package/article/34431.html +118 -0
- package/article/3447.html +75 -0
- package/article/34474.html +142 -0
- package/article/34871.html +147 -0
- package/article/35397.html +175 -0
- package/article/3544.html +199 -0
- package/article/35503.html +115 -0
- package/article/35624.html +84 -0
- package/article/35697.html +384 -0
- package/article/35863.html +73 -0
- package/article/36037.html +253 -0
- package/article/36118.html +71 -0
- package/article/3621.html +119 -0
- package/article/36251.html +296 -0
- package/article/36642.html +352 -0
- package/article/37102.html +763 -0
- package/article/37336.html +351 -0
- package/article/37351.html +89 -0
- package/article/3760.html +294 -0
- package/article/37749.html +75 -0
- package/article/37789.html +83 -0
- package/article/38005.html +765 -0
- package/article/38009.html +284 -0
- package/article/38269.html +194 -0
- package/article/38344.html +88 -0
- package/article/38359.html +334 -0
- package/article/38423.html +379 -0
- package/article/38530.html +213 -0
- package/article/38743.html +268 -0
- package/article/38753.html +204 -0
- package/article/38881.html +71 -0
- package/article/39087.html +414 -0
- package/article/39309.html +84 -0
- package/article/39486.html +74 -0
- package/article/39637.html +306 -0
- package/article/39839.html +72 -0
- package/article/39937.html +152 -0
- package/article/39970.html +71 -0
- package/article/402.html +559 -0
- package/article/40698.html +71 -0
- package/article/40811.html +71 -0
- package/article/40964.html +462 -0
- package/article/41011.html +322 -0
- package/article/41152.html +78 -0
- package/article/41696.html +71 -0
- package/article/41717.html +281 -0
- package/article/41777.html +149 -0
- package/article/419.html +985 -0
- package/article/4233.html +136 -0
- package/article/4292.html +86 -0
- package/article/43302.html +96 -0
- package/article/43397.html +106 -0
- package/article/43724.html +281 -0
- package/article/43999.html +224 -0
- package/article/44426.html +77 -0
- package/article/44964.html +137 -0
- package/article/45004.html +123 -0
- package/article/4510.html +83 -0
- package/article/45156.html +320 -0
- package/article/45157.html +52 -0
- package/article/45267.html +87 -0
- package/article/45641.html +207 -0
- package/article/45960.html +75 -0
- package/article/46100.html +1262 -0
- package/article/46366.html +74 -0
- package/article/46771.html +96 -0
- package/article/46911.html +517 -0
- package/article/46948.html +137 -0
- package/article/46ee4850.html +349 -0
- package/article/47019.html +84 -0
- package/article/47532.html +94 -0
- package/article/4783.html +429 -0
- package/article/47972.html +72 -0
- package/article/48216.html +127 -0
- package/article/48252.html +185 -0
- package/article/48520.html +74 -0
- package/article/48722.html +75 -0
- package/article/48807.html +99 -0
- package/article/49126.html +323 -0
- package/article/50001.html +88 -0
- package/article/50058.html +151 -0
- package/article/50343.html +410 -0
- package/article/50510.html +82 -0
- package/article/51082.html +98 -0
- package/article/51677.html +111 -0
- package/article/5204.html +1085 -0
- package/article/52500.html +538 -0
- package/article/52689.html +259 -0
- package/article/52877.html +569 -0
- package/article/53125.html +191 -0
- package/article/53428.html +251 -0
- package/article/53524.html +74 -0
- package/article/53698.html +322 -0
- package/article/53803e6.html +93 -0
- package/article/53924.html +291 -0
- package/article/53962.html +253 -0
- package/article/54006.html +71 -0
- package/article/54018.html +88 -0
- package/article/54161.html +83 -0
- package/article/54178.html +69 -0
- package/article/54258.html +327 -0
- package/article/54295.html +214 -0
- package/article/54313.html +1976 -0
- package/article/54351.html +90 -0
- package/article/54604.html +80 -0
- package/article/54632.html +71 -0
- package/article/54912.html +756 -0
- package/article/54918.html +129 -0
- package/article/55119.html +136 -0
- package/article/55756.html +118 -0
- package/article/55769.html +136 -0
- package/article/55870.html +161 -0
- package/article/56139.html +92 -0
- package/article/56557.html +69 -0
- package/article/56604.html +69 -0
- package/article/56816.html +266 -0
- package/article/56926.html +153 -0
- package/article/57747.html +409 -0
- package/article/57965.html +475 -0
- package/article/58816.html +78 -0
- package/article/59059.html +435 -0
- package/article/59095.html +350 -0
- package/article/59349.html +244 -0
- package/article/59402.html +216 -0
- package/article/59448.html +55 -0
- package/article/59870.html +94 -0
- package/article/59877.html +208 -0
- package/article/5dbb6f41.html +86 -0
- package/article/6008.html +75 -0
- package/article/60327.html +126 -0
- package/article/6035.html +76 -0
- package/article/60428.html +71 -0
- package/article/60544.html +128 -0
- package/article/61319.html +95 -0
- package/article/61367.html +93 -0
- package/article/624d1918.html +292 -0
- package/article/62543.html +71 -0
- package/article/62887.html +169 -0
- package/article/63074.html +120 -0
- package/article/63266.html +311 -0
- package/article/63351.html +74 -0
- package/article/63542.html +104 -0
- package/article/63824.html +275 -0
- package/article/64051.html +653 -0
- package/article/64189b69.html +72 -0
- package/article/64354.html +75 -0
- package/article/64869.html +79 -0
- package/article/64923.html +596 -0
- package/article/65128.html +95 -0
- package/article/65295.html +79 -0
- package/article/6888.html +75 -0
- package/article/7065.html +84 -0
- package/article/7455.html +85 -0
- package/article/7a3ef8f.html +315 -0
- package/article/8140.html +188 -0
- package/article/8190.html +85 -0
- package/article/8225.html +78 -0
- package/article/84c9ccd6.html +159 -0
- package/article/8f9a9ae3.html +82 -0
- package/article/9174.html +73 -0
- package/article/9738.html +294 -0
- package/article/a4145266.html +71 -0
- package/article/bedea419.html +72 -0
- package/article/bf7e7421.html +78 -0
- package/article/c1867fbf.html +103 -0
- package/article/c5576490.html +70 -0
- package/article/dcb0db28.html +76 -0
- package/article/fc3b727a.html +79 -0
- package/atom.xml +445 -0
- package/baidusitemap.xml +1079 -0
- package/blocks/dns.txt +264 -0
- package/blocks/filter.txt +1070 -0
- package/blocks/script.js +42 -0
- package/categories/CDN/index.html +48 -0
- package/categories/IDE/index.html +48 -0
- package/categories/git/index.html +48 -0
- package/categories/hexo/index.html +48 -0
- package/categories//345/205/254/345/205/261/350/212/202/346/227/245/index.html +48 -0
- package/categories//345/210/206/344/272/253/index.html +48 -0
- package/categories//345/211/215/347/253/257/index.html +48 -0
- package/categories//345/211/215/347/253/257/page/2/index.html +48 -0
- package/categories//345/211/215/347/253/257//346/265/217/350/247/210/345/231/250/index.html +48 -0
- 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 +48 -0
- package/categories//345/215/232/345/256/242/index.html +48 -0
- package/categories//345/267/245/345/205/267/index.html +48 -0
- package/categories//345/271/277/345/221/212/350/277/207/346/273/244/index.html +48 -0
- 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 +48 -0
- package/categories//346/255/243/345/210/231/index.html +48 -0
- package/categories//346/265/217/350/247/210/345/231/250/index.html +48 -0
- package/categories//347/256/227/346/263/225/index.html +48 -0
- package/categories//350/265/204/350/256/257/index.html +48 -0
- package/categories//350/275/273/346/235/276/344/270/200/345/210/273/index.html +48 -0
- package/cdn/css/font-awesome.min.css +4 -0
- package/cdn/css/grids-responsive-min.css +7 -0
- package/cdn/css/normalize.css +349 -0
- package/cdn/css/pure-min.css +11 -0
- package/cdn/fonts/fontawesome-webfont.eot +0 -0
- package/cdn/fonts/fontawesome-webfont.svg +2671 -0
- 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 +17 -0
- package/cdn/js/canvas-nest.js +1 -0
- package/cdn/js/clipboard.min.js +7 -0
- package/cdn/js/crypto-js.js +25 -0
- package/cdn/js/jquery.min.js +2 -0
- package/css/default.css +1144 -0
- package/css/donate.css +338 -0
- package/css/hbe.style.css +749 -0
- package/css/style.css +2095 -0
- package/donate/index.html +39 -0
- package/google917dcf72f6e5c7f5.html +1 -0
- package/guestbook/index.html +68 -0
- package/hosts/ads.txt +149 -0
- package/hosts/flash.txt +9 -0
- package/hosts/github.txt +6 -0
- package/hosts/google.txt +16936 -0
- package/hosts/winrar.txt +2 -0
- package/img/alipay.svg +46 -0
- package/img/bitcoin.svg +135 -0
- package/img/blog.ico +0 -0
- package/img/blog.png +0 -0
- package/img/gaba.png +0 -0
- package/img/github.svg +1 -0
- package/img/like.svg +1 -0
- package/img/mp-mini.jpg +0 -0
- package/img/mp.png +0 -0
- package/img/paypal.svg +63 -0
- package/img/upy_logo.svg +59 -0
- package/img/wechat.svg +49 -0
- package/index.html +48 -0
- package/jd_root.txt +1 -0
- package/js/codeblock-resizer.js +51 -0
- package/js/dark.js +12 -0
- package/js/donate.js +87 -0
- package/js/fixedPage.js +106 -0
- package/js/gitment.browser.js +3751 -0
- package/js/search.js +86 -0
- package/js/share.js +60 -0
- package/js/smartresize.js +32 -0
- package/js/totop.js +12 -0
- package/kankan/index.html +77 -0
- package/lib/hbe.js +293 -0
- package/package.json +25 -0
- package/page/10/index.html +49 -0
- package/page/11/index.html +59 -0
- package/page/12/index.html +67 -0
- package/page/13/index.html +63 -0
- package/page/14/index.html +66 -0
- package/page/15/index.html +60 -0
- package/page/16/index.html +60 -0
- package/page/17/index.html +62 -0
- package/page/18/index.html +61 -0
- package/page/19/index.html +58 -0
- package/page/2/index.html +48 -0
- package/page/20/index.html +57 -0
- package/page/21/index.html +61 -0
- package/page/22/index.html +55 -0
- package/page/23/index.html +64 -0
- package/page/24/index.html +60 -0
- package/page/25/index.html +58 -0
- package/page/26/index.html +48 -0
- package/page/27/index.html +58 -0
- package/page/3/index.html +48 -0
- package/page/4/index.html +48 -0
- package/page/5/index.html +51 -0
- package/page/6/index.html +51 -0
- package/page/7/index.html +51 -0
- package/page/8/index.html +53 -0
- package/page/9/index.html +48 -0
- package/randomcall/README.html +1 -0
- package/randomcall/lucker.html +290 -0
- package/randomcall/lucky.png +0 -0
- package/robots.txt +22 -0
- package/search.xml +6740 -0
- package/sitemap.xml +2669 -0
- package/tags//345/216/237/345/210/233/index.html +48 -0
- package/tags//345/250/261/344/271/220/index.html +48 -0
- package/tags//346/211/213/345/206/231/index.html +48 -0
- package/tags//347/226/253/346/203/205/index.html +48 -0
- package/tags//350/275/254/350/275/275/index.html +48 -0
- package/tags//350/275/254/350/275/275/page/2/index.html +48 -0
- package/v.html +90 -0
|
@@ -0,0 +1,384 @@
|
|
|
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>npm install 原理分析 | 前端壹菜鸟</title><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/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.staticaly.com/gh/npljy/npljy.github.io/main/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">npm install 原理分析</h1><div class="post-meta"><span class="date">2019-12-27</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%89%8D%E7%AB%AF/">前端 </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"> 4.3k</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"> 17</span><span class="post-meta-item-text"> 分钟</span></span></span></div><a class="disqus-comment-count" href="/article/35697.html#vcomment"><span class="waline-comment-count" data-path="/article/35697.html"></span><span> 条评论</span></a><div class="post-content"><blockquote>
|
|
20
|
+
<p>作者: code秘密花园 公号 / ConardLi (本文来自作者投稿)<br><code>原文地址:https</code>://mp.weixin.qq.com/s/5tmND0G_ZkYVR7Dmug0ugQ`</p>
|
|
21
|
+
</blockquote>
|
|
22
|
+
<p>开门见山,<code>npm install</code> 大概会经过上面的几个流程,本篇文章来讲一讲各个流程的实现细节、发展以及为何要这样实现。</p>
|
|
23
|
+
<span id="more"></span>
|
|
24
|
+
|
|
25
|
+
<p><img src="https://mmbiz.qpic.cn/mmbiz_png/aDoYvepE5x07V71lB2Paq6xf9EexnFcVD240SNZBLIwLogx4AEue7BLFeSSglH5MFk8oAtkMznOZRatVjugofg/640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1" alt="xuehuayu.cn"></p>
|
|
26
|
+
<h2 id="嵌套结构"><a href="#嵌套结构" class="headerlink" title="嵌套结构"></a>嵌套结构</h2><p>我们都知道,执行 <code>npm install</code> 后,依赖包被安装到了 <code>node_modules</code> ,下面我们来具体了解下,<code>npm</code> 将依赖包安装到 <code>node_modules</code> 的具体机制是什么。</p>
|
|
27
|
+
<p>在 <code>npm</code> 的早期版本, <code>npm</code> 处理依赖的方式简单粗暴,以递归的形式,严格按照 <code>package.json</code> 结构以及子依赖包的 <code>package.json</code> 结构将依赖安装到他们各自的 <code>node_modules</code> 中。直到有子依赖包不在依赖其他模块。</p>
|
|
28
|
+
<p>举个例子,我们的模块 <code>my-app</code> 现在依赖了两个模块:<code>buffer</code>、<code>ignore</code>:</p>
|
|
29
|
+
<pre><code>{
|
|
30
|
+
"name": "my-app",
|
|
31
|
+
"dependencies": {
|
|
32
|
+
"buffer": "^5.4.3",
|
|
33
|
+
"ignore": "^5.1.4",
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
</code></pre>
|
|
37
|
+
<p><code>ignore</code>是一个纯 <code>JS</code> 模块,不依赖任何其他模块,而 <code>buffer</code> 又依赖了下面两个模块:<code>base64-js</code> 、 <code>ieee754</code>。</p>
|
|
38
|
+
<pre><code>{
|
|
39
|
+
"name": "buffer",
|
|
40
|
+
"dependencies": {
|
|
41
|
+
"base64-js": "^1.0.2",
|
|
42
|
+
"ieee754": "^1.1.4"
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
</code></pre>
|
|
46
|
+
<p>那么,执行 <code>npm install</code> 后,得到的 <code>node_modules</code> 中模块目录结构就是下面这样的:<br><img src="https://mmbiz.qpic.cn/mmbiz_png/aDoYvepE5x07V71lB2Paq6xf9EexnFcVWoBdnbZrwALkMuqX7zBSicT68layF5DbnJGGxTeY94jZzEwryqKsGhg/640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1" alt="xuehuayu.cn"><br>这样的方式优点很明显, <code>node_modules</code> 的结构和 <code>package.json</code> 结构一一对应,层级结构明显,并且保证了每次安装目录结构都是相同的。</p>
|
|
47
|
+
<p>但是,试想一下,如果你依赖的模块非常之多,你的 <code>node_modules</code> 将非常庞大,嵌套层级非常之深:</p>
|
|
48
|
+
<p><img src="https://mmbiz.qpic.cn/mmbiz_png/aDoYvepE5x07V71lB2Paq6xf9EexnFcVsVhNShUm7cMBGZmyFRMwNXDHurgl7oBsHbzGmevX2V26PJWpI1gvSA/640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1" alt="xuehuayu.cn"></p>
|
|
49
|
+
<ul>
|
|
50
|
+
<li><p>在不同层级的依赖中,可能引用了同一个模块,导致大量冗余。</p>
|
|
51
|
+
</li>
|
|
52
|
+
<li><p>在 <code>Windows</code> 系统中,文件路径最大长度为260个字符,嵌套层级过深可能导致不可预知的问题。</p>
|
|
53
|
+
</li>
|
|
54
|
+
</ul>
|
|
55
|
+
<h2 id="扁平结构"><a href="#扁平结构" class="headerlink" title="扁平结构"></a>扁平结构</h2><p>为了解决以上问题,<code>NPM</code> 在 <code>3.x</code> 版本做了一次较大更新。其将早期的嵌套结构改为扁平结构:</p>
|
|
56
|
+
<ul>
|
|
57
|
+
<li>安装模块时,不管其是直接依赖还是子依赖的依赖,优先将其安装在 <code>node_modules</code> 根目录。</li>
|
|
58
|
+
</ul>
|
|
59
|
+
<p>还是上面的依赖结构,我们在执行 <code>npm install</code> 后将得到下面的目录结构:<br><img src="https://mmbiz.qpic.cn/mmbiz_png/aDoYvepE5x07V71lB2Paq6xf9EexnFcVwQTfNrouibsRDp1iccMx09157icNIGl6ic1Ck9hklrut9Oic87h5sJmveXQ/640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1" alt="xuehuayu.cn"><img src="https://mmbiz.qpic.cn/mmbiz_png/aDoYvepE5x07V71lB2Paq6xf9EexnFcVHjHHmKYz9vegse7GXo0wHqhrE0WPUtscmiabGPIItiajttWHb8C5YAsw/640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1" alt="xuehuayu.cn"><br>此时我们若在模块中又依赖了 <code>base64-js@1.0.1</code> 版本:</p>
|
|
60
|
+
<pre><code>{
|
|
61
|
+
"name": "my-app",
|
|
62
|
+
"dependencies": {
|
|
63
|
+
"buffer": "^5.4.3",
|
|
64
|
+
"ignore": "^5.1.4",
|
|
65
|
+
"base64-js": "1.0.1",
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
</code></pre>
|
|
69
|
+
<ul>
|
|
70
|
+
<li>当安装到相同模块时,判断已安装的模块版本是否符合新模块的版本范围,如果符合则跳过,不符合则在当前模块的 <code>node_modules</code> 下安装该模块。</li>
|
|
71
|
+
</ul>
|
|
72
|
+
<p>此时,我们在执行 <code>npm install</code> 后将得到下面的目录结构:<br><img src="https://mmbiz.qpic.cn/mmbiz_png/aDoYvepE5x07V71lB2Paq6xf9EexnFcViceD3Ec53rMic1KvTXN7fSFOer0kPiaMldtqQLhJYYxTqUWjlUhKMaxkA/640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1" alt="xuehuayu.cn"><img src="https://mmbiz.qpic.cn/mmbiz_png/aDoYvepE5x07V71lB2Paq6xf9EexnFcVvJMgKibou2czMUL88vUrhFkJNefaQ63ic8Qhrom4AYBygAVDHcPDhezg/640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1" alt="xuehuayu.cn"><br>对应的,如果我们在项目代码中引用了一个模块,模块查找流程如下:</p>
|
|
73
|
+
<ul>
|
|
74
|
+
<li><p>在当前模块路径下搜索</p>
|
|
75
|
+
</li>
|
|
76
|
+
<li><p>在当前模块 <code>node_modules</code> 路径下搜素</p>
|
|
77
|
+
</li>
|
|
78
|
+
<li><p>在上级模块的 <code>node_modules</code> 路径下搜索</p>
|
|
79
|
+
</li>
|
|
80
|
+
<li><p>…</p>
|
|
81
|
+
</li>
|
|
82
|
+
<li><p>直到搜索到全局路径中的 <code>node_modules</code></p>
|
|
83
|
+
</li>
|
|
84
|
+
</ul>
|
|
85
|
+
<p>假设我们又依赖了一个包 <code>buffer2@^5.4.3</code>,而它依赖了包 <code>base64-js@1.0.3</code>,则此时的安装结构是下面这样的:<br><img src="https://mmbiz.qpic.cn/mmbiz_png/aDoYvepE5x07V71lB2Paq6xf9EexnFcVlqy2xAw9kOnZGibmiauHfD8V7YaoxTPIKkm5IHDD8J3Qwk32SwThdKfw/640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1" alt="xuehuayu.cn"><br>所以 <code>npm 3.x</code> 版本并未完全解决老版本的模块冗余问题,甚至还会带来新的问题。</p>
|
|
86
|
+
<p>试想一下,你的APP假设没有依赖 <code>base64-js@1.0.1</code> 版本,而你同时依赖了依赖不同 <code>base64-js</code> 版本的 <code>buffer</code> 和 <code>buffer2</code>。由于在执行 <code>npm install</code> 的时候,按照 <code>package.json</code> 里依赖的顺序依次解析,则 <code>buffer</code> 和 <code>buffer2</code> 在 <code>package.json</code> 的放置顺序则决定了 <code>node_modules</code> 的依赖结构:</p>
|
|
87
|
+
<p>先依赖<code>buffer2</code>:<br><img src="https://mmbiz.qpic.cn/mmbiz_png/aDoYvepE5x07V71lB2Paq6xf9EexnFcVGG4KNBgDP4tYsfraJJ6vuibBfddbUxrceuicicyhNC8axqiacX35pxLWpg/640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1" alt="xuehuayu.cn"><br>先依赖<code>buffer</code>:<br><img src="data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVQImWNgYGBgAAAABQABh6FO1AAAAABJRU5ErkJggg==" alt="xuehuayu.cn"><br>另外,为了让开发者在安全的前提下使用最新的依赖包,我们在 <code>package.json</code> 通常只会锁定大版本,这意味着在某些依赖包小版本更新后,同样可能造成依赖结构的改动,依赖结构的不确定性可能会给程序带来不可预知的问题。</p>
|
|
88
|
+
<h2 id="Lock文件"><a href="#Lock文件" class="headerlink" title="Lock文件"></a>Lock文件</h2><p>为了解决 <code>npm install</code> 的不确定性问题,在 <code>npm 5.x</code> 版本新增了 <code>package-lock.json</code> 文件,而安装方式还沿用了 <code>npm 3.x</code> 的扁平化的方式。</p>
|
|
89
|
+
<p><code>package-lock.json</code> 的作用是锁定依赖结构,即只要你目录下有 <code>package-lock.json</code> 文件,那么你每次执行 <code>npm install</code> 后生成的 <code>node_modules</code> 目录结构一定是完全相同的。</p>
|
|
90
|
+
<p>例如,我们有如下的依赖结构:</p>
|
|
91
|
+
<pre><code>{
|
|
92
|
+
"name": "my-app",
|
|
93
|
+
"dependencies": {
|
|
94
|
+
"buffer": "^5.4.3",
|
|
95
|
+
"ignore": "^5.1.4",
|
|
96
|
+
"base64-js": "1.0.1",
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
</code></pre>
|
|
100
|
+
<p>在执行 <code>npm install</code> 后生成的 <code>package-lock.json</code> 如下:</p>
|
|
101
|
+
<pre><code>{
|
|
102
|
+
"name": "my-app",
|
|
103
|
+
"version": "1.0.0",
|
|
104
|
+
"dependencies": {
|
|
105
|
+
"base64-js": {
|
|
106
|
+
"version": "1.0.1",
|
|
107
|
+
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.0.1.tgz",
|
|
108
|
+
"integrity": "sha1-aSbRsZT7xze47tUTdW3i/Np+pAg="
|
|
109
|
+
},
|
|
110
|
+
"buffer": {
|
|
111
|
+
"version": "5.4.3",
|
|
112
|
+
"resolved": "https://registry.npmjs.org/buffer/-/buffer-5.4.3.tgz",
|
|
113
|
+
"integrity": "sha512-zvj65TkFeIt3i6aj5bIvJDzjjQQGs4o/sNoezg1F1kYap9Nu2jcUdpwzRSJTHMMzG0H7bZkn4rNQpImhuxWX2A==",
|
|
114
|
+
"requires": {
|
|
115
|
+
"base64-js": "^1.0.2",
|
|
116
|
+
"ieee754": "^1.1.4"
|
|
117
|
+
},
|
|
118
|
+
"dependencies": {
|
|
119
|
+
"base64-js": {
|
|
120
|
+
"version": "1.3.1",
|
|
121
|
+
"resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.3.1.tgz",
|
|
122
|
+
"integrity": "sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g=="
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
},
|
|
126
|
+
"ieee754": {
|
|
127
|
+
"version": "1.1.13",
|
|
128
|
+
"resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.1.13.tgz",
|
|
129
|
+
"integrity": "sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg=="
|
|
130
|
+
},
|
|
131
|
+
"ignore": {
|
|
132
|
+
"version": "5.1.4",
|
|
133
|
+
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.1.4.tgz",
|
|
134
|
+
"integrity": "sha512-MzbUSahkTW1u7JpKKjY7LCARd1fU5W2rLdxlM4kdkayuCwZImjkpluF9CM1aLewYJguPDqewLam18Y6AU69A8A=="
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
</code></pre>
|
|
139
|
+
<p>我们来具体看看上面的结构:<br><img src="https://mmbiz.qpic.cn/mmbiz_png/aDoYvepE5x07V71lB2Paq6xf9EexnFcVuCWAF9VfKQiaichicf9DqiaqkQjXaVicF4tKQUNtyIgaTS1t3t9Mly0aOUg/640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1" alt="xuehuayu.cn"><br>最外面的两个属性 <code>name</code> 、<code>version</code> 同 <code>package.json</code> 中的 <code>name</code> 和 <code>version</code> ,用于描述当前包名称和版本。</p>
|
|
140
|
+
<p><code>dependencies</code> 是一个对象,对象和 <code>node_modules</code> 中的包结构一一对应,对象的 <code>key</code> 为包名称,值为包的一些描述信息:</p>
|
|
141
|
+
<ul>
|
|
142
|
+
<li><p><code>version</code>:包版本 —— 这个包当前安装在 <code>node_modules</code> 中的版本</p>
|
|
143
|
+
</li>
|
|
144
|
+
<li><p><code>resolved</code>:包具体的安装来源</p>
|
|
145
|
+
</li>
|
|
146
|
+
<li><p><code>integrity</code>:包 <code>hash</code> 值,基于 <code>Subresource Integrity</code> 来验证已安装的软件包是否被改动过、是否已失效</p>
|
|
147
|
+
</li>
|
|
148
|
+
<li><p><code>requires</code>:对应子依赖的依赖,与子依赖的 <code>package.json</code> 中 <code>dependencies</code>的依赖项相同。</p>
|
|
149
|
+
</li>
|
|
150
|
+
<li><p><code>dependencies</code>:结构和外层的 <code>dependencies</code> 结构相同,存储安装在子依赖 <code>node_modules</code> 中的依赖包。</p>
|
|
151
|
+
</li>
|
|
152
|
+
</ul>
|
|
153
|
+
<p>这里注意,并不是所有的子依赖都有 <code>dependencies</code> 属性,只有子依赖的依赖和当前已安装在根目录的 <code>node_modules</code> 中的依赖冲突之后,才会有这个属性。</p>
|
|
154
|
+
<p>例如,回顾下上面的依赖关系:<br><img src="https://mmbiz.qpic.cn/mmbiz_png/aDoYvepE5x07V71lB2Paq6xf9EexnFcVvJMgKibou2czMUL88vUrhFkJNefaQ63ic8Qhrom4AYBygAVDHcPDhezg/640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1" alt="xuehuayu.cn"><br>我们在 <code>my-app</code> 中依赖的 <code>base64-js@1.0.1</code> 版本与 <code>buffer</code> 中依赖的 <code>base64-js@^1.0.2</code> 发生冲突,所以 <code>base64-js@1.0.1</code> 需要安装在 <code>buffer</code> 包的 <code>node_modules</code> 中,对应了 <code>package-lock.json</code> 中 <code>buffer</code> 的 <code>dependencies</code> 属性。这也对应了 <code>npm</code> 对依赖的扁平化处理方式。</p>
|
|
155
|
+
<p>所以,根据上面的分析, <code>package-lock.json</code> 文件 和 <code>node_modules</code> 目录结构是一一对应的,即项目目录下存在 <code>package-lock.json</code> 可以让每次安装生成的依赖目录结构保持相同。</p>
|
|
156
|
+
<p>另外,项目中使用了 <code>package-lock.json</code> 可以显著加速依赖安装时间。</p>
|
|
157
|
+
<p>我们使用 <code>npm i --timing=true --loglevel=verbose</code> 命令可以看到 <code>npm install</code> 的完整过程,下面我们来对比下使用 <code>lock</code> 文件和不使用 <code>lock</code> 文件的差别。在对比前先清理下<code>npm</code> 缓存。</p>
|
|
158
|
+
<p>不使用 <code>lock</code> 文件:<br><img src="https://mmbiz.qpic.cn/mmbiz_gif/aDoYvepE5x07V71lB2Paq6xf9EexnFcV2wXvKqVOP4DouJGf2dpvmdds2dcQEkRoEgIqUIKREhicoKMzia3JUw5w/640?wx_fmt=gif&tp=webp&wxfrom=5&wx_lazy=1" alt="xuehuayu.cn"><br>使用 <code>lock</code> 文件:<br><img src="https://mmbiz.qpic.cn/mmbiz_gif/aDoYvepE5x07V71lB2Paq6xf9EexnFcV2dYJnWXtOAWicaic6j1OXkJP1vV2hvX7v2HnhzdYT1LUnWiaMH9cGzNibw/640?wx_fmt=gif&tp=webp&wxfrom=5&wx_lazy=1" alt="xuehuayu.cn"><br>可见, <code>package-lock.json</code> 中已经缓存了每个包的具体版本和下载链接,不需要再去远程仓库进行查询,然后直接进入文件完整性校验环节,减少了大量网络请求。</p>
|
|
159
|
+
<h3 id="使用建议"><a href="#使用建议" class="headerlink" title="使用建议"></a>使用建议</h3><p>开发系统应用时,建议把 <code>package-lock.json</code> 文件提交到代码版本仓库,从而保证所有团队开发者以及 <code>CI</code> 环节可以在执行 <code>npm install</code> 时安装的依赖版本都是一致的。</p>
|
|
160
|
+
<p>在开发一个 <code>npm</code>包 时,你的 <code>npm</code>包 是需要被其他仓库依赖的,由于上面我们讲到的扁平安装机制,如果你锁定了依赖包版本,你的依赖包就不能和其他依赖包共享同一 <code>semver</code> 范围内的依赖包,这样会造成不必要的冗余。所以我们不应该把<code>package-lock.json</code> 文件发布出去( <code>npm</code> 默认也不会把 <code>package-lock.json</code> 文件发布出去)。</p>
|
|
161
|
+
<h2 id="缓存"><a href="#缓存" class="headerlink" title="缓存"></a>缓存</h2><p>在执行 <code>npm install</code> 或 <code>npm update</code>命令下载依赖后,除了将依赖包安装在<code>node_modules</code> 目录下外,还会在本地的缓存目录缓存一份。</p>
|
|
162
|
+
<p>通过 <code>npm config get cache</code> 命令可以查询到:在 <code>Linux</code> 或 <code>Mac</code> 默认是用户主目录下的 <code>.npm/_cacache</code> 目录。</p>
|
|
163
|
+
<p>在这个目录下又存在两个目录:<code>content-v2</code>、<code>index-v5</code>,<code>content-v2</code> 目录用于存储 <code>tar</code>包的缓存,而<code>index-v5</code>目录用于存储<code>tar</code>包的 <code>hash</code>。</p>
|
|
164
|
+
<p>npm 在执行安装时,可以根据 <code>package-lock.json</code> 中存储的 <code>integrity、version、name</code> 生成一个唯一的 <code>key</code> 对应到 <code>index-v5</code> 目录下的缓存记录,从而找到 <code>tar</code>包的 <code>hash</code>,然后根据 <code>hash</code> 再去找缓存的 <code>tar</code>包直接使用。</p>
|
|
165
|
+
<p>我们可以找一个包在缓存目录下搜索测试一下,在 <code>index-v5</code> 搜索一下包路径:</p>
|
|
166
|
+
<pre><code>grep "https://registry.npmjs.org/base64-js/-/base64-js-1.0.1.tgz" -r index-v5
|
|
167
|
+
</code></pre>
|
|
168
|
+
<p><img src="https://mmbiz.qpic.cn/mmbiz_png/aDoYvepE5x07V71lB2Paq6xf9EexnFcVukm2CxlEBDQWRernKUQqyU47zgJufPP5qG2U4ibmJTqxX5VqV4tSKUw/640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1" alt="xuehuayu.cn"><br>然后我们将json格式化:</p>
|
|
169
|
+
<pre><code>{
|
|
170
|
+
"key": "pacote:version-manifest:https://registry.npmjs.org/base64-js/-/base64-js-1.0.1.tgz:sha1-aSbRsZT7xze47tUTdW3i/Np+pAg=",
|
|
171
|
+
"integrity": "sha512-C2EkHXwXvLsbrucJTRS3xFHv7Mf/y9klmKDxPTE8yevCoH5h8Ae69Y+/lP+ahpW91crnzgO78elOk2E6APJfIQ==",
|
|
172
|
+
"time": 1575554308857,
|
|
173
|
+
"size": 1,
|
|
174
|
+
"metadata": {
|
|
175
|
+
"id": "base64-js@1.0.1",
|
|
176
|
+
"manifest": {
|
|
177
|
+
"name": "base64-js",
|
|
178
|
+
"version": "1.0.1",
|
|
179
|
+
"engines": {
|
|
180
|
+
"node": ">= 0.4"
|
|
181
|
+
},
|
|
182
|
+
"dependencies": {},
|
|
183
|
+
"optionalDependencies": {},
|
|
184
|
+
"devDependencies": {
|
|
185
|
+
"standard": "^5.2.2",
|
|
186
|
+
"tape": "4.x"
|
|
187
|
+
},
|
|
188
|
+
"bundleDependencies": false,
|
|
189
|
+
"peerDependencies": {},
|
|
190
|
+
"deprecated": false,
|
|
191
|
+
"_resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.0.1.tgz",
|
|
192
|
+
"_integrity": "sha1-aSbRsZT7xze47tUTdW3i/Np+pAg=",
|
|
193
|
+
"_shasum": "6926d1b194fbc737b8eed513756de2fcda7ea408",
|
|
194
|
+
"_shrinkwrap": null,
|
|
195
|
+
"bin": null,
|
|
196
|
+
"_id": "base64-js@1.0.1"
|
|
197
|
+
},
|
|
198
|
+
"type": "finalized-manifest"
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
</code></pre>
|
|
202
|
+
<p>上面的 <code>_shasum</code> 属性 <code>6926d1b194fbc737b8eed513756de2fcda7ea408</code> 即为 <code>tar</code> 包的 <code>hash</code>, <code>hash</code>的前几位 <code>6926</code> 即为缓存的前两层目录,我们进去这个目录果然找到的压缩后的依赖包:<br><img src="https://mmbiz.qpic.cn/mmbiz_png/aDoYvepE5x07V71lB2Paq6xf9EexnFcV3TqLnb0blCz4icicddP8SB8eWFqHqDvjWcaSbDkUr8sV6feGJrIricia6g/640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1" alt="xuehuayu.cn"></p>
|
|
203
|
+
<blockquote>
|
|
204
|
+
<p>以上的缓存策略是从 npm v5 版本开始的,在 npm v5 版本之前,每个缓存的模块在 ~/.npm 文件夹中以模块名的形式直接存储,储存结构是{cache}/{name}/{version}。</p>
|
|
205
|
+
</blockquote>
|
|
206
|
+
<p><code>npm</code> 提供了几个命令来管理缓存数据:</p>
|
|
207
|
+
<ul>
|
|
208
|
+
<li><p><code>npm cache add</code>:官方解释说这个命令主要是 <code>npm</code> 内部使用,但是也可以用来手动给一个指定的 package 添加缓存。</p>
|
|
209
|
+
</li>
|
|
210
|
+
<li><p><code>npm cache clean</code>:删除缓存目录下的所有数据,为了保证缓存数据的完整性,需要加上 <code>--force</code> 参数。</p>
|
|
211
|
+
</li>
|
|
212
|
+
<li><p><code>npm cache verify</code>:验证缓存数据的有效性和完整性,清理垃圾数据。</p>
|
|
213
|
+
</li>
|
|
214
|
+
</ul>
|
|
215
|
+
<p>基于缓存数据,npm 提供了离线安装模式,分别有以下几种:</p>
|
|
216
|
+
<ul>
|
|
217
|
+
<li><p><code>--prefer-offline</code>:优先使用缓存数据,如果没有匹配的缓存数据,则从远程仓库下载。</p>
|
|
218
|
+
</li>
|
|
219
|
+
<li><p><code>--prefer-online</code>:优先使用网络数据,如果网络数据请求失败,再去请求缓存数据,这种模式可以及时获取最新的模块。</p>
|
|
220
|
+
</li>
|
|
221
|
+
<li><p><code>--offline</code>:不请求网络,直接使用缓存数据,一旦缓存数据不存在,则安装失败。</p>
|
|
222
|
+
</li>
|
|
223
|
+
</ul>
|
|
224
|
+
<h2 id="文件完整性"><a href="#文件完整性" class="headerlink" title="文件完整性"></a>文件完整性</h2><p>上面我们多次提到了文件完整性,那么什么是文件完整性校验呢?</p>
|
|
225
|
+
<p>在下载依赖包之前,我们一般就能拿到 <code>npm</code> 对该依赖包计算的 <code>hash</code> 值,例如我们执行 <code>npm info</code> 命令,紧跟 <code>tarball</code>(下载链接) 的就是 <code>shasum</code>(<code>hash</code>) :<br><img src="https://mmbiz.qpic.cn/mmbiz_png/aDoYvepE5x07V71lB2Paq6xf9EexnFcVDqEI3R9kUNdQeAgiaomysKbNdU824OK5y3USPqGylP1v5dg9IFQ1VZQ/640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1" alt="xuehuayu.cn"><br>用户下载依赖包到本地后,需要确定在下载过程中没有出现错误,所以在下载完成之后需要在本地在计算一次文件的 <code>hash</code> 值,如果两个 <code>hash</code> 值是相同的,则确保下载的依赖是完整的,如果不同,则进行重新下载。</p>
|
|
226
|
+
<h2 id="整体流程"><a href="#整体流程" class="headerlink" title="整体流程"></a>整体流程</h2><p>好了,我们再来整体总结下上面的流程:</p>
|
|
227
|
+
<ul>
|
|
228
|
+
<li><p>检查 <code>.npmrc</code> 文件:优先级为:项目级的 <code>.npmrc</code> 文件 > 用户级的 <code>.npmrc</code> 文件> 全局级的 <code>.npmrc</code> 文件 > npm 内置的 <code>.npmrc</code> 文件</p>
|
|
229
|
+
</li>
|
|
230
|
+
<li><p>检查项目中有无 <code>lock</code> 文件。</p>
|
|
231
|
+
</li>
|
|
232
|
+
<li><p>无 <code>lock</code> 文件:</p>
|
|
233
|
+
</li>
|
|
234
|
+
<li><p>从 <code>npm</code> 远程仓库获取包信息</p>
|
|
235
|
+
</li>
|
|
236
|
+
<li><p>根据 <code>package.json</code> 构建依赖树,构建过程:</p>
|
|
237
|
+
</li>
|
|
238
|
+
<li><p>构建依赖树时,不管其是直接依赖还是子依赖的依赖,优先将其放置在 <code>node_modules</code> 根目录。</p>
|
|
239
|
+
</li>
|
|
240
|
+
<li><p>当遇到相同模块时,判断已放置在依赖树的模块版本是否符合新模块的版本范围,如果符合则跳过,不符合则在当前模块的 <code>node_modules</code> 下放置该模块。</p>
|
|
241
|
+
</li>
|
|
242
|
+
<li><p>注意这一步只是确定逻辑上的依赖树,并非真正的安装,后面会根据这个依赖结构去下载或拿到缓存中的依赖包</p>
|
|
243
|
+
</li>
|
|
244
|
+
<li><p>在缓存中依次查找依赖树中的每个包 </p>
|
|
245
|
+
</li>
|
|
246
|
+
<li><p>不存在缓存:</p>
|
|
247
|
+
</li>
|
|
248
|
+
<li><p>从 <code>npm</code> 远程仓库下载包</p>
|
|
249
|
+
</li>
|
|
250
|
+
<li><p>校验包的完整性</p>
|
|
251
|
+
</li>
|
|
252
|
+
<li><p>校验不通过:</p>
|
|
253
|
+
</li>
|
|
254
|
+
<li><p>重新下载 </p>
|
|
255
|
+
</li>
|
|
256
|
+
<li><p>校验通过:</p>
|
|
257
|
+
</li>
|
|
258
|
+
<li><p>将下载的包复制到 <code>npm</code> 缓存目录</p>
|
|
259
|
+
</li>
|
|
260
|
+
<li><p>将下载的包按照依赖结构解压到 <code>node_modules</code></p>
|
|
261
|
+
</li>
|
|
262
|
+
</ul>
|
|
263
|
+
<p>存在缓存:将缓存按照依赖结构解压到 <code>node_modules</code></p>
|
|
264
|
+
<ul>
|
|
265
|
+
<li><p>将包解压到 <code>node_modules</code></p>
|
|
266
|
+
</li>
|
|
267
|
+
<li><p>生成 <code>lock</code> 文件</p>
|
|
268
|
+
</li>
|
|
269
|
+
</ul>
|
|
270
|
+
<p>有 <code>lock</code> 文件:</p>
|
|
271
|
+
<ul>
|
|
272
|
+
<li><p>检查 <code>package.json</code> 中的依赖版本是否和 <code>package-lock.json</code> 中的依赖有冲突。</p>
|
|
273
|
+
</li>
|
|
274
|
+
<li><p>如果没有冲突,直接跳过获取包信息、构建依赖树过程,开始在缓存中查找包信息,后续过程相同</p>
|
|
275
|
+
</li>
|
|
276
|
+
</ul>
|
|
277
|
+
<p><img src="https://mmbiz.qpic.cn/mmbiz_png/aDoYvepE5x07V71lB2Paq6xf9EexnFcVD240SNZBLIwLogx4AEue7BLFeSSglH5MFk8oAtkMznOZRatVjugofg/640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1" alt="xuehuayu.cn"><br>上面的过程简要描述了 <code>npm install</code> 的大概过程,这个过程还包含了一些其他的操作,例如执行你定义的一些生命周期函数,你可以执行 <code>npm install package --timing=true --loglevel=verbose</code> 来查看某个包具体的安装流程和细节。</p>
|
|
278
|
+
<h2 id="yarn"><a href="#yarn" class="headerlink" title="yarn"></a>yarn</h2><p><img src="https://mmbiz.qpic.cn/mmbiz_png/aDoYvepE5x07V71lB2Paq6xf9EexnFcVAfh9WOPjFFP8sEfnOkYUYC8SE2Qpp7U8kHIayFVbcA7eqOsUjmMsFw/640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1" alt="xuehuayu.cn"><br><code>yarn</code> 是在 <code>2016</code> 年发布的,那时 <code>npm</code> 还处于 <code>V3</code> 时期,那时候还没有 <code>package-lock.json</code> 文件,就像上面我们提到的:不稳定性、安装速度慢等缺点经常会受到广大开发者吐槽。此时,<code>yarn</code> 诞生:<br><img src="data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVQImWNgYGBgAAAABQABh6FO1AAAAABJRU5ErkJggg==" alt="xuehuayu.cn"><br>上面是官网提到的 <code>yarn</code> 的优点,在那个时候还是非常吸引人的。当然,后来 <code>npm</code> 也意识到了自己的问题,进行了很多次优化,在后面的优化(<code>lock</code>文件、缓存、默认-s…)中,我们多多少少能看到 <code>yarn</code> 的影子,可见 <code>yarn</code> 的设计还是非常优秀的。</p>
|
|
279
|
+
<p><code>yarn</code> 也是采用的是 <code>npm v3</code> 的扁平结构来管理依赖,安装依赖后默认会生成一个 <code>yarn.lock</code> 文件,还是上面的依赖关系,我们看看 <code>yarn.lock</code> 的结构:</p>
|
|
280
|
+
<pre><code># THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
|
|
281
|
+
# yarn lockfile v1
|
|
282
|
+
|
|
283
|
+
|
|
284
|
+
base64-js@1.0.1:
|
|
285
|
+
version "1.0.1"
|
|
286
|
+
resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.0.1.tgz#6926d1b194fbc737b8eed513756de2fcda7ea408"
|
|
287
|
+
integrity sha1-aSbRsZT7xze47tUTdW3i/Np+pAg=
|
|
288
|
+
|
|
289
|
+
base64-js@^1.0.2:
|
|
290
|
+
version "1.3.1"
|
|
291
|
+
resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.1.tgz#58ece8cb75dd07e71ed08c736abc5fac4dbf8df1"
|
|
292
|
+
integrity sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==
|
|
293
|
+
|
|
294
|
+
buffer@^5.4.3:
|
|
295
|
+
version "5.4.3"
|
|
296
|
+
resolved "https://registry.yarnpkg.com/buffer/-/buffer-5.4.3.tgz#3fbc9c69eb713d323e3fc1a895eee0710c072115"
|
|
297
|
+
integrity sha512-zvj65TkFeIt3i6aj5bIvJDzjjQQGs4o/sNoezg1F1kYap9Nu2jcUdpwzRSJTHMMzG0H7bZkn4rNQpImhuxWX2A==
|
|
298
|
+
dependencies:
|
|
299
|
+
base64-js "^1.0.2"
|
|
300
|
+
ieee754 "^1.1.4"
|
|
301
|
+
|
|
302
|
+
ieee754@^1.1.4:
|
|
303
|
+
version "1.1.13"
|
|
304
|
+
resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.13.tgz#ec168558e95aa181fd87d37f55c32bbcb6708b84"
|
|
305
|
+
integrity sha512-4vf7I2LYV/HaWerSo3XmlMkp5eZ83i+/CDluXi/IGTs/O1sejBNhTtnxzmRZfvOUqj7lZjqHkeTvpgSFDlWZTg==
|
|
306
|
+
|
|
307
|
+
ignore@^5.1.4:
|
|
308
|
+
version "5.1.4"
|
|
309
|
+
resolved "https://registry.yarnpkg.com/ignore/-/ignore-5.1.4.tgz#84b7b3dbe64552b6ef0eca99f6743dbec6d97adf"
|
|
310
|
+
integrity sha512-MzbUSahkTW1u7JpKKjY7LCARd1fU5W2rLdxlM4kdkayuCwZImjkpluF9CM1aLewYJguPDqewLam18Y6AU69A8A==
|
|
311
|
+
</code></pre>
|
|
312
|
+
<p>可见其和 <code>package-lock.json</code> 文件还是比较类似的,还有一些区别就是:</p>
|
|
313
|
+
<ul>
|
|
314
|
+
<li><p><code>package-lock.json</code> 使用的是 <code>json</code> 格式,<code>yarn.lock</code> 使用的是一种自定义格式</p>
|
|
315
|
+
</li>
|
|
316
|
+
<li><p><code>yarn.lock</code> 中子依赖的版本号不是固定的,意味着单独又一个 <code>yarn.lock</code> 确定不了 <code>node_modules</code> 目录结构,还需要和 <code>package.json</code> 文件进行配合。而 <code>package-lock.json</code> 只需要一个文件即可确定。</p>
|
|
317
|
+
</li>
|
|
318
|
+
</ul>
|
|
319
|
+
<p><code>yarn</code> 的缓策略看起来和 <code>npm v5</code> 之前的很像,每个缓存的模块被存放在独立的文件夹,文件夹名称包含了模块名称、版本号等信息。使用命令 <code>yarn cache dir</code> 可以查看缓存数据的目录:<br><img src="https://mmbiz.qpic.cn/mmbiz_png/aDoYvepE5x07V71lB2Paq6xf9EexnFcVKdmzDKwu5UiatB527goedL0U8ib1UR3jxm03sEUXeSS6BbsM6L8La0Wg/640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1" alt="xuehuayu.cn"></p>
|
|
320
|
+
<blockquote>
|
|
321
|
+
<p><code>yarn</code> 默认使用 <code>prefer-online</code> 模式,即优先使用网络数据,如果网络数据请求失败,再去请求缓存数据。</p>
|
|
322
|
+
</blockquote>
|
|
323
|
+
<h2 id="参考"><a href="#参考" class="headerlink" title="参考"></a>参考</h2><p><a target="_blank" rel="noopener" href="https://juejin.im/post/5a6008c2f265da3e5033cd93">https://juejin.im/post/5a6008c2f265da3e5033cd93</a></p>
|
|
324
|
+
<p><a target="_blank" rel="noopener" href="https://www.zhihu.com/question/305539244/answer/551386426">https://www.zhihu.com/question/305539244/answer/551386426</a></p>
|
|
325
|
+
<p><a target="_blank" rel="noopener" href="https://zhuanlan.zhihu.com/p/37285173">https://zhuanlan.zhihu.com/p/37285173</a></p>
|
|
326
|
+
<p><strong>推荐阅读</strong></p>
|
|
327
|
+
<p>(点击标题可跳转阅读)</p>
|
|
328
|
+
<p><a target="_blank" rel="noopener" href="http://mp.weixin.qq.com/s?__biz=MzAxODE2MjM1MA==&mid=2651557341&idx=1&sn=9df72e127322b7717f13271263b3be0e&chksm=80255a1cb752d30a9a73312bc8ad51f0cf3b114ca3a3022b76bf2cc53d885dadc022453428e0&scene=21#wechat_redirect">NPM 如何管理依赖包版本</a></p>
|
|
329
|
+
<p><a target="_blank" rel="noopener" href="http://mp.weixin.qq.com/s?__biz=MzAxODE2MjM1MA==&mid=2651557570&idx=1&sn=ed30591ec4be28fe0fce0d2bf9ab0510&chksm=80255903b752d0159534caeba7e444d9eb3a39091e085c8418551480f6b4a4fba8649f9b9a5d&scene=21#wechat_redirect">2019 年前端事件回顾</a></p>
|
|
330
|
+
<p><a target="_blank" rel="noopener" href="http://mp.weixin.qq.com/s?__biz=MzAxODE2MjM1MA==&mid=2651556030&idx=1&sn=b690e282e1470c8c803e08ceb69b574d&chksm=80255f7fb752d669b0ee4dee52b9287ce6b7573555b3eac646d3db14003e781e2368911770f0&scene=21#wechat_redirect">在 NPM 发布自己造的轮子</a></p>
|
|
331
|
+
<p>觉得本文对你有帮助?请分享给更多人</p>
|
|
332
|
+
<p>关注「前端大全」加星标,提升前端技能</p>
|
|
333
|
+
<p><img src="https://mmbiz.qpic.cn/mmbiz_png/zPh0erYjkib3jzxuxibgz8GJ7k0UVp4kHMMDsL32ialKjpkgA9q7BFkbJ8VRYh0Liad1x6rD7w6oU7icR9DVPgsIxzQ/640?wx_fmt=png&tp=webp&wxfrom=5&wx_lazy=1&wx_co=1" alt="xuehuayu.cn"></p>
|
|
334
|
+
<p>好文章,我在看❤️</p>
|
|
335
|
+
</div><iframe src="/donate/?AliPayQR=https://store.xuehuayu.cn/store/public/alipay_qr.jpg&WeChatQR=https://store.xuehuayu.cn/store/public/wechat_qr.png&UnionPayQR=null&GitHub=null&BTCQR=null&BTCKEY=null&PayPal=https://www.paypal.com/paypalme/OrdinaryPerson" style="overflow-x:hidden; overflow-y:hidden; border:0xp none #fff; min-height:240px; width:100%;" frameborder="0" scrolling="no"></iframe><div><ul class="post-copyright"><li class="post-copyright-author"><strong>本文作者:</strong>雪花雨</li><li class="post-copyright-link"><strong>本文链接:</strong><a href="/article/35697.html">https://xuehuayu.cn/article/35697.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/44426.html">7 个令人兴奋的 JavaScript 新特性</a><a class="next" href="/article/56139.html">第 4 种 Web 语言来了:WebAssembly</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
|
|
336
|
+
const serverURL = origin.includes('cainiaoblog') ? 'https://cmts.cainiaoblog.cn' : 'https://cmts.xuehuayu.cn'
|
|
337
|
+
const locale = {
|
|
338
|
+
placeholder: '请正确填写昵称和邮箱,方便接收回复通知~',
|
|
339
|
+
sofa: '沙发空缺中,还不快抢~',
|
|
340
|
+
};
|
|
341
|
+
Waline.init({
|
|
342
|
+
el: '#vcomment',
|
|
343
|
+
serverURL: serverURL,
|
|
344
|
+
pageSize: '20',
|
|
345
|
+
visitor: true, // 阅读量统计
|
|
346
|
+
requiredMeta: ['nick', 'mail'],
|
|
347
|
+
emoji: [
|
|
348
|
+
'https://cdn.jsdelivr.net/gh/walinejs/emojis@1.0.0/weibo',
|
|
349
|
+
'https://cdn.jsdelivr.net/gh/walinejs/emojis@1.0.0/qq',
|
|
350
|
+
'https://cdn.jsdelivr.net/gh/walinejs/emojis@1.0.0/tw-emoji',
|
|
351
|
+
],
|
|
352
|
+
locale,
|
|
353
|
+
pageview: true
|
|
354
|
+
})
|
|
355
|
+
</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.staticaly.com/gh/npljy/npljy.github.io/main/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() {
|
|
356
|
+
var val = $(this).val()
|
|
357
|
+
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>'
|
|
358
|
+
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>'
|
|
359
|
+
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>'
|
|
360
|
+
|
|
361
|
+
if (val === 'self') {
|
|
362
|
+
$('#search').html(self)
|
|
363
|
+
var search_path = 'search.xml';
|
|
364
|
+
if (search_path.length == 0) {
|
|
365
|
+
search_path = 'search.xml';
|
|
366
|
+
}
|
|
367
|
+
var path = 'https://cdn.staticaly.com/gh/npljy/npljy.github.io/main/' + search_path;
|
|
368
|
+
searchFunc(path, 'local-search-input', 'local-search-result');
|
|
369
|
+
} else if (val === 'baidu') {
|
|
370
|
+
$('#search').html(baidu)
|
|
371
|
+
} else if (val === 'google') {
|
|
372
|
+
$('#search').html(google)
|
|
373
|
+
}
|
|
374
|
+
})</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">191</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/%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">2</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/c5576490.html">面试准备</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(){
|
|
375
|
+
var cnb =window.location.origin.indexOf('cainiaoblog') !==-1
|
|
376
|
+
if (cnb) {
|
|
377
|
+
var gxba =document.getElementById('gxba')
|
|
378
|
+
var gaba =document.getElementById('gaba')
|
|
379
|
+
var gabaLink =document.getElementById('gaba-link')
|
|
380
|
+
gxba.innerText ='京ICP备20007647号-1'
|
|
381
|
+
gaba.innerText ='京公网安备 11010802031254号'
|
|
382
|
+
gabaLink.setAttribute('href','http://www.beian.gov.cn/portal/registerSystemInfo?recordcode=11010802031254')
|
|
383
|
+
}
|
|
384
|
+
})()</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.staticaly.com/gh/npljy/npljy.github.io/main/js/totop.min.js" async></script><script type="text/javascript" src="//cdn.staticaly.com/gh/npljy/npljy.github.io/main/js/dark.min.js" async></script><script type="text/javascript" src="//cdn.staticaly.com/gh/npljy/npljy.github.io/main/js/codeblock-resizer.min.js"></script><script type="text/javascript" src="//cdn.staticaly.com/gh/npljy/npljy.github.io/main/js/smartresize.min.js"></script></div></body></html>
|
|
@@ -0,0 +1,73 @@
|
|
|
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>如何使div自适应内容的宽度和高度 | 前端壹菜鸟</title><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/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.staticaly.com/gh/npljy/npljy.github.io/main/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">如何使div自适应内容的宽度和高度</h1><div class="post-meta"><span class="date">2020-02-06</span><span> | </span><span class="tag original"><a href="/tags/%E5%8E%9F%E5%88%9B/">原创 </a></span><span> | </span><span class="category"><a href="/categories/%E5%89%8D%E7%AB%AF/">前端 </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"> 35</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"> 1</span><span class="post-meta-item-text"> 分钟</span></span></span></div><a class="disqus-comment-count" href="/article/35863.html#vcomment"><span class="waline-comment-count" data-path="/article/35863.html"></span><span> 条评论</span></a><div class="post-content"><p>有时候div无法自适应 内容的宽度高度,如何设置div呢?<br>设置如下 样式 即可</p>
|
|
20
|
+
<span id="more"></span>
|
|
21
|
+
|
|
22
|
+
<hr>
|
|
23
|
+
<figure class="highlight css"><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="attribute">width</span>: fit-content</span><br><span class="line">height: fit-content</span><br></pre></td></tr></table></figure>
|
|
24
|
+
</div><iframe src="/donate/?AliPayQR=https://store.xuehuayu.cn/store/public/alipay_qr.jpg&WeChatQR=https://store.xuehuayu.cn/store/public/wechat_qr.png&UnionPayQR=null&GitHub=null&BTCQR=null&BTCKEY=null&PayPal=https://www.paypal.com/paypalme/OrdinaryPerson" style="overflow-x:hidden; overflow-y:hidden; border:0xp none #fff; min-height:240px; width:100%;" frameborder="0" scrolling="no"></iframe><div><ul class="post-copyright"><li class="post-copyright-author"><strong>本文作者:</strong>雪花雨</li><li class="post-copyright-link"><strong>本文链接:</strong><a href="/article/35863.html">https://xuehuayu.cn/article/35863.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/%E5%8E%9F%E5%88%9B/">原创</a></div><div class="post-nav"><a class="pre" href="/article/24581.html">移动端 H5 相关问题汇总</a><a class="next" href="/article/53524.html">两层div,如何使内层div的内容不换行,超出滚动</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
|
|
25
|
+
const serverURL = origin.includes('cainiaoblog') ? 'https://cmts.cainiaoblog.cn' : 'https://cmts.xuehuayu.cn'
|
|
26
|
+
const locale = {
|
|
27
|
+
placeholder: '请正确填写昵称和邮箱,方便接收回复通知~',
|
|
28
|
+
sofa: '沙发空缺中,还不快抢~',
|
|
29
|
+
};
|
|
30
|
+
Waline.init({
|
|
31
|
+
el: '#vcomment',
|
|
32
|
+
serverURL: serverURL,
|
|
33
|
+
pageSize: '20',
|
|
34
|
+
visitor: true, // 阅读量统计
|
|
35
|
+
requiredMeta: ['nick', 'mail'],
|
|
36
|
+
emoji: [
|
|
37
|
+
'https://cdn.jsdelivr.net/gh/walinejs/emojis@1.0.0/weibo',
|
|
38
|
+
'https://cdn.jsdelivr.net/gh/walinejs/emojis@1.0.0/qq',
|
|
39
|
+
'https://cdn.jsdelivr.net/gh/walinejs/emojis@1.0.0/tw-emoji',
|
|
40
|
+
],
|
|
41
|
+
locale,
|
|
42
|
+
pageview: true
|
|
43
|
+
})
|
|
44
|
+
</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.staticaly.com/gh/npljy/npljy.github.io/main/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() {
|
|
45
|
+
var val = $(this).val()
|
|
46
|
+
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>'
|
|
47
|
+
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>'
|
|
48
|
+
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>'
|
|
49
|
+
|
|
50
|
+
if (val === 'self') {
|
|
51
|
+
$('#search').html(self)
|
|
52
|
+
var search_path = 'search.xml';
|
|
53
|
+
if (search_path.length == 0) {
|
|
54
|
+
search_path = 'search.xml';
|
|
55
|
+
}
|
|
56
|
+
var path = 'https://cdn.staticaly.com/gh/npljy/npljy.github.io/main/' + search_path;
|
|
57
|
+
searchFunc(path, 'local-search-input', 'local-search-result');
|
|
58
|
+
} else if (val === 'baidu') {
|
|
59
|
+
$('#search').html(baidu)
|
|
60
|
+
} else if (val === 'google') {
|
|
61
|
+
$('#search').html(google)
|
|
62
|
+
}
|
|
63
|
+
})</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">191</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/%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">2</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/c5576490.html">面试准备</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(){
|
|
64
|
+
var cnb =window.location.origin.indexOf('cainiaoblog') !==-1
|
|
65
|
+
if (cnb) {
|
|
66
|
+
var gxba =document.getElementById('gxba')
|
|
67
|
+
var gaba =document.getElementById('gaba')
|
|
68
|
+
var gabaLink =document.getElementById('gaba-link')
|
|
69
|
+
gxba.innerText ='京ICP备20007647号-1'
|
|
70
|
+
gaba.innerText ='京公网安备 11010802031254号'
|
|
71
|
+
gabaLink.setAttribute('href','http://www.beian.gov.cn/portal/registerSystemInfo?recordcode=11010802031254')
|
|
72
|
+
}
|
|
73
|
+
})()</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.staticaly.com/gh/npljy/npljy.github.io/main/js/totop.min.js" async></script><script type="text/javascript" src="//cdn.staticaly.com/gh/npljy/npljy.github.io/main/js/dark.min.js" async></script><script type="text/javascript" src="//cdn.staticaly.com/gh/npljy/npljy.github.io/main/js/codeblock-resizer.min.js"></script><script type="text/javascript" src="//cdn.staticaly.com/gh/npljy/npljy.github.io/main/js/smartresize.min.js"></script></div></body></html>
|