-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathatom.xml
130 lines (78 loc) · 32.3 KB
/
atom.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title>记得的博客</title>
<link href="/atom.xml" rel="self"/>
<link href="http://yoursite.com/"/>
<updated>2018-12-09T10:12:45.092Z</updated>
<id>http://yoursite.com/</id>
<author>
<name>jide</name>
</author>
<generator uri="http://hexo.io/">Hexo</generator>
<entry>
<title>说说jsonp</title>
<link href="http://yoursite.com/2018/12/09/what-is-jsonp/"/>
<id>http://yoursite.com/2018/12/09/what-is-jsonp/</id>
<published>2018-12-09T08:41:29.000Z</published>
<updated>2018-12-09T10:12:45.092Z</updated>
<content type="html"><![CDATA[<p>说起jsonp,直到一周前,我对它的认识还停留在请求地址末尾拼接上<code>?callback=callback</code>就能解决跨域问题,以及知道怎么通过原生js去发送一个jsonp请求。上周我研究<a href="https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Access_control_CORS" target="_blank" rel="noopener">CORS</a>时顺带去了解了下jsonp的原理,对它的认识才更进一步。</p><a id="more"></a> <h2 id="jsonp原理"><a href="#jsonp原理" class="headerlink" title="jsonp原理"></a>jsonp原理</h2><p>我们知道,限于<a href="https://developer.mozilla.org/zh-CN/docs/Web/Security/Same-origin_policy" target="_blank" rel="noopener">同源政策</a>,在脚本内发送的跨域请求会被浏览器限制。但是,通过script标签去请求不同源上的脚本文件,却不会被浏览器限制。</p><p>再详细点说明就是,对于一个不同源的接口<code>//domain.com/api/list</code>,这样请求会被限制:</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br></pre></td><td class="code"><pre><span class="line">$.ajax({</span><br><span class="line">type: <span class="string">'get'</span>,</span><br><span class="line">url: <span class="string">'//domain.com/api/list'</span>,</span><br><span class="line">data: {</span><br><span class="line">currPage: <span class="number">1</span>,</span><br><span class="line">pageSize: <span class="number">10</span></span><br><span class="line">}</span><br><span class="line">})</span><br></pre></td></tr></table></figure><p>而这么请求却不会被限制:</p><p><code><script src="//domain.com/api/list?currPage=1&pageSize=10&callback=callback"></script></code></p><p>我们可以把一次ajax请求流程拆分成两个步骤看待,一步是【发送请求】,一步是【接受响应数据并执行回调】。对于一个跨域请求,【发送请求】的步骤我们已经实现了,再实现【接受响应数据并执行回调】,我们就完成了一次跨域请求了!让我们来看看第二步应该怎么实现。</p><p>当服务器查询好数据打算返回给浏览器时,需要做一下“特殊”的处理:</p><p>1、从请求参数中读取回调函数名称,这个字段通常是前后端约定好了的。</p><p>2、将数据填充到回调函数里</p><p><code>callback({"name": "小明", "id": 1823})</code></p><p>3、将响应头的<code>Content-Type</code>设置成<code>application/javascript</code>,只有这样数据才会被我们预期的那样使用,别忘了,我们是通过script标签去请求的接口。</p><p>服务器做完这些工作,请求就能按照我们预期的那样被使用啦。接下来是<strong>show me the code</strong>环节。</p><p>浏览器端代码:</p><figure class="highlight html"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br></pre></td><td class="code"><pre><span class="line"><span class="tag"><<span class="name">script</span>></span><span class="undefined"></span></span><br><span class="line"><span class="javascript"><span class="function"><span class="keyword">function</span> <span class="title">callback</span> (<span class="params">data</span>) </span>{</span></span><br><span class="line"><span class="javascript">alert(<span class="built_in">JSON</span>.stringify(data))</span></span><br><span class="line"><span class="undefined">}</span></span><br><span class="line"><span class="undefined"></span><span class="tag"></<span class="name">script</span>></span></span><br><span class="line"><span class="tag"><<span class="name">script</span> <span class="attr">src</span>=<span class="string">"http://localhost:3333/api/jsonp?callback=callback"</span>></span><span class="undefined"></span><span class="tag"></<span class="name">script</span>></span></span><br></pre></td></tr></table></figure><p>服务器端代码(Koa):</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line">exports.jsonp = <span class="keyword">async</span> (ctx, next) => {</span><br><span class="line"> <span class="comment">// 读取回调函数名称</span></span><br><span class="line"> <span class="keyword">let</span> callbackName = ctx.request.url.match(<span class="regexp">/callback=(\w+)/</span>)[<span class="number">1</span>]</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 查询数据</span></span><br><span class="line"> <span class="keyword">let</span> data = <span class="built_in">JSON</span>.stringify({<span class="attr">name</span>: <span class="string">'小明'</span>, <span class="attr">id</span>: <span class="number">1823</span>, <span class="attr">age</span>: <span class="number">18</span>})</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 设置响应头</span></span><br><span class="line"> ctx.set(<span class="string">'Content-Type'</span>, <span class="string">'application/javascript'</span>)</span><br><span class="line"></span><br><span class="line"> <span class="comment">// 返回数据</span></span><br><span class="line"> ctx.response.body = <span class="string">`<span class="subst">${callbackName}</span>(<span class="subst">${data}</span>)`</span></span><br><span class="line">}</span><br></pre></td></tr></table></figure><p>运行结果</p><img src="/2018/12/09/what-is-jsonp/1.png" title="运行结果"><p>总结一下:jsonp的原理就是,浏览器通过script标签去请求一个不同源上的接口,服务器将数据接口填充进回调函数里返回给浏览器。</p><h2 id="优缺点"><a href="#优缺点" class="headerlink" title="优缺点"></a>优缺点</h2><p>jsonp的优点在于它的兼容性,毕竟是早些时代的产物,兼容性没得说。缺点是只支持<code>GET</code>方法,有点膈应。如果不是产品用户群体特殊,还是尽早使用<a href="https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Access_control_CORS" target="_blank" rel="noopener">CORS</a>。</p><h2 id="佩服佩服"><a href="#佩服佩服" class="headerlink" title="佩服佩服"></a>佩服佩服</h2><p>了解完jsonp的原理后,不得不感慨人民群众的智慧真是伟大,这种法子都能想的出来,佩服佩服。</p><img src="/2018/12/09/what-is-jsonp/2.gif" title="运行结果"><p>以上。</p>]]></content>
<summary type="html">
<p>说起jsonp,直到一周前,我对它的认识还停留在请求地址末尾拼接上<code>?callback=callback</code>就能解决跨域问题,以及知道怎么通过原生js去发送一个jsonp请求。上周我研究<a href="https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Access_control_CORS" target="_blank" rel="noopener">CORS</a>时顺带去了解了下jsonp的原理,对它的认识才更进一步。</p>
</summary>
<category term="js" scheme="http://yoursite.com/categories/js/"/>
<category term="jsonp" scheme="http://yoursite.com/tags/jsonp/"/>
</entry>
<entry>
<title>跨域资源共享</title>
<link href="http://yoursite.com/2018/12/02/cros/"/>
<id>http://yoursite.com/2018/12/02/cros/</id>
<published>2018-12-02T08:16:23.000Z</published>
<updated>2018-12-09T08:37:32.702Z</updated>
<content type="html"><![CDATA[<p>跨域请求是前端开发时经常遇到的一个场景,以前总是遇到了跨域报错就去谷歌,没有系统的去了解,趁着周末有空,专门去研究了下。</p><a id="more"></a> <h2 id="什么是跨域资源共享(Cross-Origin-Resource-Sharing)"><a href="#什么是跨域资源共享(Cross-Origin-Resource-Sharing)" class="headerlink" title="什么是跨域资源共享(Cross-Origin Resource Sharing)"></a>什么是跨域资源共享(Cross-Origin Resource Sharing)</h2><p>前端的跨域请求的实现都是建立在跨域资源共享(CORS)这套机制上的,那么什么是跨域资源共享呢?</p><p>跨域资源共享是一套机制,它通过额外的HTTP头来告诉浏览器,让一个源(origin)上的web应用有权限去访问不同源(diffent origin)上的资源;当一个web应用去请求与它不同源(origin)上的资源时,它会发出一个跨域请求(cross-origin Http Request)。</p><p>ps: 同源的定义:如果两个页面的协议,端口,域名相同,则两个页面拥有相同的源;若协议、端口、域名有一个不相同,则不同源。</p><h2 id="功能概述"><a href="#功能概述" class="headerlink" title="功能概述"></a>功能概述</h2><p>跨域资源共享新增了一组HTTP头部字段,服务器使用这些头部字段来描述哪些源被允许通过浏览器来读取资源;另外,对于那些可能对服务器数据产生副作用的HTTP请求方法(特别是GET以外的请求方法,或者是搭配某些MIME类型的POST请求),浏览器必须先发送一个方法为OPTIONS的预检请求(preflight request),来读取服务器支持的请求方法。在得到服务器“批准”后,才会发送实际的请求。服务器也可以通知客户端,是否需要携带身份凭证(包括Cookie和HTTP认证相关数据)。</p><h3 id="若干访问场景"><a href="#若干访问场景" class="headerlink" title="若干访问场景"></a>若干访问场景</h3><p>概念上的东西总是让人晕乎乎的,下面我们通过三个场景来具体了解下吧。</p><h4 id="简单请求"><a href="#简单请求" class="headerlink" title="简单请求"></a>简单请求</h4><p>简单请求是指不会出发CORS预检的请求,若满足下述所有条件,则该请求就是个简单请求。</p><ul><li>使用下列方法之一:<ul><li><code>GET</code></li><li><code>HEAD</code></li><li><code>POST</code></li></ul></li><li>没有人为设置下列合集之外的其他头部字段<ul><li><code>Accept</code></li><li><code>Accept-Language</code></li><li><code>Content-Language</code></li><li><code>Content-Type</code>(需要注意额外的限制)</li><li><code>DPR</code></li><li><code>Downlink</code></li><li><code>Save-Data</code></li><li><code>Viewport-Width</code></li><li><code>Width</code></li></ul></li><li><code>Content-Type</code>的值仅限下列三者之一:<ul><li><code>text/plain</code></li><li><code>multipart/form-data</code></li><li><code>application/x-www-form-urlencoded</code></li></ul></li></ul><p>一般<code>GET</code>请求,可以看作是简单请求,它的请求头与响应头如下:</p><img src="/2018/12/02/cros/01.png" title="简单请求-1"><p>请求头中的<code>Origin</code>字段指明请求是从哪个源发起的,响应头中的<code>Access-Control-Allow-Origin</code>字段指明哪些源有权限访问,*代表该资源可以被所任意源访问。</p><p>若只想某一源可以访问,服务器的头部字段可以这么设定:</p><p><code>Access-Control-Allow-Origin: http://localhost:8080</code></p><p>若服务器没有返回<code>Access-Control-Allow-Origin</code>或返回的值与浏览器所在源不匹配。则浏览器会阻止脚本继续运行,如下图所示。</p><img src="/2018/12/02/cros/02.png" title="简单请求-2"><h4 id="预检请求"><a href="#预检请求" class="headerlink" title="预检请求"></a>预检请求</h4><p>与简单请求对立的是预检请求,他会在实际的请求发送前先去发送一个方法为<code>OPTIONS</code>的预检请求,来询问服务器是否允许该实际请求。”预检请求“的使用,可以避免跨域请求对服务器的用户数据产生未预期的影响。</p><p>当请求满足下列任一条件时,浏览器会发送预检请求:</p><ul><li>使用了下列任一HTTP方法:<ul><li><code>PUT</code></li><li><code>DELETE</code></li><li><code>CONNECT</code></li><li><code>OPTIONS</code></li><li><code>TRACE</code></li><li><code>PATCH</code></li></ul></li><li>人为设置了下列头部字段之外的头部字段:<ul><li><code>Accept</code></li><li><code>Accept-Language</code></li><li><code>Content-Language</code></li><li><code>Content-Type</code>(注意下面的附加要求)</li><li><code>DPR</code></li><li><code>Downlink</code></li><li><code>Save-Data</code></li><li><code>Viewport-Width</code></li><li><code>Width</code></li></ul></li><li><code>Content-Type</code> 的值不属于下列之一:<ul><li><code>application/x-www-form-urlencoded</code></li><li><code>multipart/form-data</code></li><li><code>text/plain</code></li></ul></li></ul><h5 id="让我们来发送一个PUT请求看看:"><a href="#让我们来发送一个PUT请求看看:" class="headerlink" title="让我们来发送一个PUT请求看看:"></a>让我们来发送一个PUT请求看看:</h5><img src="/2018/12/02/cros/03.png" title="预检请求-1"><p>可以看到,在PUT请求发送前,浏览器发送了一个OPTIONS请求;(OPTIONS请求的)请求头中的<code>Access-Control-Request-Method: PUT</code>指明真实的请求是一个<code>PUT</code>请求。响应头中的<code>Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS</code>指明服务器允许使用这些请求方法。预检通过,浏览器发送真实请求,皆大欢喜。</p><p>若服务器没有返回<code>Access-Control-Allow-Methods</code>或返回的值与真实的请求方法不匹配。浏览器则不会发送真实的请求,如下图所示。</p><img src="/2018/12/02/cros/04.png" title="预检请求-2"><h5 id="让我们来发送一个人为添加了其他头部字段的POST请求看看:"><a href="#让我们来发送一个人为添加了其他头部字段的POST请求看看:" class="headerlink" title="让我们来发送一个人为添加了其他头部字段的POST请求看看:"></a>让我们来发送一个人为添加了其他头部字段的POST请求看看:</h5><img src="/2018/12/02/cros/06.png" title="预检请求-3"><p>请求头中的<code>Access-Control-Request-Headers: x-custom-field</code>指明了额外添加的头部字段,响应头中的<code>Access-Control-Allow-Headers: x-custom-field</code>指明了允许添加的头部字段。</p><p>若服务器没有返回<code>Access-Control-Request-Headers</code>或返回的值与真实的请求方法中添加的其他头部字段不匹配。浏览器则不会发送真实的请求,如下图所示。</p><img src="/2018/12/02/cros/07.png" title="预检请求-4"><h4 id="携带身份凭证的请求"><a href="#携带身份凭证的请求" class="headerlink" title="携带身份凭证的请求"></a>携带身份凭证的请求</h4><img src="/2018/12/02/cros/09.png" title="XMLHttpRequest设置"><p>一般而言,对于跨域请求,浏览器<strong>不会</strong>携带身份凭证信息,例如Cookie,如果要携带身份凭证信息,则需要将<code>XMLHttpRequest</code>的<code>withCredentials</code>属性设置为true</p><img src="/2018/12/02/cros/08.png" title="携带身份凭证的请求"><p>相应的,服务器也得将<code>Access-Control-Allow-Credentials</code>为<code>true</code>,不然浏览器将不会把响应的内容返回给请求者;同时<code>Access-Control-Allow-Origin</code>不能设置成通配符<code>*</code>,必须指定具体的<code>origin</code>才行。</p><h4 id="其他"><a href="#其他" class="headerlink" title="其他"></a>其他</h4><p>除了上述介绍的一些头部字段以外,还有个常用的头部字段,<code>Access-Control-Max-Age</code>,它指定了preflight请求的结果能够被缓存多久。语法如下:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">Access-Control-Max-Age: <delta-seconds></span><br></pre></td></tr></table></figure><h4 id="经验总结"><a href="#经验总结" class="headerlink" title="经验总结"></a>经验总结</h4><ul><li><code>GET</code>请求的请求头中,不会有<code>Content-Type</code>字段,<code>Content-Type</code>字段只会在<code>POST</code>、<code>PUT</code>的请求头中出现,它的语音是告诉服务器实际发送的数据类型。</li></ul><p>以上。</p><p>本文参考:</p><ul><li><a href="https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Access_control_CORS" target="_blank" rel="noopener">HTTP访问控制(CORS)</a></li></ul>]]></content>
<summary type="html">
<p>跨域请求是前端开发时经常遇到的一个场景,以前总是遇到了跨域报错就去谷歌,没有系统的去了解,趁着周末有空,专门去研究了下。</p>
</summary>
<category term="http" scheme="http://yoursite.com/categories/http/"/>
<category term="cros" scheme="http://yoursite.com/tags/cros/"/>
</entry>
<entry>
<title>编写文字样式时,行高带来的影响</title>
<link href="http://yoursite.com/2018/07/21/web-lineheight-and-ps-lineheight/"/>
<id>http://yoursite.com/2018/07/21/web-lineheight-and-ps-lineheight/</id>
<published>2018-07-21T06:10:12.000Z</published>
<updated>2018-07-21T08:56:18.247Z</updated>
<content type="html"><![CDATA[<p>当我们在编写文字样式时,明明是按照设计给的标注写的样式,但文字的间距,却可能会大于设计搞。这一现象,是受文字的行高属性影响导致的。</p><a id="more"></a> <h2 id="现象"><a href="#现象" class="headerlink" title="现象"></a>现象</h2><p>列如,下图1是我随便找的一个标注,下图2是我根据标注写的页面。经手工测量,两行文字的间距为36px,明显超出标注里的11px。</p><img src="/2018/07/21/web-lineheight-and-ps-lineheight/1.jpg" title="标注"><p style="text-align: center"><i>图1</i></p><img src="/2018/07/21/web-lineheight-and-ps-lineheight/2.jpg" title="页面截图"><p style="text-align: center"><i>图2</i></p><h2 id="原因"><a href="#原因" class="headerlink" title="原因"></a>原因</h2><p>造成这一现象的原因是:浏览器不像ps,不是以文字的实际大小计算外边距,而是以文字的盒模型的大小计算外边距。打开浏览器调试工具我们可以发现,文字外边距是从文字盒模型的底部开始计算的。所以当我们按照标注给的值设置外边距时,文字实际间距会大于设计稿的间距。 </p><p>文字的盒模型会被文字行高撑开,行高越大,盒模型越大,偏差也就越大。</p><p>从图3可以看出,两行文字间的实际距离等于【第一行文字底部到他的盒模型底部的距离】加上【外边距】加上【第二行文字头部到盒模型头部的距离】。</p><img src="/2018/07/21/web-lineheight-and-ps-lineheight/3.jpg" title="调试工具截图"><p style="text-align: center"><i>图3</i></p><h2 id="怎么解决"><a href="#怎么解决" class="headerlink" title="怎么解决"></a>怎么解决</h2><p>怎么解决?方法有三:</p><h3 id="方法一:将行高设置为1"><a href="#方法一:将行高设置为1" class="headerlink" title="方法一:将行高设置为1"></a>方法一:将行高设置为1</h3><p>将行高设置成1后,文字大小与盒模型大小相等,【第一行文字底部到他的盒模型底部的距离】、【第二行文字头部到盒模型头部的距离】这两个值为0,两行文字间的间距就等于设置的外边距(参考第二段的公式理解)。</p><p><em>此方法仅适用于单行文字</em></p><h3 id="方法二:手动计算外边距"><a href="#方法二:手动计算外边距" class="headerlink" title="方法二:手动计算外边距"></a>方法二:手动计算外边距</h3><p>我们知道,文字间的间距由3部分组成,因此我们可以手动计算出外边距值。 例如(假定设计稿中)第一行文字的大小为16px,第二行文字的大小为12px,他们的间距是20px。假定行高为1.5。那么实际设定的外边距值就是:20 - (16 * 1.5 - 16) / 2 - (12 * 1.5 - 12) / 2 = 13(px)。</p><p><em>此方法适用于任何情况,但计算过程繁琐</em></p><p>ps:文字的盒模型大小 = 文字大小 * 文字行高<br>ps:文字底部到他的盒模型底部的距离 = (文字大小 * 文字行高 - 文字大小) / 2</p><h3 id="方法三:UI标注时连带着行高一起标注"><a href="#方法三:UI标注时连带着行高一起标注" class="headerlink" title="方法三:UI标注时连带着行高一起标注"></a>方法三:UI标注时连带着行高一起标注</h3><p>对设计专业度要求较高,详见<a href="https://www.jianshu.com/p/55f1d2c9a82e" target="_blank" rel="noopener">这篇文章</a></p><h2 id="结语"><a href="#结语" class="headerlink" title="结语"></a>结语</h2><p>本文分析了实际开发中,文字的间距可能与设计稿不一致的现象及原因,并提供了三个解决方案,希望对你有所帮助。</p>]]></content>
<summary type="html">
<p>当我们在编写文字样式时,明明是按照设计给的标注写的样式,但文字的间距,却可能会大于设计搞。这一现象,是受文字的行高属性影响导致的。</p>
</summary>
<category term="css" scheme="http://yoursite.com/categories/css/"/>
<category term="解决问题" scheme="http://yoursite.com/tags/%E8%A7%A3%E5%86%B3%E9%97%AE%E9%A2%98/"/>
</entry>
<entry>
<title>记一次webpack构建优化</title>
<link href="http://yoursite.com/2018/04/22/buileOptimize/"/>
<id>http://yoursite.com/2018/04/22/buileOptimize/</id>
<published>2018-04-22T02:47:50.000Z</published>
<updated>2018-06-11T09:47:54.194Z</updated>
<content type="html"><![CDATA[<p>一次偶然的机会,我知道了webpack有很多可视化工具,可以帮助你分析应用的依赖图表,找出不好的地方,让你去优化他们。我通过使用webpack的官方分析工具,优化了项目构建逻辑,使构建后的平均文件的size减少了50kb,部分文件的size减少了100kb。</p><a id="more"></a> <h2 id="webpack-Analyze"><a href="#webpack-Analyze" class="headerlink" title="webpack Analyze"></a>webpack Analyze</h2><p>这是webpack的官方分析工具<a href="https://webpack.github.io/analyse/" target="_blank" rel="noopener">Analyze</a>,使用它之前,你需要先生成一份<strong>包含关于模块的统计数据的json文件</strong>,你可以参照<a href="https://doc.webpack-china.org/api/stats/#src/components/Sidebar/Sidebar.jsx" target="_blank" rel="noopener">这篇文档</a>,如果你使用的是Node APi,那么你可能需要参考<a href="https://doc.webpack-china.org/api/node/#stats-%E5%AF%B9%E8%B1%A1-stats-object-" target="_blank" rel="noopener">这篇文档</a>。</p><p>将生成好的json文件上传至Analyze,你会看到如下图所示界面。这是你应用的构建概览。你可以在Modules,Chunks,Assets目录里看见更详细的报告,也可以在Hints目录里查看优化提示。</p><img src="/2018/04/22/buileOptimize/01.jpg" title="Analyze Home"><h2 id="大量module被多个chunks依赖"><a href="#大量module被多个chunks依赖" class="headerlink" title="大量module被多个chunks依赖"></a>大量module被多个chunks依赖</h2><p>让我们回到主题,点击Hints我发现,在我的应用中有很多个module被多个chunk依赖,这使得我chunk的尺寸比预期要大,会使页面访问速度变慢。我感到很奇怪?我的项目是用Vue-cli生成的,项目里配置了webpack的CommonsChunkPlugin插件,按理说这些被多个chunk依赖的module是会被打包进一个公共文件才对的。为什么这些module没有被打包进公共文件?问题出在哪?</p><img src="/2018/04/22/buileOptimize/02.jpg" title="大量module被多个chunks依赖"><h2 id="问题出在哪呢?"><a href="#问题出在哪呢?" class="headerlink" title="问题出在哪呢?"></a>问题出在哪呢?</h2><p>首先我猜测,可能是CommonsChunkPlugin插件配置不对,我依次尝试了<a href="https://doc.webpack-china.org/plugins/commons-chunk-plugin/" target="_blank" rel="noopener">官方文档</a>上的配置案例,问题任然存在。看来不是配置的问题。那问题出在哪呢?我整个人有点斯巴达,看样子又得去看源码了。</p><p>在看源码之前,我灵光一闪,有了新的发现。</p><p>我在配置代码里加了一行代码,打印资源路径。发现——我通过代码分割功能引入的子chunk的路径并没有出被打印在控制台中,也就是说,<strong>CommonsChunkPlugin不会去提取被分割的子chunk中的公共文件</strong>。</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br></pre></td><td class="code"><pre><span class="line"><span class="keyword">new</span> webpack.optimize.CommonsChunkPlugin({</span><br><span class="line"> name: <span class="string">'vendor'</span>,</span><br><span class="line"> minChunks: <span class="function"><span class="keyword">function</span> (<span class="params">module, count</span>) </span>{</span><br><span class="line"> <span class="built_in">console</span>.log(<span class="built_in">module</span>.resource) <span class="comment">// 打印资源路径</span></span><br><span class="line"> <span class="keyword">return</span> (</span><br><span class="line"> <span class="built_in">module</span>.resource &&</span><br><span class="line"> /\.js$/.test(<span class="built_in">module</span>.resource) &&</span><br><span class="line"> <span class="built_in">module</span>.resource.indexOf(</span><br><span class="line"> path.join(__dirname, <span class="string">'../node_modules'</span>)</span><br><span class="line"> ) === <span class="number">0</span></span><br><span class="line"> )</span><br><span class="line"> }</span><br><span class="line">}),</span><br></pre></td></tr></table></figure><p>得出的这个令我很兴奋,我马上停用掉代码分割功能,来验证我的想法。</p><figure class="highlight js"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line"><span class="comment">// 通过代码分割功能异步引入的页面组件</span></span><br><span class="line"><span class="keyword">const</span> pageOne = <span class="function"><span class="params">()</span> =></span> <span class="keyword">import</span>(<span class="string">'@/page/pageOne'</span> <span class="comment">/* webpackChunkName: "pageOne" */</span>)</span><br><span class="line"><span class="keyword">const</span> pageTwo = <span class="function"><span class="params">()</span> =></span> <span class="keyword">import</span>(<span class="string">'@/page/pageTwo'</span> <span class="comment">/* webpackChunkName: "pageTwo" */</span>)</span><br><span class="line"></span><br><span class="line"><span class="comment">// 停用代码分割功能</span></span><br><span class="line"><span class="keyword">import</span> pageOne <span class="keyword">from</span> <span class="string">'@/page/pageOne'</span></span><br><span class="line"><span class="keyword">import</span> pageTwo <span class="keyword">from</span> <span class="string">'@/page/pageTwo'</span></span><br></pre></td></tr></table></figure><p>验证的结果同我的猜想一样。</p><h2 id="优化结果对比"><a href="#优化结果对比" class="headerlink" title="优化结果对比"></a>优化结果对比</h2><p>找到原因问题就好解决了,既然<strong>CommonsChunkPlugin不会去提取被分割的子chunk中的公共文件</strong>,那我就手动将他们提取到一个公共文件里面去。</p><p>放一张优化前后的构建对比图。</p><img src="/2018/04/22/buileOptimize/03.jpg" title="优化效果对比"><p>从图中可以看到,文件尺寸平均减少了50kb,画红线的三个文件更是减少了100kb。</p>]]></content>
<summary type="html">
<p>一次偶然的机会,我知道了webpack有很多可视化工具,可以帮助你分析应用的依赖图表,找出不好的地方,让你去优化他们。我通过使用webpack的官方分析工具,优化了项目构建逻辑,使构建后的平均文件的size减少了50kb,部分文件的size减少了100kb。</p>
</summary>
<category term="js" scheme="http://yoursite.com/categories/js/"/>
<category term="webpack" scheme="http://yoursite.com/tags/webpack/"/>
<category term="优化" scheme="http://yoursite.com/tags/%E4%BC%98%E5%8C%96/"/>
</entry>
<entry>
<title>Hello Hexo</title>
<link href="http://yoursite.com/2018/04/15/helloWorld/"/>
<id>http://yoursite.com/2018/04/15/helloWorld/</id>
<published>2018-04-15T07:52:08.000Z</published>
<updated>2018-04-25T13:53:40.256Z</updated>
<content type="html"><![CDATA[<p>去年买的搬瓦工的服务器,因为到期了太久没有续费,已经被厂商关闭了,部署在上面的博客自然也访问不到了。也没有心思把它再重新搭建起来,天知道我当初搭建它时查了多少文章。[笑哭]</p><p>但话又说回来了,博客是coder的脸面,没有的话又有点说不过去,只好另辟蹊径,找到了Hexo。</p><a id="more"></a> <h2 id="说说Hexo"><a href="#说说Hexo" class="headerlink" title="说说Hexo"></a>说说Hexo</h2><p>Hexo的使用体验是简单 + 愉快的,基本上跟着<a href="https://hexo.io/zh-cn/docs/index.html" target="_blank" rel="noopener">官方教程</a>敲一遍就能上手,书写方面采用的是MarkDown,学起来也很快。部署方面也很简单,将写好的文章传到服务器上就可以了(就你废话多)。这里我还参考了<a href="https://zhuanlan.zhihu.com/p/26625249" target="_blank" rel="noopener">知乎的一篇文章</a>。</p><p>从想法萌生到新博客诞生,整个过程算下来不到2个小时,还是挺快的。让人心情预愉悦^ ^</p><p>今天就先到这了~</p><p>以上。</p>]]></content>
<summary type="html">
<p>去年买的搬瓦工的服务器,因为到期了太久没有续费,已经被厂商关闭了,部署在上面的博客自然也访问不到了。也没有心思把它再重新搭建起来,天知道我当初搭建它时查了多少文章。[笑哭]</p>
<p>但话又说回来了,博客是coder的脸面,没有的话又有点说不过去,只好另辟蹊径,找到了Hexo。</p>
</summary>
<category term="随笔" scheme="http://yoursite.com/categories/%E9%9A%8F%E7%AC%94/"/>
</entry>
</feed>