-
Notifications
You must be signed in to change notification settings - Fork 0
/
atom.xml
518 lines (276 loc) · 159 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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title>Calpa</title>
<icon>https://www.gravatar.com/avatar/e2a0454b2ff2e4aeb4fa2937b7a2ea4a</icon>
<link href="/atom.xml" rel="self"/>
<link href="https://calpa.me/"/>
<updated>2017-10-02T11:58:36.000Z</updated>
<id>https://calpa.me/</id>
<author>
<name>Calpa</name>
<email>[email protected]</email>
</author>
<generator uri="http://hexo.io/">Hexo</generator>
<entry>
<title>前端程序員的必備工具清單(MacOS)</title>
<link href="https://calpa.me/2017/10/02/frontend-developer-tools-in-macos/"/>
<id>https://calpa.me/2017/10/02/frontend-developer-tools-in-macos/</id>
<published>2017-10-02T13:53:00.000Z</published>
<updated>2017-10-02T11:58:36.000Z</updated>
<content type="html"><![CDATA[<h2 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h2><p>工欲善其事,必先利其器。一套完善的工具可以幫助我們事半功倍。而作為前端程序員的我,也是花了點時間為自己配置了一套工具。如果你也是使用 MacOS 作為你的開發系統的話,那麼你可以看一下這篇文章。</p><h2 id="日常"><a href="#日常" class="headerlink" title="日常"></a>日常</h2><h3 id="Alfred-3"><a href="#Alfred-3" class="headerlink" title="Alfred 3"></a><a href="https://www.alfredapp.com/" rel="external nofollow noopener noreferrer" target="_blank">Alfred 3</a></h3><p><img class="lozad" data-src="https://i.imgur.com/5yaDRiv.jpg" alt="Alfred Search"></p><p>Alfred 是一個強大的效率工具,而且它更加是一個全面的自動化工具平台。你可以從下圖感受一下:</p><p><img class="lozad" data-src="https://i.imgur.com/RK1OiPq.png" alt="Alfred 的功能"></p><p>你只要在 Alfred 的輸入框,寫下你想要的東西前幾個字,它便會顯示你所希望的命令。不過最強大的是可以和 MacOS 內置的全文搜尋一起用,也就是你輸入<code>in</code> 命令,它就可以全局全文搜尋。</p><p><img class="lozad" data-src="https://i.imgur.com/925QlWY.png" alt="全局搜尋"></p><p>另外,它也可以記錄你所 Copy 過的歷史,如果你使用 Emacs 的 Kill Ring 的話,他就會自動記錄代碼。我工作的時候就經常應用到 Alfred,因為有很多代碼都需要刪除,然後幾個小時後就有人跟你說那個代碼需要還原。。。</p><p><img class="lozad" data-src="https://i.imgur.com/SsJkjae.png" alt="Clipboard 歷史記錄"></p><p>另外,它的 Powerpack 和 Workflows 提供 Alfred 一個升級的可能性(腦洞),讓你可以寫出自己的代碼,並快捷執行。</p><h3 id="Aria2GUI"><a href="#Aria2GUI" class="headerlink" title="Aria2GUI"></a>Aria2GUI</h3><p>下載神器,網上有很多不同的前端界面,例如 <a href="https://github.com/yangshun1029/aria2gui" rel="external nofollow noopener noreferrer" target="_blank">Yet Another Aria2 Web FrontEnd</a></p><p><img class="lozad" data-src="https://i.imgur.com/YT38J2q.png" alt="Yet Another Aria2 Web FrontEnd"></p><h3 id="ImageOptim"><a href="#ImageOptim" class="headerlink" title="ImageOptim"></a><a href="https://imageoptim.com/mac" rel="external nofollow noopener noreferrer" target="_blank">ImageOptim</a></h3><p><img class="lozad" data-src="https://i.imgur.com/tEgTJmb.png" alt="ImageOptim 界面"></p><p>沒有經過優化或壓縮的圖片,直接上傳到伺服器或讓其他用戶下載的話,需要的時間都會很長,所以我的圖片大多都會經過 ImageOptim 優化一下。ImageOptim 是一個開源,免費的無損圖片優化工具。</p><h3 id="Moom"><a href="#Moom" class="headerlink" title="Moom"></a><a href="https://manytricks.com/moom/" rel="external nofollow noopener noreferrer" target="_blank">Moom</a></h3><p>Mac 本身沒有提供類似 Windows 上面移動,放大視窗的功能,因此會經常看到有些人的電腦很多個視窗重疊了。。。</p><p><img class="lozad" data-src="https://i.imgur.com/dGOOGRz.jpg" alt="Align Left"></p><h3 id="TotalSpaces2"><a href="#TotalSpaces2" class="headerlink" title="TotalSpaces2"></a><a href="https://totalspaces.binaryage.com/" rel="external nofollow noopener noreferrer" target="_blank">TotalSpaces2</a></h3><p><img class="lozad" data-src="https://i.imgur.com/cAizggh.png" alt="TotalSpaces2"></p><p>一個超好用的 Mac 桌面空間管理工具,包含以下六大功能:</p><ol><li><p>可以上下左右放置桌面佈局,而不是只有默認的向左向右<br> <img class="lozad" data-src="https://i.imgur.com/j0xBUi1.png" alt="上下左右的桌面佈局"></p></li><li><p>觸控板可以跳轉上下左右的桌面格子<br> <img class="lozad" data-src="https://i.imgur.com/f3uGPqJ.png" alt="觸控跳轉格子"></p></li><li><p>桌面格子可以設置默認的應用<br> <img class="lozad" data-src="https://i.imgur.com/2KEOJhI.png" alt="設置默認應用"></p></li><li><p>全面的桌面概覽<br> <img class="lozad" data-src="https://i.imgur.com/8pZTHJc.png" alt="全面的桌面概覽"></p></li><li>更加炫酷的桌面跳轉效果<br> <img class="lozad" data-src="https://i.imgur.com/69cceh0.png" alt="跳轉效果"></li><li>屏幕的四個角落可以觸發各自的動作<br> <img class="lozad" data-src="https://i.imgur.com/HtnXX4a.png" alt="屏幕角落觸發動作"></li></ol><p>應用場景:</p><p>當只有一個屏幕,又要同時運行多個佔用全屏的應用,你可能需要切來切去。透過使用 TotalSpaces2,你就可以輕鬆切換屏幕,比如說下面看伺服器狀態,上面看代碼區域。</p><p>另外,你也可以設置 Terminal 應用在下方屏幕格子,編輯器在上方屏幕格子。</p><h3 id="Eagle"><a href="#Eagle" class="headerlink" title="Eagle"></a><a href="https://eagle.cool/macOS" rel="external nofollow noopener noreferrer" target="_blank">Eagle</a></h3><p><img class="lozad" data-src="https://i.imgur.com/6JGSOld.png" alt="Eagle"></p><p>Eagle 是一個專門為設計師而打造的圖片收藏及管理工具。雖然我不是設計師,但是我有收藏大量的圖片,尤其是二次元動畫的截圖。對於這麼多的圖片,我曾經都很苦惱,因為截圖之後無法再次調用。。。幸好有這個工具,我就可以輕鬆地收藏網頁圖片,或者截屏到 <a href="https://eagle.cool/macOS" rel="external nofollow noopener noreferrer" target="_blank">Eagle</a>。之後可以打上標籤,或者人物的台詞。</p><p><img class="lozad" data-src="https://i.imgur.com/VnB1ItB.png" alt="感覺圖片太多,需要找個工具管理圖片www"></p><h2 id="Coding"><a href="#Coding" class="headerlink" title="Coding"></a>Coding</h2><h3 id="oh-my-zsh"><a href="#oh-my-zsh" class="headerlink" title="oh-my-zsh"></a><a href="https://github.com/robbyrussell/oh-my-zsh" rel="external nofollow noopener noreferrer" target="_blank">oh-my-zsh</a></h3><p><img class="lozad" data-src="https://i.imgur.com/otYtqAu.png" alt="oh-my-zsh"></p><p>為什麼你的 Terminal 使用上來那麼不一樣?是的,<strong>oh-my-zsh</strong> 背後的社區驅動著我(逃。。。</p><p>有時間可以說說到底為什麼 <strong>oh-my-zsh</strong> 那麼強大,以及它的配件。</p><h3 id="Solarized-配色方案"><a href="#Solarized-配色方案" class="headerlink" title="Solarized 配色方案"></a><a href="http://ethanschoonover.com/solarized" rel="external nofollow noopener noreferrer" target="_blank">Solarized 配色方案</a></h3><p><img class="lozad" data-src="https://i.imgur.com/mf5wi85.png" alt="兩種配色方案"></p><p><img class="lozad" data-src="https://i.imgur.com/Vtm0vIa.png" alt="清晰易見"></p><p><img class="lozad" data-src="https://i.imgur.com/7O38J5g.png" alt="包含的顏色"></p><h3 id="SourceTree"><a href="#SourceTree" class="headerlink" title="SourceTree"></a><a href="https://www.sourcetreeapp.com/" rel="external nofollow noopener noreferrer" target="_blank">SourceTree</a></h3><p><img class="lozad" data-src="https://i.imgur.com/7vtlS8m.png" alt="SourceTree 界面"></p><p>以前沒有習慣命令行的時候,我是用 SourceTree 來看 Git 歷史的。雖然我現在喜歡使用命令行來操作 Git,但是比較複雜的 Git 操作還是需要專門的工具的,例如 SourceTree 就是一個不錯的選擇。</p><h2 id="高能區域(編輯器)"><a href="#高能區域(編輯器)" class="headerlink" title="高能區域(編輯器)"></a>高能區域(編輯器)</h2><p>無論是什麼神的編輯器,還是編輯器的神,取其精華去其糟粕才是最好的。</p><h3 id="Atom"><a href="#Atom" class="headerlink" title="Atom"></a><a href="https://atom.io/" rel="external nofollow noopener noreferrer" target="_blank">Atom</a></h3><p><img class="lozad" data-src="https://i.imgur.com/B47vleN.png" alt="Atom"></p><p>Atom 是一個基於 Electron 的現代開源文本編輯器,你可以直接黑掉它的核心,甚至改得完全不一樣。你可以使用 HTML,CSS/Less 及 JavaScript 修改 Atom的功能,它的功能包括但不限於:</p><ol><li><p>支持跨平台</p><ol><li><p>內置的 Package 管理系統</p><p>你可以在 Atom 直接搜尋 Package,並且安裝 Package。</p></li><li><p>自動補全</p></li><li>瀏覽檔案系統</li><li>全局搜尋</li></ol></li></ol><p><img class="lozad" data-src="https://i.imgur.com/IDDanXB.png" alt="編輯器 with Git Diff"></p><p><img class="lozad" data-src="https://i.imgur.com/03wyXY4.png" alt="Atom 設置面板"></p><p><img class="lozad" data-src="https://i.imgur.com/RTMhhex.png" alt="內置的 Package 管理系統"></p><h3 id="Emacs"><a href="#Emacs" class="headerlink" title="Emacs"></a>Emacs</h3><blockquote><p>Emacs = Escape + Meta + Alt + Control + Shift</p></blockquote><p><img class="lozad" data-src="https://i.imgur.com/HmiuWMz.png" alt="Emacs Hello World"></p><p>其實我是蠻喜歡 Emacs 的思想,以及它的按鍵。因為寫代碼就好像輸入打遊戲需要的特殊命令,一種寫代碼就是玩遊戲的概念。我養成盲打的習慣,好像也是因為 Emacs 而開始的。。。</p><h3 id="Vim"><a href="#Vim" class="headerlink" title="Vim"></a>Vim</h3><p>如果我要簡單的 Git Commit,我就可以直接寫 Git Commit 記錄,然後輸入<code>:wq</code>,並不需要那麼複雜的工具。</p><h2 id="瀏覽器"><a href="#瀏覽器" class="headerlink" title="瀏覽器"></a>瀏覽器</h2><ol><li><a href="https://www.google.com/chrome/index.html" rel="external nofollow noopener noreferrer" target="_blank">Google Chrome</a></li></ol><p>這個是個必需品吧。。。</p><ol><li><a href="https://www.getpostman.com/" rel="external nofollow noopener noreferrer" target="_blank">Postman</a></li></ol><p>一個超級好用的 HTTP 請求工具,誰用誰知道。</p><h2 id="相關文章"><a href="#相關文章" class="headerlink" title="相關文章"></a>相關文章</h2><ol><li><a href="https://calpa.me/2017/07/02/introduction-to-hhkb-pro-2/">《神兵利器 – HHKB Pro 2 開箱文》</a></li></ol>]]></content>
<summary type="html">
<h2 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h2><p>工欲善其事,必先利其器。一套完善的工具可以幫助我們事半功倍。而作為前端程序員的我,也是花了點時間為自己配置了一套工具。如果你也是使用 Mac
</summary>
<category term="Front End" scheme="https://calpa.me/Tags/Front-End/"/>
<category term="MacOS" scheme="https://calpa.me/Tags/MacOS/"/>
</entry>
<entry>
<title>【圖多】《遠征成功﹣﹣一個香港人北上杭州豬場的前端面試之路》</title>
<link href="https://calpa.me/2017/09/30/hang-zhou-interview-summary/"/>
<id>https://calpa.me/2017/09/30/hang-zhou-interview-summary/</id>
<published>2017-09-30T10:00:00.000Z</published>
<updated>2017-09-30T12:50:29.000Z</updated>
<content type="html"><![CDATA[<h2 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h2><p>謝邀。本文圖多,流量黨慎入。</p><p>首先,我要感謝網易。作為一個香港人,能夠拿到杭州的面試機會,實屬機會難得。這次的兩輪技術面試,考察點廣泛而深入。雖然問題比較深入,但這讓我感覺對於技術要求比較高,這是一件好事,因為可以反映公司對於技術的重視。在大四的這一年裡,我會繼續努力,爭取時間學習一個。本文將會記錄我面試時遇過的問題,以及作為一個香港人在杭州遇到的困難。。。</p><p><img class="lozad" data-src="https://i.imgur.com/3IAyiiO.png" alt="我想先以升級和畢業為目標努力"></p><p>如果你想看圖的話,直接跳到下方的<a href="#杭州之旅">杭州之旅</a>章節就行。</p><h2 id="一面"><a href="#一面" class="headerlink" title="一面"></a>一面</h2><h3 id="面試官的問題"><a href="#面試官的問題" class="headerlink" title="面試官的問題"></a>面試官的問題</h3><ol><li><a href="/about">自我介紹</a></li><li>跨域怎樣處理?</li><li>如何做模塊化?有什麼好處?</li><li><a href="/about">你追求的前端是怎樣的一個前端?</a></li></ol><h3 id="我的問題"><a href="#我的問題" class="headerlink" title="我的問題"></a>我的問題</h3><p>前後端分離?</p><h2 id="二面"><a href="#二面" class="headerlink" title="二面"></a>二面</h2><h3 id="面試官的問題-1"><a href="#面試官的問題-1" class="headerlink" title="面試官的問題"></a>面試官的問題</h3><ol><li><a href="/about">自我介紹</a></li><li><a href="/about">請介紹一下你的專業 (Major)</a></li><li><a href="/2017/04/23/hackUST-2017-hackathon-summary/">什麼是黑客松?做什麼的?</a></li><li>最近一次黑客松你做了什麼?</li><li>說一下 React 實現原理</li><li>有了解過 React 底部發生什麼事情嗎?</li><li>React 生態圈</li><li>React Router 發生什麼事情?</li><li>Redux 做了什麼事情?</li><li>如何做多狀態管理</li><li><a href="/2017/09/27/async-summary/">異步操作</a></li><li>輸入網址之後到瀏覽器渲染完成之間,發生什麼事情</li></ol><h3 id="我的問題-1"><a href="#我的問題-1" class="headerlink" title="我的問題"></a>我的問題</h3><ol><li>前後端分離?</li><li>前端渲染?服務器渲染?前端下載框架,然後獲取伺服器資料再渲染?</li></ol><p>我印象最深刻的是下面三條題目:</p><ol><li>跨域</li><li>異步操作</li><li>輸入網址之後到瀏覽器渲染完成之間,發生什麼事情</li></ol><p>很難?是的,因為我還沒有寫文章,拿著草稿就出去面試。。。如果你有關心社區裡面的文章的話,你會發現那些都是周經(每個星期都提出來的話題)。</p><p><img class="lozad" data-src="https://i.imgur.com/SxgiJxK.png" alt="但是越強才越有攻略的價值"></p><p>很輕鬆?也不是。因為暑假的時候,我去了實習,沒有那麼多時間去寫博客文章,所以有一種被人家追稿的感覺。所以,在這一次面試裡面,我就把兩個月累積的稿子在兩次面試裡面說出來,你想一想也知道,當天的我是說了多少話。。。</p><p>對於這三個問題,我會分成三篇文章,因為這三個問題,有很多細節在裡面的。異步操作已經在<a href="/2017/09/27/async-summary/">《異步操作見聞錄》</a>談及過,有機會的話,我們再討論一下跨域以及輸入網址之後到瀏覽器渲染完成之間,發生什麼事情。</p><p>好吧,就讓我們從香港出發吧。</p><hr><h2 id="杭州之旅"><a href="#杭州之旅" class="headerlink" title="杭州之旅"></a>杭州之旅</h2><h3 id="香港"><a href="#香港" class="headerlink" title="香港"></a>香港</h3><p><img class="lozad" data-src="https://i.imgur.com/qPTMcjM.jpg" alt="九龍塘車站"><br><img class="lozad" data-src="https://i.imgur.com/ZkmrV9p.jpg" alt="上車了"><br>我沒有選擇從香港國際機場出發,而是選擇去深圳寶安機場出發。我需要在九龍塘坐火車上去落馬洲,過關後在福田口岸坐地鐵 4號線到會展中心,轉乘 1號線到車公廟,然後轉乘 11號線抵達機場站。</p><h3 id="深圳"><a href="#深圳" class="headerlink" title="深圳"></a>深圳</h3><p><img class="lozad" data-src="https://i.imgur.com/l7g4Qdj.jpg" alt="深圳寶安機場"><br>深圳機場和香港機場都是採取了自然採光的設計,盡可能利用太陽光,這樣的設計看上去帶有現代科技感,也有自然的元素在內。那些六角形的位置,有著一種規律的美感。</p><p><img class="lozad" data-src="https://i.imgur.com/WWO2xOy.jpg" alt="42 登機口"></p><p>The answer to life, the universe, and everything.</p><p><img class="lozad" data-src="https://i.imgur.com/4LGNjjM.jpg" alt="初音 Kindle"></p><p>我在過去的暑假定制的初音 Kindle,一種帶著初音去旅行的感覺www</p><h3 id="杭州"><a href="#杭州" class="headerlink" title="杭州"></a>杭州</h3><p><img class="lozad" data-src="https://i.imgur.com/XbYLcdi.jpg" alt="抵達杭州"><br>抵達杭州的時候,風和日麗,一點都不像會有颱風過來的樣子。</p><p><img class="lozad" data-src="https://i.imgur.com/yPPME3s.jpg" alt="電子支付在杭州"></p><p>杭州是阿里巴巴的總部,可以說是具有中國特色的電子支付,支付寶發源地。只要有支付寶,就可以在便利店購物,坐巴士,完全不用帶現金出街也行。可惜的是,杭州電子公交卡需要實名認證,還需要開通花唄。花唄功能,到本文截稿為止,它依然沒有讓非中國身份證的人使用。也就是說,身為一個香港人,還是需要購買一張公交卡(八達通),或者使用現金。</p><p>雖然這一次杭州之旅,我不能享受這個服務,我也覺得沒有什麼問題,因為深圳還是需要公交卡來乘坐地鐵或者巴士。然而,這個時候的我,還沒有想到杭州處於一個拒絕沒有中國身份證的狀態。。。</p><p>即使我預定了賓館,他們依然不能接待我。我打電話問面試官說一下這個問題後,便跑去杭州知名的如家快捷酒店,試試能不能入住。可惜的是,對於沒有中國身份證的人,他們是不能接待的,解釋是沒有開通港澳台居民的服務。。。</p><p><img class="lozad" data-src="https://i.imgur.com/zdHe4xH.png" alt="我想問個問題"></p><p>對於外國人而言,他們是可以入籍中國,然後獲得中國身份證。然而,香港土生土長的香港人,又怎麼會跟你搞一張中國身份證呢?關於這一點,我不想在這裡展開。但是,對於有心前來杭州工作的香港人,包括我在內,這是一個迫切的問題。不知道 2020 年杭州舉辦的亞洲運動會,杭州的政策會有什麼改變,但我相信這一定會越來越好的。畢竟她想要成為一線城市,這一點可以說是不能忽視的。一線城市其中一個要素是有很多來自不同地方的人。。。你連居住也不能保障,如何叫人留下來。。。對於這一點,面試當日的 HR 面試環節,我明確表示我是香港人,沒有中國身份證的事實,並詢問網易的安排。</p><p>於是,那一天我就被三連拒了。幸得杭州友人幫忙,我才得以找了一個房間租下來,不至於流落街頭。</p><h3 id="面試當日"><a href="#面試當日" class="headerlink" title="面試當日"></a>面試當日</h3><p><img class="lozad" data-src="https://i.imgur.com/cdlkptJ.jpg" alt="網易正門"></p><p>網易的門口也是蠻好找的,因為門口一大堆單車。。。</p><p>面試當日,非常多人。隨便找幾個人談天,他們都是大牛,現在實習於中國的知名互聯網公司,讓我感到要爭取時間,學習一個。如果要問能不能贏 我也沒有底氣,畢竟能夠進去網易的都是大牛www</p><p><img class="lozad" data-src="https://i.imgur.com/z8B9JbB.png" alt="如果要問能不能贏 我也沒有底氣"></p><p>你問我能不能面試過關,我只能說無可奉告,因為我沒有底氣。因此,選擇困難症的我只好爭取時間吃飯,因為網易餐廳的菜單實在是太多了,很吸引人www</p><p><img class="lozad" data-src="https://i.imgur.com/vfbrXh2.jpg" alt="吃飯了"></p><p><img class="lozad" data-src="https://i.imgur.com/XGOSYlY.jpg" alt="網易餐廳午餐"></p><p>中午要吃得清淡一點,因為不知道有沒有面試,要是有的話,那就不能破喉嚨了。。。</p><p><img class="lozad" data-src="https://i.imgur.com/Ou7RoJ1.jpg" alt="網易餐廳晚餐"></p><p>真是的,這麼多面試題目,我要好好吃一頓。。。</p><p><img class="lozad" data-src="https://i.imgur.com/HvzzHOM.png" alt="真是的,好辛苦呢(一臉幸福"></p><h3 id="第三天"><a href="#第三天" class="headerlink" title="第三天"></a>第三天</h3><p><img class="lozad" data-src="https://i.imgur.com/TlVLgIY.jpg" alt="醬鴨"><br><img class="lozad" data-src="https://i.imgur.com/tYSNBmp.jpg" alt="好吃的杭州菜"></p><p>儘管第一天遇到了那些不愉快的事,但是吃過網易餐廳的菜,還有杭州友人和我一起去吃得杭州菜之後,我也忘記那些事情了。</p><p><img class="lozad" data-src="https://i.imgur.com/0gVyruv.png" alt=":p"></p><h2 id="後記"><a href="#後記" class="headerlink" title="後記"></a>後記</h2><p>最後再一次感謝網易。我感覺杭州是一個好地方,不管是空氣,還是食物,我也覺得很好。</p><p>對於網易雲音樂,我最喜歡的是每日歌曲推薦和評論區系統。它的算法也是蠻準確的,雖然我不是很懂算法,但是每天能夠聽到不同的歌曲,然後收藏一個,也是覺得蠻開心的。我每天都要利用網易雲音樂,聽日文歌曲。尤其是寫代碼,或者寫博客文章的時候,更加是要不斷聽我喜歡的音樂裡面的歌曲。</p><p>如果你在 2018 年之後要來杭州的話,可以找一下我。</p><p>說到這裡,歡迎來到實力至上的世界。</p><p><img class="lozad" data-src="https://i.imgur.com/4Ltl87d.png" alt=""></p><h2 id="備註"><a href="#備註" class="headerlink" title="備註"></a>備註</h2><p>Hexo 框架有問題:當文章長度有一定長度,而且中英文混合的時候,<code>hexo serve</code> 會有亂碼問題。原因是 Node.js buffer 問題。。。</p><p>本文已參加<a href="https://juejin.im/post/59aa744ff265da247c4f145c" rel="external nofollow noopener noreferrer" target="_blank">掘金秋招征文</a>。</p>]]></content>
<summary type="html">
<h2 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h2><p>謝邀。本文圖多,流量黨慎入。</p>
<p>首先,我要感謝網易。作為一個香港人,能夠拿到杭州的面試機會,實屬機會難得。這次的兩輪技術面試,考
</summary>
<category term="Front End" scheme="https://calpa.me/Tags/Front-End/"/>
<category term="Interview" scheme="https://calpa.me/Tags/Interview/"/>
<category term="杭州" scheme="https://calpa.me/Tags/%E6%9D%AD%E5%B7%9E/"/>
<category term="掘金技術征文" scheme="https://calpa.me/Tags/%E6%8E%98%E9%87%91%E6%8A%80%E8%A1%93%E5%BE%81%E6%96%87/"/>
</entry>
<entry>
<title>異步操作見聞錄</title>
<link href="https://calpa.me/2017/09/27/async-summary/"/>
<id>https://calpa.me/2017/09/27/async-summary/</id>
<published>2017-09-27T12:00:00.000Z</published>
<updated>2017-09-30T12:44:38.000Z</updated>
<content type="html"><![CDATA[<h2 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h2><p>異步操作是非常常見的操作,也是其中一題常見的前端工程師面試題目。在日常開發中,我們會和伺服器交互,或者是和用戶的行動作出反應,比如說監聽某些點擊事件。這個時候,其實我們是執行了異步操作,我們需要等待對方若干時間才能收到返回值,甚至是一個錯誤的值。。。因此,異步操作很容易產生一些誤會。這裡,我會說一下異步操作,及其返回的處理方法。</p><h2 id="同步與異步的分別"><a href="#同步與異步的分別" class="headerlink" title="同步與異步的分別"></a>同步與異步的分別</h2><p>在同步的世界裡面,我們希望執行某些操作之後,就能夠馬上拿到返回的值,然後執行下一步。然而,當我們發出 HTTP 請求的時候,我們可能需要等待世界的另外一端返回信息,這需要時間,便不是同步了。。。</p><p>如果沒有異步的話,當你發出 HTTP 請求的時候,瀏覽器需要等待伺服器返回才執行下一步。這就是代表瀏覽器會卡住。。。</p><p>異步處理,簡單來說就是我們發出了一個行動,但是不是馬上得到結果,我們會繼續執行後面的指令,等到函數裡面有一個返回,我們才拿那個返回值來使用。最簡單的說法,就是我們向服務器發出請求,但是服務器需要時間處理,並且返回處理過的內容。</p><h2 id="異步操作處理方法"><a href="#異步操作處理方法" class="headerlink" title="異步操作處理方法"></a>異步操作處理方法</h2><ol><li>Callback</li><li>Promise (思想)</li><li>Generator</li><li>Async await (推薦)</li></ol><h3 id="Callback"><a href="#Callback" class="headerlink" title="Callback"></a>Callback</h3><p>我們看一下維基百科上面對於 Callback 的說明:</p><blockquote><p>在電腦程式設計中,回呼函式,或簡稱回呼(Callback 即call then back 被主函數呼叫運算後會返回主函數),是指通過函數參數傳遞到其它代碼的,某一塊可執行代碼的參照。這一設計允許了底層代碼呼叫在高層定義的子程式。</p></blockquote><p>這樣好像說得蠻複雜的,但其實很簡單,你把一個函數 cb (Function) 作為參數 (Argument)傳進這個函數 B 裡面,然後在函數 B 使用函數 cb。</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line">function func(x, cb) {</div><div class="line"> cb(x)</div><div class="line">}</div></pre></td></tr></table></figure><p>舉個例子,比如我們要在 Node.js 裡面讀取一個檔案,我們的代碼會是下面這樣的:</p><p>hello.txt:<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">Hello World, I'm Calpa Liu.</div></pre></td></tr></table></figure></p><hr><p>index.js:<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div></pre></td><td class="code"><pre><div class="line">var fs = require('fs');</div><div class="line"></div><div class="line">fs.readFile('hello.txt', function (err, data) {</div><div class="line"> if (err) {</div><div class="line"> return console.error(err);</div><div class="line"> }</div><div class="line"></div><div class="line"> console.log(data);</div><div class="line">});</div><div class="line"></div><div class="line">console.log('Finished');</div></pre></td></tr></table></figure></p><p>我們會在 callback 裡面處理 callback,也就是一個回調裡面做另外一件事情,那可能是另外一個 callback,那麼你可以想象一下,我們越寫越深。。。這樣有兩個問題,第一:代碼的耦合性會很高,不容易去拆分代碼;第二:代碼的維護性很差。</p><p><img class="lozad" data-src="https://i.imgur.com/bjHDvVN.jpg" alt="Imgur"></p><h3 id="Promise"><a href="#Promise" class="headerlink" title="Promise"></a>Promise</h3><p>Promise 是說如果你做了 A 的事情,成功了就做 B,不成功就做 C,你還可以繼續做 D 的事情,然後進行成功和不成功的處理。這樣說可能比較虛,但是你看一下 MDN 上面的圖就會明白了。</p><p><img class="lozad" data-src="https://i.imgur.com/w9BxjmL.png" alt="Promise - MDN"></p><p>一個發射子彈的動作可以這樣寫:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div></pre></td><td class="code"><pre><div class="line">var fire = new Promise(function(resolve, reject) {</div><div class="line"> setTimeout(function() {</div><div class="line"> resolve('已命中三千里外的目標');</div><div class="line"> }, 3000)</div><div class="line">});</div><div class="line"></div><div class="line">fire.then(function(result) {</div><div class="line"> console.log(result);</div><div class="line">});</div></pre></td></tr></table></figure><p>你可以在 Windows 平台按 F12 或 Ctrl + Shift + I,或在 Mac 上 按 Cmd + Opt + I,打開 Google Chrome Developer Tools ,然後在 Console 貼上上面的代碼,三秒後就會輸出<code>已命中三千里外的目標</code>。</p><p>你也可以在 then() 裡面寫 1個到 N個的 Promise。</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div></pre></td><td class="code"><pre><div class="line">var fire = new Promise(function(resolve, reject) {</div><div class="line"> setTimeout(function() {</div><div class="line"> resolve('已命中三千里外的目標');</div><div class="line"> }, 3000)</div><div class="line">});</div><div class="line"></div><div class="line">fire.then(function(result) {</div><div class="line"> console.log(result);</div><div class="line"> console.log('正在返回司令部');</div><div class="line"> return fire.then(function (result) {</div><div class="line"> console.log(result);</div><div class="line"> });</div><div class="line">});</div></pre></td></tr></table></figure><h3 id="Generator"><a href="#Generator" class="headerlink" title="Generator"></a>Generator</h3><p>Generator 其實是一個狀態機,內部保存機器的運行狀態。我們透過獲取機器的完成狀態 (done),我們能夠重複調用機器。我們可以使用 yield 暫停一個函數,並跳出函數。從外面的角度來看,我們可以從上而下去寫代碼,但是代碼會複雜,難以理解。</p><p>雖然它已經寫進 ECMAScript 2015 的正式規範裡面,但是我不太喜歡使用 Generator。我們簡單看一下 Generator 就好了,因為現在是 2017 年,異步操作的有更加好的處理方法。</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div></pre></td><td class="code"><pre><div class="line">function* gen() {</div><div class="line"> yield 1;</div><div class="line"> yield 2;</div><div class="line"> yield 3;</div><div class="line">}</div><div class="line"></div><div class="line">var g = gen(); // "Generator { }"</div><div class="line">g; //</div><div class="line">g.next(); // {value: 1, done: false}</div><div class="line">g.next(); // {value: 2, done: false}</div><div class="line">g.next(); // {value: 3, done: false}</div><div class="line">g.next() // {value: undefined, done: true}</div></pre></td></tr></table></figure><h3 id="Async-Await"><a href="#Async-Await" class="headerlink" title="Async/Await"></a>Async/Await</h3><p>對於技術的要求,是無止境的。為了寫出更加優美的代碼,你又可以付出什麼的代價呢?</p><p>如果你沒有試過 Async/Await 的話,那麼你就應該試一下,因為實在是太優雅了。</p><p>這里我就放出一段現在博客在用的代碼:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div></pre></td><td class="code"><pre><div class="line">async const getPosts = () => {</div><div class="line"> await res = axios.get('https://calpa.me/posts');</div><div class="line"> return res.data;</div><div class="line">}</div></pre></td></tr></table></figure><p>我們簡單的讀一下這段代碼:</p><p>一個異步的不變量 <code>getPosts</code> 是一個箭頭函數,內部操作為等待 axios 的 GET 請求到地址:<a href="https://calpa.me">http://calpa.me</a>,並返回伺服器返回的資料。</p><p>這是一個非常簡單的異步操作吧,但是如果是這樣的呢?<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div></pre></td><td class="code"><pre><div class="line">async const getUserData = () => {</div><div class="line"> await posts = axios.get('https://calpa.me/posts');</div><div class="line"> await accountInfo = axios.get('https://calpa.me/about');</div><div class="line"> /* ... */</div><div class="line">}</div></pre></td></tr></table></figure></p><p>如果你想要使用 Async / Await 的話,可以使用<br><a href="https://www.infoq.com/news/2017/02/node-76-async-await" rel="external nofollow noopener noreferrer" target="_blank">Node.js 7.6</a> 或以上的版本。例如使用 nvm 安裝 v8: <code>nvm install v8</code>,然後 <code>nvm use v8</code>。</p><p>另外,如果你不想更新 Node 版本的話,你可以安裝 <a href="https://caolan.github.io/async/" rel="external nofollow noopener noreferrer" target="_blank">async 工具庫</a>。</p><h2 id="感想"><a href="#感想" class="headerlink" title="感想"></a>感想</h2><p>異步操作已經成為了前端工程師面試常見的問題之一,感覺是對於前端工程師的技術水平需求越來越提高了。雖然這些都是在 MDN 上面寫好的介紹,但是只有自己用過才會知道什麼比較好。</p><p>如果公司的 Node 版本可以支持 Async/Await 的話,那就直接用 Async/Await 就好了。不行的話,那就用 Promise 吧,不然 Generator 的設計對於強迫症患者來說很不順眼。。。</p><h2 id="參考資料"><a href="#參考資料" class="headerlink" title="參考資料"></a>參考資料</h2><ol><li><a href="https://en.wikipedia.org/wiki/Callback" rel="external nofollow noopener noreferrer" target="_blank">Callback (computer programming) - Wikipedia</a></li><li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise" rel="external nofollow noopener noreferrer" target="_blank">Promise - MDN</a></li><li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Generator" rel="external nofollow noopener noreferrer" target="_blank">Generator</a></li><li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function" rel="external nofollow noopener noreferrer" target="_blank">async function - JavaScript MDN</a></li></ol>]]></content>
<summary type="html">
<h2 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h2><p>異步操作是非常常見的操作,也是其中一題常見的前端工程師面試題目。在日常開發中,我們會和伺服器交互,或者是和用戶的行動作出反應,比如說監聽某些
</summary>
<category term="JavaScript" scheme="https://calpa.me/Tags/JavaScript/"/>
<category term="Front End" scheme="https://calpa.me/Tags/Front-End/"/>
</entry>
<entry>
<title>React-markdown -- 實時渲染 Markdown 的 React 工具</title>
<link href="https://calpa.me/2017/08/31/react-markdown-render-markdown-as-component/"/>
<id>https://calpa.me/2017/08/31/react-markdown-render-markdown-as-component/</id>
<published>2017-08-31T06:25:00.000Z</published>
<updated>2017-09-30T12:24:26.000Z</updated>
<content type="html"><![CDATA[<h2 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h2><p>要寫出優雅的文檔是有難度的,尤其是需要格式規範的文章。而利用 Markdown,則可以專心寫作。Markdown 除了可以直接編譯為 HTML,還能編譯為 PowerPoint, Resume,還有 React 組件。無論是<a href="https://calpa.me/2017/06/01/create-markdown-powerpoint-in-5-mins/">利用 Markdown 製作 PowerPoint</a>,還是利用 Markdown 製作簡歷,都是非常方便的。如果你不是很熟悉 Markdown 語法的話,你可以在下文看 <a href="#Markdown-語法">Markdown 語法</a>。但是如果可以接受他人傳進來的 Markdown 文章,然後渲染他們的文章,那就會更加好。所以我就找了一下 React + Markdown 的組合,發現這個 React-markdown 工具下載的人數蠻多的。雖然那個項目還在開發階段,但是你可以在 <a href="http://rexxars.github.io/react-markdown" rel="external nofollow noopener noreferrer" target="_blank">Live Demo</a> 測試一下渲染為 React 組件的效果。</p><hr><p><img class="lozad" data-src="https://i.imgur.com/UFkBeEN.png" alt="Live Demo"></p><p><img class="lozad" data-src="https://i.imgur.com/q2q2RJv.png" alt="直接渲染為 React 組件"></p><h2 id="react-markdown"><a href="#react-markdown" class="headerlink" title="react-markdown"></a>react-markdown</h2><p>Github: <a href="https://github.com/rexxars/react-markdown" rel="external nofollow noopener noreferrer" target="_blank">https://github.com/rexxars/react-markdown</a><br>npmjs: <a href="https://www.npmjs.com/package/react-markdown" rel="external nofollow noopener noreferrer" target="_blank">https://www.npmjs.com/package/react-markdown</a></p><h3 id="安裝"><a href="#安裝" class="headerlink" title="安裝"></a>安裝</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">npm install --save react-markdown</div></pre></td></tr></table></figure><h3 id="使用方法"><a href="#使用方法" class="headerlink" title="使用方法"></a>使用方法</h3><p>使用 ES6 Import <code>ReactMarkdown</code>,然后使用 <reactmarkdown>,並傳入 Markdown 到 source。</reactmarkdown></p><figure class="highlight js"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">import</span> ReactMarkdown <span class="keyword">from</span> <span class="string">'react-markdown'</span>;</div><div class="line"></div><div class="line"><span class="keyword">const</span> input = <span class="string">'# This is a header\n\nAnd this is a paragraph'</span>;</div><div class="line"></div><div class="line"><ReactMarkdown source={input} /></div></pre></td></tr></table></figure><p>然後你會看到這樣的:</p><p><img class="lozad" data-src="https://i.imgur.com/zR2Olai.png" alt="React Markdown 例子"></p><p>官網上是這樣說的:<br><figure class="highlight js"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">var</span> React = <span class="built_in">require</span>(<span class="string">'react'</span>);</div><div class="line"><span class="keyword">var</span> ReactDOM = <span class="built_in">require</span>(<span class="string">'react-dom'</span>);</div><div class="line"><span class="keyword">var</span> ReactMarkdown = <span class="built_in">require</span>(<span class="string">'react-markdown'</span>);</div><div class="line"></div><div class="line"><span class="keyword">var</span> input = <span class="string">'# This is a header\n\nAnd this is a paragraph'</span>;</div><div class="line"></div><div class="line">ReactDOM.render(</div><div class="line"> <ReactMarkdown source={input} />,</div><div class="line"> <span class="built_in">document</span>.getElementById(<span class="string">'container'</span>)</div><div class="line">);</div></pre></td></tr></table></figure></p><h3 id="Webpack-1-配置"><a href="#Webpack-1-配置" class="headerlink" title="Webpack 1 配置"></a>Webpack 1 配置</h3><p>如果你是用 Webpack 1 的話,你需要安裝 json-loader:<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">npm install --save json-loader</div></pre></td></tr></table></figure></p><p>並在你的 webpack 設置裡面加上:</p><figure class="highlight js"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div></pre></td><td class="code"><pre><div class="line">{</div><div class="line"> <span class="built_in">module</span>: {</div><div class="line"> loaders: [{</div><div class="line"> test: <span class="regexp">/\.json$/</span>,</div><div class="line"> loader: <span class="string">'json-loader'</span></div><div class="line"> }]</div><div class="line"> }</div><div class="line">}</div></pre></td></tr></table></figure><p>如果你設置 <code>escapeHtml</code> 或 <code>skipHtml</code> 為 <code>true</code>,該組件就不會使用<code>dangerouslySetInnerHTML</code>。</p><h3 id="選項"><a href="#選項" class="headerlink" title="選項"></a>選項</h3><p>以下選項除了<code>source</code>之外都是可選的,其實這個工具已經配置成開箱即用,這裡就說幾個最底部的選項,更多的選項請去官網看。</p><ul><li><code>source</code> - 你的 Markdown 來源(必須)- string</li><li><code>className</code> - 容器的 className - string</li><li><code>containerTagName</code> - 容器的標籤名字 ,因為 Markdown 會有很多不同層次的 elements,容器需要把它們封裝。默認是<code>div</code> - string</li></ul><p>這個渲染器會渲染的組件有:</p><ul><li><code>HtmlInline</code> - 行內 HTML</li><li><code>HtmlBlock</code> - HTML 塊</li><li><code>Text</code> - 文字 (在段落裡面)</li><li><code>Paragraph</code> - 段落 (<code><p></code>)</li><li><code>Heading</code> - 標題 (<code><h1></code>, <code><h2></code> etc)</li><li><code>Softbreak</code> - 換行</li><li><code>Hardbreak</code> - 斷行(強制換行) (<code><br></code>)</li><li><code>Link</code> - 鏈接 (<code><a></code>)</li><li><code>Image</code> - 圖像 (<code><img></code>)</li><li><code>Emph</code> - 強調 (<code><em></code>)</li><li><code>Code</code> - Inline code nodes (<code><code></code>)</li><li><code>CodeBlock</code> - Blocks of code (<code><code></code>)</li><li><code>BlockQuote</code> - 參照 (<code><blockquote></code>)</li><li><code>List</code> - 列表 (<code><ol></code>, <code><ul></code>)</li><li><code>Item</code> - 列表 (<code><li></code>)</li><li><code>Strong</code> - Strong/bold nodes (<code><strong></code>)</li><li><code>ThematicBreak</code> - 水平分割線 (<code><hr></code>)</li></ul><h2 id="Markdown-語法"><a href="#Markdown-語法" class="headerlink" title="Markdown 語法"></a>Markdown 語法</h2><p>Markdown 的目標是易讀易寫,而它能夠幫助程序員專注開發,減少編寫文檔時候遇到的格式問題。Markdown 和 HTML 的寫法差不多,雖然 HTML 已經很容易寫,但是 Markdown 則是更加格式化,如果你直接閱讀 Markdown 文檔,你也可以想象到它渲染後的樣式。</p><h3 id="標題"><a href="#標題" class="headerlink" title="標題"></a>標題</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line"># H1</div><div class="line">## H2</div><div class="line">### H3</div></pre></td></tr></table></figure><h3 id="清單"><a href="#清單" class="headerlink" title="清單"></a>清單</h3><p>無序清單使用<code>*</code>, <code>+</code> 或<code>-</code>,而我這是常用<code>-</code><br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div></pre></td><td class="code"><pre><div class="line">* Red</div><div class="line">* Green</div><div class="line">* Blue</div><div class="line"></div><div class="line">+ Red</div><div class="line">+ Green</div><div class="line">+ Blue</div><div class="line"></div><div class="line">- Red</div><div class="line">- Green</div><div class="line">- Blue</div></pre></td></tr></table></figure></p><p>有序清單則使用數字接著一個英文句點:<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line">1. Apple</div><div class="line">2. Banana</div><div class="line">3. Watermelon</div></pre></td></tr></table></figure></p><h2 id="後記"><a href="#後記" class="headerlink" title="後記"></a>後記</h2><p>順帶說一下,我的博客已經配置好 Service Worker,現在可以離線訪問網站。也就是下次訪問的時候,即使沒有 Wifi 或者連接到網絡,你也能夠瀏覽到文章內容。</p><p>有機會的話,我會說說如何配置 Service Worker,以及當中的原理。</p><p>我的簡歷也差不多重構一次了(逃。。。</p>]]></content>
<summary type="html">
<h2 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h2><p>要寫出優雅的文檔是有難度的,尤其是需要格式規範的文章。而利用 Markdown,則可以專心寫作。Markdown 除了可以直接編譯為 HTM
</summary>
<category term="Markdown" scheme="https://calpa.me/Tags/Markdown/"/>
<category term="React" scheme="https://calpa.me/Tags/React/"/>
</entry>
<entry>
<title>React 應用輕量化(一)Source Map</title>
<link href="https://calpa.me/2017/08/27/react-app-optimization-1-source-map/"/>
<id>https://calpa.me/2017/08/27/react-app-optimization-1-source-map/</id>
<published>2017-08-27T02:03:00.000Z</published>
<updated>2017-09-30T12:24:26.000Z</updated>
<content type="html"><![CDATA[<h2 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h2><p><code>create-react-app</code> 提供了很方便的創建 React 應用途徑。它已經把 webpack, Babel, Autoprefixer, ESLint, Jest 等常用工具打包進去。可以說是一個非常方便,好用的製造 React 應用工具。當我打算把包裝好的檔案推上去的時候,我卻發現打包之後的檔案大小有點大,因此我就開始優化這個網頁應用了。第一點我優化的地方就是 Source Map。</p><p>如果你細心看 README.md 的話,你會發現下面這一句,它把 Source Map 也打包進去。。。</p><blockquote><p>A build script to bundle JS, CSS, and images for production, with sourcemaps.</p></blockquote><p>在測試環境中,我們可以透過 sourcemap 找到 bundle 過後的對應項目組件,這個是蠻方便的。</p><p>但是,在生產環境中,如果有 sourcemap 的話,就會直接暴露項目中的架構,以及檔案,同時會增加網站大小。。。</p><h2 id="解決方法"><a href="#解決方法" class="headerlink" title="解決方法"></a>解決方法</h2><h3 id="快速方法"><a href="#快速方法" class="headerlink" title="快速方法"></a>快速方法</h3><p>排除 <code>*.map</code>,避免部署 sourcemap 到上面。。。</p><p>這個方法並不能從根源解決問題,因為產生 sourcemap 需時較長,另外,也會產生一個不需要的檔案大小略大的 sourcemap 檔案。</p><h3 id="徹底方法"><a href="#徹底方法" class="headerlink" title="徹底方法"></a>徹底方法</h3><ol><li><code>npm run eject</code>,如果你沒有 Eject 過的話。</li></ol><p>Eject 是一個特殊命令,把 <code>create-react-app</code> 的懶人包變成自定義的項目。在 Eject 之前,請想清楚你是否需要掌握項目的每一個細節。</p><p>對應日新月異的產品需求以及開發需求,我選擇 Eject。比如說 SCSS,CSS 模組化。</p><ol><li><p>用你喜歡的文字編輯器 或 IDE 打開 <code>/config/webpack.config.prod.js</code></p></li><li><p>刪除或注釋第五十三行 <code>devtool: 'source-map'</code></p></li></ol><p>在上面你可以看到這樣的注釋:</p><blockquote><p>// We generate sourcemaps in production. This is slow but gives good results.<br>// You can exclude the *.map files from the build during deployment.</p></blockquote><p>它這裡寫就是說產生 sourcemap 會給出好的結果,雖然產生時間會更加長。。。</p><p>另外,你可以排除 <code>*.map</code>,避免部署 Source Map 到上面。。。</p><h2 id="參考資料"><a href="#參考資料" class="headerlink" title="參考資料"></a>參考資料</h2><ol><li><a href="https://github.com/facebookincubator/create-react-app" rel="external nofollow noopener noreferrer" target="_blank">create-react-app README</a></li><li><a href="https://github.com/facebookincubator/create-react-app/issues/2005" rel="external nofollow noopener noreferrer" target="_blank">Disable webpack production sourcemaps</a></li></ol>]]></content>
<summary type="html">
<h2 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h2><p><code>create-react-app</code> 提供了很方便的創建 React 應用途徑。它已經把 webpack, Babel
</summary>
<category term="React" scheme="https://calpa.me/Tags/React/"/>
</entry>
<entry>
<title>善用 Github Issue 的開源評論插件 -- Gitalk</title>
<link href="https://calpa.me/2017/08/04/utilize-github-issue-by-using-gitalk/"/>
<id>https://calpa.me/2017/08/04/utilize-github-issue-by-using-gitalk/</id>
<published>2017-08-04T12:00:00.000Z</published>
<updated>2017-09-30T12:24:33.000Z</updated>
<content type="html"><![CDATA[<p><img class="lozad" data-src="https://i.imgur.com/DqyRXB9.jpg" alt="Gitalk"></p><h2 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h2><p>以前,我的博客是用 Disqus 的評論插件,但是無論是載入速度,還是樣式上,都是有所缺乏的。我一直沒有安裝其他的評論插件,因為覺得搬家有點麻煩。但是當我試用一下之後,我就覺得這個插件安裝很方便,功能也很實用,尤其是可以寫 Markdown 評論,就讓我非常喜歡這個插件了。因此,我拜讀了一下 <a href="https://github.com/gitalk/gitalk" rel="external nofollow noopener noreferrer" target="_blank">Gitalk Github Repo</a> 的代碼。我會在這裡說一下我對這個插件的理解,並提交繁體中文 README.md 到官方倉庫上。如果你想試用的話,你可以到<a href="https://gitalk.github.io/" rel="external nofollow noopener noreferrer" target="_blank">官網</a>或<a href="#gitalk-container">我的博客</a>留言。</p><p>Gitalk 是一個基於 Github Issue 和 Preact 開發的評論插件。它支持多語言,包括英文,繁體中文和簡體中文,並<a href="https://github.com/gitalk/gitalk/blob/48de82ca24d4cb24a464f7cc9e72884a208b9d5c/src/gitalk.jsx#L55" rel="external nofollow noopener noreferrer" target="_blank">自動判斷用戶當前語言</a>:<code>navigator.language || navigator.userLanguage</code>。用戶只需要使用自己的個人或組織 Github 賬戶便可以登入系統。</p><p>另外,它也有以下的功能:</p><ul><li>無干擾模式:<code>distractionFreeMode</code></li><li>快捷鍵提交評論 (cmd || ctrl + enter)</li></ul><h2 id="安裝方法"><a href="#安裝方法" class="headerlink" title="安裝方法"></a>安裝方法</h2><h3 id="使用-cdn-引入"><a href="#使用-cdn-引入" class="headerlink" title="使用 cdn 引入"></a>使用 cdn 引入</h3><figure class="highlight html"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line"><span class="tag"><<span class="name">link</span> <span class="attr">rel</span>=<span class="string">"stylesheet"</span> <span class="attr">href</span>=<span class="string">"https://unpkg.com/gitalk/dist/gitalk.css"</span>></span></div><div class="line"></div><div class="line"><span class="tag"><<span class="name">script</span> <span class="attr">src</span>=<span class="string">"https://unpkg.com/gitalk/dist/gitalk.min.js"</span>></span><span class="undefined"></span><span class="tag"></<span class="name">script</span>></span></div></pre></td></tr></table></figure><p>直至8月4日,我仍然沒有在 cdnjs 上面找到 Gitalk 的,只好去 cdnjs/cdnjs 上面提交了<a href="https://github.com/cdnjs/cdnjs/issues/11668" rel="external nofollow noopener noreferrer" target="_blank">新的 cdn 需求</a>。如果你也認為有需要用到 cdnjs 的話,你可以去那裡說一下。</p><h3 id="利用-npm-安裝"><a href="#利用-npm-安裝" class="headerlink" title="利用 npm 安裝"></a>利用 npm 安裝</h3><figure class="highlight sh"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line">npm i --save gitalk</div><div class="line">cnpm i --save gitalk</div></pre></td></tr></table></figure><figure class="highlight js"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">import</span> <span class="string">'gitalk/dist/gitalk.css'</span></div><div class="line"><span class="keyword">import</span> Gitalk <span class="keyword">from</span> <span class="string">'gitalk'</span></div></pre></td></tr></table></figure><h3 id="去-Github-上面-clone-Gitalk"><a href="#去-Github-上面-clone-Gitalk" class="headerlink" title="去 Github 上面 clone Gitalk"></a>去 Github 上面 clone Gitalk</h3><figure class="highlight sh"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line">git <span class="built_in">clone</span> [email protected]:gitalk/gitalk.git</div><div class="line"><span class="built_in">cd</span> gitalk/dist/</div></pre></td></tr></table></figure><p>然後把壓縮過的<code>gitalk.min.js</code> 放進你的項目。</p><h2 id="使用方法"><a href="#使用方法" class="headerlink" title="使用方法"></a>使用方法</h2><p><img class="lozad" data-src="https://i.imgur.com/C6HEsRv.png" alt="Register a new OAuth Application"></p><p>Gitalk 需要 <strong>Github Application</strong>,如果沒有請點擊 <a href="https://github.com/settings/applications/new" rel="external nofollow noopener noreferrer" target="_blank">Register a new OAuth application</a> 申請,<code>Authorization callback URL</code> 填寫當前使用插件頁面的域名,例如我的博客就是填寫 <a href="https://calpa.me">https://calpa.me</a></p><h3 id="代碼範例"><a href="#代碼範例" class="headerlink" title="代碼範例"></a>代碼範例</h3><figure class="highlight js"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">var</span> gitalk = <span class="keyword">new</span> Gitalk({</div><div class="line"> clientID: <span class="string">'Github Application Client ID'</span>,</div><div class="line"> clientSecret: <span class="string">'Github Application Client Secret'</span>,</div><div class="line"> repo: <span class="string">'Github repo'</span>,</div><div class="line"> owner: <span class="string">'Github repo owner'</span>,</div><div class="line"> admin: [<span class="string">'Github repo collaborators'</span>],</div><div class="line">})</div><div class="line"></div><div class="line">gitalk.render(<span class="string">'gitalk-container'</span>)</div></pre></td></tr></table></figure><h2 id="Gitalk-選項"><a href="#Gitalk-選項" class="headerlink" title="Gitalk 選項"></a>Gitalk 選項</h2><ul><li><p><strong>clientID</strong> <code>String</code></p><p><strong>必須</strong>. Github Application Client ID.</p></li><li><p><strong>clientSecret</strong> <code>String</code></p><p><strong>必須</strong>. Github Application Client Secret.</p></li><li><p><strong>repo</strong> <code>String</code></p><p><strong>必須</strong>. Github repository.</p></li><li><p><strong>owner</strong> <code>String</code></p><p><strong>必須</strong>. Github repository 所有者,可以是個人或者組織。</p></li><li><p><strong>admin</strong> <code>Array</code></p><p><strong>必須</strong>. Github repository 合作者 (確保對這個 repository 是有寫的權限)。</p></li><li><p><strong>id</strong> <code>String</code></p><p>Default: <code>location.href</code>.</p><p>頁面的唯一標識。</p></li><li><p><strong>labels</strong> <code>Array</code></p><p>Default: <code>['Gitalk']</code>.</p><p>Github issue 的標簽。</p></li><li><p><strong>title</strong> <code>String</code></p><p>Default: <code>document.title</code>.</p><p>Github issue 的標題。</p></li><li><p><strong>body</strong> <code>String</code></p><p>Default: <code>location.href + header.meta[description]</code>.</p><p>Github issue 的內容。</p></li><li><p><strong>language</strong> <code>String</code></p><p>Default: <code>navigator.language || navigator.userLanguage</code>.</p><p>設置語言,支持 [en, zh-CN, zh-TW]。</p></li><li><p><strong>perPage</strong> <code>Number</code></p><p>Default: <code>10</code>.</p><p>每次加載的數據大小,最多 100。</p></li><li><p><strong>distractionFreeMode</strong> <code>Boolean</code></p><p>Default: false。</p><p>類似Facebook評論框的全屏遮罩效果.</p></li><li><p><strong>pagerDirection</strong> <code>String</code></p><p>Default: ‘last’</p><p>評論排序方式, <code>last</code>為按評論創建時間倒敘,<code>first</code>為按創建時間正序。</p></li><li><p><strong>createIssueManually</strong> <code>Boolean</code></p><p>Default: <code>false</code>.</p><p>如果當前頁面沒有相應的 isssue 且登錄的用戶屬於 admin,則會自動創建 issue。如果設置為 <code>true</code>,則顯示一個初始化頁面,創建 issue 需要點擊 <code>init</code> 按鈕。</p></li><li><p><strong>proxy</strong> <code>String</code></p><p>Default: <a href="https://cors-anywhere.herokuapp.com/https://github.com/login/oauth/access_token" rel="external nofollow noopener noreferrer" target="_blank">https://cors-anywhere/herokuapp.com</a></p><p> <a href="https://github.com/isaacs/github/issues/330" rel="external nofollow noopener noreferrer" target="_blank">Github oauth 請求到反向代理,為了支持 CORS。 </a></p></li><li><p><strong>flipMoveOptions</strong> <code>Object</code></p><p>Default:</p><figure class="highlight js"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div></pre></td><td class="code"><pre><div class="line">{</div><div class="line"> staggerDelayBy: <span class="number">150</span>,</div><div class="line"> appearAnimation: <span class="string">'accordionVertical'</span>,</div><div class="line"> enterAnimation: <span class="string">'accordionVertical'</span>,</div><div class="line"> leaveAnimation: <span class="string">'accordionVertical'</span>,</div><div class="line">}</div></pre></td></tr></table></figure><p>評論列表的動畫。 <a href="https://github.com/joshwcomeau/react-flip-move/blob/master/documentation/enter_leave_animations.md" rel="external nofollow noopener noreferrer" target="_blank">參考</a></p></li><li><p><strong>enableHotKey</strong> <code>Boolean</code></p><p>Default: <code>true</code>.</p><p>啟用快捷鍵(cmd|ctrl + enter) 提交評論.</p></li></ul><h2 id="方法"><a href="#方法" class="headerlink" title="方法"></a>方法</h2><ul><li><p><code>render(String/HTMLElement)</code></p><p>初始化渲染並掛載插件,<a href="https://github.com/gitalk/gitalk/blob/48de82ca24d4cb24a464f7cc9e72884a208b9d5c/src/index.js#L17" rel="external nofollow noopener noreferrer" target="_blank">需要提供 HTMLElement 的 id </a>。</p></li><li><p><code>setPerPage(page: number)</code></p><p>// TODO: 我想在構建gitalk之後,可以再次手動設置屬性 perPage 屬性,再次自行定義每個頁面的評論載入量。</p></li></ul><h2 id="後記"><a href="#後記" class="headerlink" title="後記"></a>後記</h2><p>這個 <a href="https://github.com/gitalk/gitalk" rel="external nofollow noopener noreferrer" target="_blank">Gitalk</a> 也是蠻好用的,它界面簡潔清新,沒有廣告,還支持 Markdown 格式。而且感覺更加適合 Markdown 程序員使用。。。</p>]]></content>
<summary type="html">
<p><img class="lozad" data-src="https://i.imgur.com/DqyRXB9.jpg" alt="Gitalk"></p>
<h2 id="前言"><a href="#前言" class="headerlink" title="前言"><
</summary>
<category term="Front End" scheme="https://calpa.me/Tags/Front-End/"/>
<category term="Blog" scheme="https://calpa.me/Tags/Blog/"/>
</entry>
<entry>
<title>項目代碼調試:提問前要做的六個步驟</title>
<link href="https://calpa.me/2017/07/24/six-steps-to-debug-before-directly-ask-question/"/>
<id>https://calpa.me/2017/07/24/six-steps-to-debug-before-directly-ask-question/</id>
<published>2017-07-24T13:00:00.000Z</published>
<updated>2017-09-30T12:28:08.000Z</updated>
<content type="html"><![CDATA[<p>上天對於每個地球人都是公平的,每個人都一天只有 24 小時。為什麼有的人會停留不前,有的人卻會不斷有所成長?其中一個原因是當遇到問題時,他們解決問題的方法是非常不同的。同樣是遇到問題,與其伸手,等其他程序員幫助去解決問題,倒不如自己先嘗試各種方法,然後才問人家。。。我會在這篇文章簡單說一下在你提問之前,你可以做的六個步驟。</p><h2 id="步驟"><a href="#步驟" class="headerlink" title="步驟"></a>步驟</h2><h3 id="1-檢查,試驗本地環境"><a href="#1-檢查,試驗本地環境" class="headerlink" title="1. 檢查,試驗本地環境"></a>1. 檢查,試驗本地環境</h3><p> 如果你是和其他人一齊開發項目的話,可能你會遇到 packages 安裝報錯的問題,這個時候,你應該試試安裝packages,例如<code>npm install</code>,把現有項目的 packages 更新一下,可能現有的 packages 已經不是最新的,或者有所缺乏。</p><p> 另外,你也可以看一下你自己的 npm 和 node 版本,是否因為版本號太低,而導致無法安裝某些 packages。如果是的話,請先確定是否需要用那麼新的 package 版本,然後再更新 node 版本。</p><h3 id="2-Google-Bing-一下"><a href="#2-Google-Bing-一下" class="headerlink" title="2. Google / Bing 一下"></a>2. Google / Bing 一下</h3><p> <img class="lozad" data-src="https://i.imgur.com/1Djy0Gj.png" alt="Google 一下"></p><p> 問題就是答案,其實你直接在搜尋引擎搜尋,就會找到這些問題的解決方法。如果你問我一些技術的問題,我很可能會直接叫你 Google,因為有時候第一個搜尋結果就是你的答案。如果你已經找過,但是找不到的話,很大機會是你的搜尋字不對,你可以加一下你的項目的 package,比如說 把 react, bootstrap 等字眼加在搜尋裡面。</p><h3 id="3-閱讀官方資料"><a href="#3-閱讀官方資料" class="headerlink" title="3. 閱讀官方資料"></a>3. 閱讀官方資料</h3><p> <img class="lozad" data-src="https://i.imgur.com/kmFRumd.png" alt="Calpa's Blog Github Repo"></p><p> 先閱讀 Github上面的 README.md,然後閱讀官網上對於該項目的簡介,使用方法,再看 API。你可以再看一次 Github Repo 的說明,看看有沒有自己沒注意到的地方。你也可以直接進入官網,然後看它對於各個方法,變量的說明。如果你看不到你想要的方法,你可以返回第二步,Google 一下。</p><h3 id="4-查看-Issue"><a href="#4-查看-Issue" class="headerlink" title="4. 查看 Issue"></a>4. 查看 Issue</h3><p> 如果你還是搜不到的話,看看人家有沒有遇到類似的問題,並從中獲取靈感。</p><h3 id="5-閱讀源代碼"><a href="#5-閱讀源代碼" class="headerlink" title="5. 閱讀源代碼"></a>5. 閱讀源代碼</h3><p> 有時候,開源項目的作者寫得比較匆忙,急著都沒有寫好文檔,以及測試代碼。這個時候,你直接看上面的代碼吧。。。</p><p> 如果是部署在 Github 上面的話,可以使用在線代碼搜尋插件,比如說 <a href="https://chrome.google.com/webstore/detail/insightio-for-github/pmhfgjjhhomfplgmbalncpcohgeijonh" rel="external nofollow noopener noreferrer" target="_blank">Insight.io for Github</a>。如果你已經把它 clone 下來的話,可以使用流行的編輯器進行全局搜尋,例如 Atom,Sublime。</p><p> <img class="lozad" data-src="https://i.imgur.com/OWuA4xP.png" alt="Insight.io"></p><p> 另外,你也可以使用 <a href="https://github.com/Jianru-Lin/lambda-view" rel="external nofollow noopener noreferrer" target="_blank">lambda-view</a>,閱讀 JavaScript 源代碼時,這個很好用的。<br> <img class="lozad" data-src="https://i.imgur.com/kmuI2NX.png" alt="lambda-view"></p><h3 id="6-出去走走,喝點水"><a href="#6-出去走走,喝點水" class="headerlink" title="6. 出去走走,喝點水"></a>6. 出去走走,喝點水</h3><p> <img class="lozad" data-src="https://i.imgur.com/oXlUIRt.gif" alt="喝點水,休息一下"></p><p> 如果你看了網上的解決方法,但覺得無從入手的話,出去走一走,喝一口水,讓大腦休息一下。有時候,我上午想不到的問題,吃個午餐,然後下午就想到解決方法了。</p><h2 id="禮貌地提出問題"><a href="#禮貌地提出問題" class="headerlink" title="禮貌地提出問題"></a>禮貌地提出問題</h2><p> 如果你做了以上的步驟,還是沒有辦法解決問題的話,你可以去 Repo 的 Issue 上面說一下,先不要直接說我找到一個 bug。。。</p><h2 id="後記"><a href="#後記" class="headerlink" title="後記"></a>後記</h2><p>感覺很長時間沒有寫博客了,文筆開始生疏。這一篇文章寫的時間比以前長,可能我要努力一點才行。。。</p>]]></content>
<summary type="html">
<p>上天對於每個地球人都是公平的,每個人都一天只有 24 小時。為什麼有的人會停留不前,有的人卻會不斷有所成長?其中一個原因是當遇到問題時,他們解決問題的方法是非常不同的。同樣是遇到問題,與其伸手,等其他程序員幫助去解決問題,倒不如自己先嘗試各種方法,然後才問人家。。。我會在這
</summary>
<category term="思考" scheme="https://calpa.me/Tags/%E6%80%9D%E8%80%83/"/>
</entry>
<entry>
<title>簡單易用的開源 JavaScript 動畫圖標庫 -- Titanic</title>
<link href="https://calpa.me/2017/07/06/titanic-a-set-of-animated-icons/"/>
<id>https://calpa.me/2017/07/06/titanic-a-set-of-animated-icons/</id>
<published>2017-07-06T03:00:00.000Z</published>
<updated>2017-09-30T12:28:23.000Z</updated>
<content type="html"><![CDATA[<p>如果你用過 Font Awesome 等圖標,你可能會覺得它們很好看,用起來很很方便。但是,在用戶點擊這些圖標的時候,它們是不會有反應的。如果有這些圖標會動的話,那就更加好。Titanic 提供一系列的動畫圖標,以及以 JavaScript 的調用圖標動畫的方法。</p><p>如果你想要看 Hello, World 的版本的話,你可以到我的 <a href="https://codepen.io/calpa/pen/xrzPxx" rel="external nofollow noopener noreferrer" target="_blank">Codepen</a> 裡面,測試一下。</p><p><img class="lozad" data-src="https://i.imgur.com/bLmxAZ3.gif" alt="Preview"></p><h2 id="安裝方法"><a href="#安裝方法" class="headerlink" title="安裝方法"></a>安裝方法</h2><p>你可以使用 CDN 或者 npm 來安裝 Titanic。</p><h3 id="CDN"><a href="#CDN" class="headerlink" title="CDN"></a>CDN</h3><p>直接在 HTML head 裡面加進下面的字符。<br><figure class="highlight html"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line"><span class="tag"><<span class="name">script</span> <span class="attr">src</span>=<span class="string">"https://cdn.rawgit.com/icons8/titanic/master/dist/js/titanic.min.js"</span>></span><span class="undefined"></span><span class="tag"></<span class="name">script</span>></span></div><div class="line"><span class="tag"><<span class="name">script</span> <span class="attr">src</span>=<span class="string">"https://cdnjs.cloudflare.com/ajax/libs/bodymovin/4.5.9/bodymovin.min.js"</span>></span><span class="undefined"></span><span class="tag"></<span class="name">script</span>></span></div></pre></td></tr></table></figure></p><p>然後在 body 的部分初始化 Titanic。</p><figure class="highlight html"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line"><span class="tag"><<span class="name">script</span>></span><span class="undefined"></span></div><div class="line"><span class="javascript"> <span class="keyword">var</span> titanic = <span class="keyword">new</span> Titanic();</span></div><div class="line"><span class="undefined"></span><span class="tag"></<span class="name">script</span>></span></div></pre></td></tr></table></figure><p>你可以透過這種標籤來加上 Titanic 圖標。</p><figure class="highlight html"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line"><span class="tag"><<span class="name">div</span> <span class="attr">class</span>=<span class="string">'titanic titanic_chat'</span>></span><span class="tag"></<span class="name">div</span>></span></div></pre></td></tr></table></figure><p><img class="lozad" data-src="https://i.imgur.com/aiG4BYo.png" alt="All icons"></p><p>你可以透過<a href="https://rawgit.com/icons8/titanic/master/demo/index.html" rel="external nofollow noopener noreferrer" target="_blank">這裡</a>查找 Titanic 所支持的圖標,把 chat 換成以下的字詞:</p><ul><li>caps</li><li>chat</li><li>checkbox</li><li>expand</li><li>cheap</li><li>expensive</li><li>idea</li><li>mailbox</li><li>mic</li><li>no-mic</li><li>online</li><li>pause</li><li>power</li><li>shopping</li><li>smile</li><li>stop</li><li>unlock</li><li>zoom</li></ul><h3 id="npm"><a href="#npm" class="headerlink" title="npm"></a>npm</h3><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">npm install titanic-icons --save</div></pre></td></tr></table></figure><p>鏈接:<a href="https://www.npmjs.com/package/titanic-icons" rel="external nofollow noopener noreferrer" target="_blank">titanic-icons - npmjs</a></p><h3 id="使用你自己的備份"><a href="#使用你自己的備份" class="headerlink" title="使用你自己的備份"></a>使用你自己的備份</h3><p>如果你喜歡在自己的伺服器,而不是 rawgit 去使用 Titanic 的話,你只需要把 base URL 傳進 init() 裡面。</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">titanic.begin(<span class="string">'/my/base/directory/'</span>);</div></pre></td></tr></table></figure><p>然後,當你有一個div,id=”chat” 的時候,Titanic 會自動檢測所有在 /my/base/directory/chat.json 裡面的圖標。</p><h2 id="API"><a href="#API" class="headerlink" title="API"></a>API</h2><ul><li><code>titanic.isInitialized()</code> – 返回 true / false</li><li><code>titanic.items</code> – 返回包含所有 titanic 圖標的一個 Array</li><li><code>titanic.items[index].on(), titanic.items[index].off(), titanic.items[index].play()</code> – 調整動畫 by index</li><li><code>titanic.on(token), titanic.off(token), titanic.play(token)</code> – 調整動畫 by token (name)</li></ul><h2 id="例子"><a href="#例子" class="headerlink" title="例子"></a>例子</h2><figure class="highlight html"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div></pre></td><td class="code"><pre><div class="line"><span class="tag"><<span class="name">head</span>></span></div><div class="line"> <span class="comment"><!--Inserting the scripts once for the whole page--></span></div><div class="line"> <span class="tag"><<span class="name">script</span> <span class="attr">src</span>=<span class="string">"https://cdn.rawgit.com/icons8/titanic/master/dist/js/titanic.min.js"</span>></span><span class="undefined"></span><span class="tag"></<span class="name">script</span>></span></div><div class="line"> <span class="tag"><<span class="name">script</span> <span class="attr">src</span>=<span class="string">"https://cdnjs.cloudflare.com/ajax/libs/bodymovin/4.5.9/bodymovin.min.js"</span>></span><span class="undefined"></span><span class="tag"></<span class="name">script</span>></span></div><div class="line"><span class="tag"></<span class="name">head</span>></span></div><div class="line"><span class="tag"><<span class="name">body</span>></span></div><div class="line"> <span class="comment"><!--Inserting an icon--></span></div><div class="line"> <span class="tag"><<span class="name">div</span> <span class="attr">class</span>=<span class="string">'titanic titanic-checkbox'</span>></span><span class="tag"></<span class="name">div</span>></span></div><div class="line"></div><div class="line"> <span class="comment"><!--Initializing--></span></div><div class="line"> <span class="tag"><<span class="name">script</span>></span><span class="undefined"></span></div><div class="line"><span class="javascript"> <span class="keyword">var</span> titanic = <span class="keyword">new</span> Titanic({</span></div><div class="line"><span class="javascript"> hover: <span class="literal">true</span>, <span class="comment">// auto animated on hover (default true)</span></span></div><div class="line"><span class="javascript"> click: <span class="literal">true</span> <span class="comment">// auto animated on click/tap (default false)</span></span></div><div class="line"><span class="undefined"> });</span></div><div class="line"><span class="undefined"> </span><span class="tag"></<span class="name">script</span>></span></div><div class="line"></div><div class="line"> <span class="comment"><!--Clicking turns this icon on--></span></div><div class="line"> <span class="tag"><<span class="name">button</span> <span class="attr">onclick</span>=<span class="string">"titanic.on(getElementById('checkbox').value)"</span>></span>On<span class="tag"></<span class="name">button</span>></span></div><div class="line"><span class="tag"></<span class="name">body</span>></span></div></pre></td></tr></table></figure><h2 id="原作者的話"><a href="#原作者的話" class="headerlink" title="原作者的話"></a>原作者的話</h2><blockquote><p>JavaScript is basically <a href="https://github.com/bodymovin/bodymovin" rel="external nofollow noopener noreferrer" target="_blank">bodymovin</a> plus few lines of my code. It’s a solid library with an awesome name. Thank you, guys.</p><p>Icons are created by <a href="https://dribbble.com/imargarita" rel="external nofollow noopener noreferrer" target="_blank">Margarita Ivanchikova</a> from <a href="https://icons8.com/" rel="external nofollow noopener noreferrer" target="_blank">Icons8</a>. She has many more awesome animations in her portfolio.</p><p>The code rewritten by <a href="https://github.com/dhilt" rel="external nofollow noopener noreferrer" target="_blank">Denis Alexanov</a>, my teacher and guru. Thank you!</p><p>Project is produced by Icons8, author of the famous icon library, <a href="https://iconpharm.com" rel="external nofollow noopener noreferrer" target="_blank">IconPharm</a>, and <a href="https://sleeklogos.design" rel="external nofollow noopener noreferrer" target="_blank">Sleek Logos</a>.</p><p>The code is created by Icons8</p></blockquote><p><img class="lozad" data-src="https://i.imgur.com/p8Xoj9l.gif" alt="Magritte"></p><p>Github Repo: <a href="https://github.com/icons8/titanic" rel="external nofollow noopener noreferrer" target="_blank">icons 8 / titanic</a></p><h2 id="感想"><a href="#感想" class="headerlink" title="感想"></a>感想</h2><p>我覺得這個很炫酷,我應該可以用在現有的前端開發項目,比如說博客,還有在做的一個在線學習編程平台上。如果你希望看到我如何應用 Titanic 的話,你可以打個星,關注一下我的博客。</p>]]></content>
<summary type="html">
<p>如果你用過 Font Awesome 等圖標,你可能會覺得它們很好看,用起來很很方便。但是,在用戶點擊這些圖標的時候,它們是不會有反應的。如果有這些圖標會動的話,那就更加好。Titanic 提供一系列的動畫圖標,以及以 JavaScript 的調用圖標動畫的方法。</p>
</summary>
<category term="JavaScript" scheme="https://calpa.me/Tags/JavaScript/"/>
<category term="Library" scheme="https://calpa.me/Tags/Library/"/>
</entry>
<entry>
<title>神兵利器 -- HHKB Pro 2 開箱文</title>
<link href="https://calpa.me/2017/07/02/introduction-to-hhkb-pro-2/"/>
<id>https://calpa.me/2017/07/02/introduction-to-hhkb-pro-2/</id>
<published>2017-07-02T12:16:00.000Z</published>
<updated>2017-07-02T15:54:05.000Z</updated>
<content type="html"><![CDATA[<img class="lozad" data-src="https://i.imgur.com/AVN6eaJ.jpg" width="500"><p>我一開始拿到 Happy Hacking KeyBoard Pro 2時,我就問為什麼鍵盤可以完全沒有字的,那叫我如何輸入。。。雖然我可以盲打(不看鍵盤直接輸入),但也許我未必可以有能力使用這樣的鍵盤。但寫了一天代碼之後,我才發現,原來這一切都是自己的猜疑而已。這個鍵盤打起來就是一個字,爽。</p><img class="lozad" data-src="https://i.imgur.com/AbKpx2P.jpg" width="500" title="HHKB Pro 2"><center>HHKB Pro 2 盒子</center><h2 id="HHKB"><a href="#HHKB" class="headerlink" title="HHKB"></a>HHKB</h2><p>在我取得這個 HHKB Pro 2 之前,我是一直在用 Cooler Master 的紅軸機械鍵盤,這個打起來也是很爽的。</p><p>HHKB 的按鍵數量相對少,只提供必需的那些按鍵,它取消了數字鍵,功能鍵,以及方向鍵。但是對於 Emacs 用戶(我)來說,這些都不是問題,因為很多時候都是按 Ctrl + P/N/B/F 來達到上下左右的效果。</p><p>雖則如此,我利用 Karabiner 做了四點配置:</p><ol><li>當 MacBook 鏈接 HHKB 的時候,電腦自帶的鍵盤不會再有輸出。</li><li>右邊 Command 按鍵變為右邊 Option</li><li>右邊 Option 按鍵變為右按 Mouse</li><li>Option 加 IKJL 等於 上下左右</li></ol><img class="lozad" data-src="https://i.imgur.com/aDZMqim.png" width="500" title="配置"><h2 id="Emacs"><a href="#Emacs" class="headerlink" title="Emacs"></a>Emacs</h2><blockquote><p>Emacs = Escape Meta Alt Ctrl Super</p></blockquote><p>作為一個 Emacs 重度(中毒)用戶,對 Ctrl 鍵的需求是很大的。尤其是我把 Ctrl 和 Caps Lock 的位置交換之後,左手無名指就經常發力。</p><p>不知不覺之間,我就已經學會了盲打的技巧。現在打代碼就像玩遊戲一樣,我幾乎都不用看鍵盤,直接想到那個字,那句命令,直接打出來。如果你不用看鍵盤,而是直接輸入的話,每分鐘打字速度會提高很多的。。。</p><p>最後,祝大家都能有自己的神兵利器,享受 Happy Hacking 的旅途。</p>]]></content>
<summary type="html">
<img class="lozad" data-src="https://i.imgur.com/AVN6eaJ.jpg" width="500">
<p>我一開始拿到 Happy Hacking KeyBoard Pro 2時,我就問為什麼鍵盤可以完全沒有字的,那叫我如何輸入。
</summary>
<category term="KeyBoard" scheme="https://calpa.me/Tags/KeyBoard/"/>
</entry>
<entry>
<title>【翻譯】前端性能優化必備工具清單</title>
<link href="https://calpa.me/2017/06/19/front-end-performance-check-list-for-production-in-chinese/"/>
<id>https://calpa.me/2017/06/19/front-end-performance-check-list-for-production-in-chinese/</id>
<published>2017-06-19T12:00:00.000Z</published>
<updated>2017-09-30T12:28:28.000Z</updated>
<content type="html"><![CDATA[<p>在網頁開發的世界裡,尤其是前端開發,我們會用很多時間尋找最好的設計,以及最好的內容。雖然這是沒有錯的,但是,我們會忘記去優化我們的網頁。。。這會讓用戶需要很久的時間,比如說,瀏覽器需要六秒到十秒以上才能完成整個渲染過程。。。</p><p>在這篇文章,我會分享優化網頁的檢查清單。如果你覺得我有錯漏的地方,請在下面留言。這張清單會包含一些優化搜尋引擎排名 (SEO) 的技巧,以及減少網頁加載時間的最佳實踐。</p><blockquote><p>編者按:很多都是我聽過或從來沒有用過的工具,我還是要學習一個。。。</p></blockquote><p>馬上開始!</p><h2 id="那些我們忘記的基本功"><a href="#那些我們忘記的基本功" class="headerlink" title="那些我們忘記的基本功"></a>那些我們忘記的基本功</h2><h3 id="Favicon"><a href="#Favicon" class="headerlink" title="Favicon"></a>Favicon</h3><p> 請不要忘記為你的網站加上它,它就好像是你的網站的 ID。無論你有沒有 favicon.ico ,用戶的瀏覽器依然會請求它。如果你忘記加上這個檔案,你的網站就會返回 404 Not Found,這會讓瀏覽器面紅。。。所以你要小心一點,避免給予用戶負面的第一印象。要解決這個問題,你可以透過 <a href="http://realfavicongenerator.net/" rel="external nofollow noopener noreferrer" target="_blank">Favicon Generator</a> 生成 favicon 和 manifest 檔案。</p><h3 id="Open-Graph"><a href="#Open-Graph" class="headerlink" title="Open Graph"></a>Open Graph</h3><p> 加上社交媒體的 meta 標籤,用戶更好地分享你的文章,同時 Google Ranking 也會提高,你可以使用 <a href="https://megatags.co/" rel="external nofollow noopener noreferrer" target="_blank">Meta Tags</a> 產生 Social meta tags。</p><blockquote><p>譯者按:產生 Open Graph Meta Tags,我的博客也加上了 Open Graph。</p></blockquote><h2 id="圖片優化"><a href="#圖片優化" class="headerlink" title="圖片優化"></a>圖片優化</h2><h3 id="壓縮圖像"><a href="#壓縮圖像" class="headerlink" title="壓縮圖像"></a>壓縮圖像</h3><p> 載入圖片會大幅地延長網頁的加載時間,甚至達到整體網頁載入時間的七成。如果可以的話,請使用 SVG,以及壓縮你的那些精緻圖像。你可以使用 <a href="http://compresspng.com/" rel="external nofollow noopener noreferrer" target="_blank">Compress PNG</a> 來幫忙壓縮圖像。</p><h2 id="CSS-優化"><a href="#CSS-優化" class="headerlink" title="CSS 優化"></a>CSS 優化</h2><h3 id="Autoprefixer"><a href="#Autoprefixer" class="headerlink" title="Autoprefixer"></a><strong>Autoprefixer</strong></h3><p> 解決跨瀏覽器上的 CSS 問題。我們都會在自己喜歡的瀏覽器下寫 CSS 的規矩,而我則是使用 Chrome。雖然如此,你依然需要為這些規矩加上 prefix 來支持所有類型的瀏覽器。 Autoprefixer 會使用現在瀏覽器熱度,對各種屬性支持度的資料,來提供你所需要的 prefix。你可以透過命令行來運用它。</p><figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line">npm install -g postcss-cli autoprefixer</div><div class="line">postcss *.css use autoprefixer -d build</div></pre></td></tr></table></figure><p>你也可以使用 Webpack 設置,或者使用 <a href="https://autoprefixer.github.io/" rel="external nofollow noopener noreferrer" target="_blank">Autoprefixer CSS online</a> 。</p><h3 id="Purifycss"><a href="#Purifycss" class="headerlink" title="Purifycss"></a><strong>Purifycss</strong></h3><p> 刪除項目內沒有用到的 CSS 規矩。它會讀取內容 (HTML/JS/PHP) 和 CSS,然後返回必須的 CSS。它是一個非常有用的工具,如果你是在用 CSS 框架比如說 Bootstrap,這個能夠減少很多的 CSS 文檔大小。</p><p>安裝方法:<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">npm install -g purify-css</div></pre></td></tr></table></figure></p><p>使用方法:<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">purifycss src/css/main.css src/css/bootstrap.css src/js/main.js — min — info — out src/dist/index.css</div></pre></td></tr></table></figure></p><p>你可以在 purify-css 的 <a href="https://github.com/purifycss/purifycss" rel="external nofollow noopener noreferrer" target="_blank">Github Page</a> 中獲得更多資訊。</p><h3 id="minify-CSS"><a href="#minify-CSS" class="headerlink" title="minify CSS"></a>minify CSS</h3><p> 你可以使用 purify-css 或使用網上的<a href="http://csscompressor.com/" rel="external nofollow noopener noreferrer" target="_blank">CSS Compressor</a>。</p><h2 id="減少載入時間"><a href="#減少載入時間" class="headerlink" title="減少載入時間"></a>減少載入時間</h2><h3 id="PageSpeed-Insights"><a href="#PageSpeed-Insights" class="headerlink" title="PageSpeed Insights"></a><a href="https://developers.google.com/speed/pagespeed/insights/" rel="external nofollow noopener noreferrer" target="_blank">PageSpeed Insights</a></h3><p> PageSpeed Insights 可以用來檢查載入網頁速度,它會分別在手提電話和電腦運行測試。它會使用手提電話的 user-agent,以及 Desktop 的 user-agent。PageSpeed 會檢查網頁時候已經應用網頁的最佳實踐,並提供一個 0﹣100 的分數,同時提供如何提高分數的意見。</p><h3 id="GZIP"><a href="#GZIP" class="headerlink" title="GZIP"></a>GZIP</h3><p> 開啟 GZIP 壓縮,是其中一個減少網頁載入速度的最快改善方法。Just Do IT,設置 GZIP,並讓你的用戶享受飛一般的感受,下圖是節省流量的效果圖。</p><img class="lozad" data-src="https://i.imgur.com/k7FRiSi.png" width="500" title="PICSrush GZIP 測試圖"><center>PICSrush GZIP 測試圖</center><p>你可以在<a href="https://checkgzipcompression.com/" rel="external nofollow noopener noreferrer" target="_blank">Check GZIP compression</a> 網站中測試你的網站是否已經開啟 GZIP 壓縮功能。</p><h3 id="CDN"><a href="#CDN" class="headerlink" title="CDN"></a>CDN</h3><p> 根據<a href="https://zh.wikipedia.org/zh-hk/%E5%85%A7%E5%AE%B9%E5%82%B3%E9%81%9E%E7%B6%B2%E8%B7%AF" rel="external nofollow noopener noreferrer" target="_blank">維基百科</a>,內容傳遞網路(CDN)是指一種透過互聯網互相連接的電腦網絡系統,利用最靠近使用者的伺服器,更快地傳送檔案。簡單來說,CDN 就是一種網絡上的緩存系統。你可以使用免費的 <a href="https://www.cloudflare.com/" rel="external nofollow noopener noreferrer" target="_blank">CloudFlare</a> 來達到這個效果。</p><blockquote><p>編者按:你可以用 cdnjs 或其他 cdn。</p></blockquote><h2 id="優化平台"><a href="#優化平台" class="headerlink" title="優化平台"></a>優化平台</h2><h3 id="Sentry"><a href="#Sentry" class="headerlink" title="Sentry"></a><a href="https://sentry.io/welcome/" rel="external nofollow noopener noreferrer" target="_blank">Sentry</a></h3><p> 對於前端工程師來說,它是一個非常正的工具。Sentry 檢查在瀏覽器環境下,是否存在任何 uncaught JavaScript exceptions,主動追蹤發生的錯誤,並提供報告。它提供豐富的 API,使得你可以自定義如何在其他地方顯示這些數據。</p><p> 它會透過 Email, SMS 或 Slack 通知你,當前端環境發生錯誤時,它亦會提供用戶回應。</p><h3 id="Google-Tag-Manager"><a href="#Google-Tag-Manager" class="headerlink" title="Google Tag Manager"></a><a href="https://developers.google.com/tag-manager/" rel="external nofollow noopener noreferrer" target="_blank">Google Tag Manager</a></h3><p> Google Tag Manager 可以一站式管理你所有會傳送到第三方,例如 Facebook 和 Twitter 的 JavaScript 代碼。透過使用它,你減少網頁的載入時間,以及更加方便地在同一個地方管理 JavaScript 代碼。</p><iframe width="100%" height="300" src="https://www.youtube.com/embed/KRvbFpeZ11Y" frameborder="0" allowfullscreen></iframe><blockquote><p>Thanks for reading! feel free to leave a comment if you think I miss something.</p><p>If you think other people should read this, press the 💚 button, tweet and share the post. Remember to follow me on Medium so you can get notified about my future posts.</p></blockquote><h2 id="譯者的話"><a href="#譯者的話" class="headerlink" title="譯者的話"></a>譯者的話</h2><p>這次翻譯英文文章,真的是很有趣呢,不過要寫起來感覺沒有自己從零開始寫一篇那麼流暢。</p><p>一開始我是去問問人家,可不可以翻譯一下他們的文章?結果就取得同意了。</p><p>這次翻譯這一篇文章,讓我了解到很多對我來講是新的工具,比如說 Sentry 以及Google Tag Manager。我還是一個萌新,感覺前端的路還有很長要走啊。。。</p><img class="lozad" data-src="https://i.imgur.com/SJma5Pv.png" width="500" title="calpa blog 測試圖"><center>Calpa’s Blog GZIP 測試圖</center><hr><p>原文鏈接: <a href="https://hackernoon.com/front-end-performance-check-list-for-production-4e930cb63e8a" rel="external nofollow noopener noreferrer" target="_blank">Frontend Performance Check-list For Production - Medium</a><br>原作者:<a href="https://medium.com/@yjose" rel="external nofollow noopener noreferrer" target="_blank">Youssouf El Azizi</a> <small>(Founder <a href="http://picsrush.com" rel="external nofollow noopener noreferrer" target="_blank">http://picsrush.com</a> , React js developer)</small></p>]]></content>
<summary type="html">
<p>在網頁開發的世界裡,尤其是前端開發,我們會用很多時間尋找最好的設計,以及最好的內容。雖然這是沒有錯的,但是,我們會忘記去優化我們的網頁。。。這會讓用戶需要很久的時間,比如說,瀏覽器需要六秒到十秒以上才能完成整個渲染過程。。。</p>
<p>在這篇文章,我會分享優化網頁的檢查
</summary>
<category term="Front End" scheme="https://calpa.me/Tags/Front-End/"/>
<category term="Performance" scheme="https://calpa.me/Tags/Performance/"/>
<category term="Production" scheme="https://calpa.me/Tags/Production/"/>
<category term="Check-list" scheme="https://calpa.me/Tags/Check-list/"/>
</entry>
<entry>
<title>【多圖】2017 年香港開源年會後記</title>
<link href="https://calpa.me/2017/06/14/hong-kong-open-sources-conference-remarks/"/>
<id>https://calpa.me/2017/06/14/hong-kong-open-sources-conference-remarks/</id>
<published>2017-06-14T01:28:00.000Z</published>
<updated>2017-06-14T15:39:05.000Z</updated>
<content type="html"><![CDATA[<p>大約兩個星期之前,我在 Facebook上看到 2017 年的香港開源年會的消息。我想,我是不是可以透過這個機會,認識一下不同領域的程序員呢。於是,我在 EventBrite 上面買了學生票。但最終我拿到 VIP 票了,感覺有點激動。我把這一次的會議做了幾點筆記,也許,每一個人都應該參加最少一次如此有規模的大會。我會在這裡說說我參與這次會議所發生的一些事。</p><p>在這一次大會之前,我參加了 Hong Kong Open Source Meeting #2,當時我是說<a href="https://calpa.me/2017/06/01/create-markdown-powerpoint-in-5-mins/">《5分鐘製作 Markdown PowerPoint》</a>。</p><p>那天晚上,我才知道原來那一次演講的話,就會有一張免費 VIP 票,包含入場的資格,衣服及外套。我還拿到一些免費的票,轉送給其他認識的人了。</p><img class="lozad" data-src="https://i.imgur.com/ZBautza.jpg" width="500" title="VIP Ticket"><center>VIP 門票</center><img class="lozad" data-src="https://i.imgur.com/4q7YR0J.png" width="500" title="Tshirt"><center>大會送的衣服</center><p>我之前幫忙舉辦 Hang Seng Bank AI Hackathon,在說大數據的時候提到了這個黑客松,並放出了團體合照。。。</p><img class="lozad" data-src="https://i.imgur.com/aSRoBdc.jpg" width="500" title="Hang Seng Bank AI Hackathon"><center>團體合照</center><h2 id="大數據"><a href="#大數據" class="headerlink" title="大數據"></a>大數據</h2><p>一些中國的互聯網公司對數據十分看重,並認為這些數據都是可以製造財富的資產。比如說滴滴打車收集了很多打車的交易數據,並善用這些數據優化分配司機和乘客的算法。又比如說阿里巴巴對大數據很重視,它的<a href="https://tianchi.aliyun.com/" rel="external nofollow noopener noreferrer" target="_blank">天池大數據眾智平台</a>會提供各種各樣的大數據,並舉辦比賽招聘人才。</p><p>在這一次大會中,我了解到原來台灣在開放數據這一方面做得不錯。根據<a href="https://index.okfn.org/place/" rel="external nofollow noopener noreferrer" target="_blank">Global Open Data Index</a> 的開放數據顯示,台灣是排名第一的,而香港則是排行 23。就讓我們看一下香港政府是如何開放數據的。</p><h3 id="香港的開放數據"><a href="#香港的開放數據" class="headerlink" title="香港的開放數據"></a>香港的開放數據</h3><p>香港政府<a href="https://data.gov.hk/tc/" rel="external nofollow noopener noreferrer" target="_blank">資料一線通</a>平台,以多種檔案格式提供多個政府部門類別,機構的一些查詢資料,比如說天氣預報,中學教育統計資料。值得注意的是,這些檔案並不是 ODF,而是 xls, xml, csv, json, gif, txt, tif。。。</p><p>而且連 Hello World 都不能跑,這叫我如何是好。。。</p><p>我把嘗試這個平台的過程寫成<a href="https://calpa.me/2017/06/12/hong-kong-open-data-from-zero-to-giveup/">《香港開放數據平台 - 從入門到放棄》</a>。</p><h2 id="自動化構建"><a href="#自動化構建" class="headerlink" title="自動化構建"></a>自動化構建</h2><img class="lozad" data-src="https://i.imgur.com/q8g0CgG.jpg" width="500" title="Reproducible builds"><p>Debian 的 Leader Chirs Lamb 也來了這一次的大會,他分享了 Reproducible builds 這一個主題。</p><h3 id="不可重現的原因"><a href="#不可重現的原因" class="headerlink" title="不可重現的原因"></a>不可重現的原因</h3><img class="lozad" data-src="https://i.imgur.com/NTUpphj.jpg" width="500" title="Reason of non-reproducibility"><ol><li>Timestramps</li><li>時區<br>比如說,你在美國用 <code>new Date()</code> 和我在香港用的話是不同的。</li><li>Non-deterministic file ordering</li><li>字典 / hash key 的次序不同<br>有些</li><li>用戶,群組,系統變量不同</li><li>組建的路徑不同 (eg. /home/lamby vs /home/calpa)</li></ol><hr><h3 id="Technical-Advantages"><a href="#Technical-Advantages" class="headerlink" title="Technical Advantages"></a>Technical Advantages</h3><img class="lozad" data-src="https://i.imgur.com/5WY6bHC.jpg" width="500" title="Technical Advantages"><ol><li>檢測構造環境程序所導致的意外。</li><li>更加容易地測試更新的代碼。<br>我們可以自動構建測試所需要的生產環境,定義所需要的數據。透過這個方法,我們可以自動測試時候更新後的代碼會不會引入更多的 Bug。。。</li></ol><hr><h2 id="最佳實踐"><a href="#最佳實踐" class="headerlink" title="最佳實踐"></a>最佳實踐</h2><h3 id="Builds"><a href="#Builds" class="headerlink" title="Builds"></a>Builds</h3><img class="lozad" data-src="https://i.imgur.com/p6pTo4O.jpg" width="500" title="Best Practices of Builds"><center>Best Practices of Builds</center><ol><li>把它當成是藍圖一樣</li><li>避免需要登入去構建或調試<br>這個可以利用Makefile, Gulp, Grunt 等一些自動化構建工具幫忙自動構建程序</li><li>善用版本控制工具去構建檔案<br>比如說用 Git…</li><li>Explicit is better than implicit<br>其實這一個思想以前也</li><li>每一次跑的時候都創造一個新的 layer</li></ol><hr><h3 id="Container-Host-Security"><a href="#Container-Host-Security" class="headerlink" title="Container Host Security"></a>Container Host Security</h3><img class="lozad" data-src="https://i.imgur.com/DZ1CSib.jpg" width="500" title="Best Practices of Container Host Security"><p><center>Best Practices of Container Host Security</center></p><ol><li>不要用 root 身份去跑</li><li>要限制 SSH Access</li><li>用 namespaces</li><li>定義資源限額</li><li>開啟記錄</li></ol><h2 id="認識其他程序員"><a href="#認識其他程序員" class="headerlink" title="認識其他程序員"></a>認識其他程序員</h2><img class="lozad" data-src="https://i.imgur.com/NXToUgx.png" width="500" title="台北摩茲工寮網頁"><p>這次我認識了台北摩茲工寮的其中一個摩茲人,了解到原來他們會每個禮拜在台北會有聚會。</p><p>也許,我們也可以參加他們的開源項目,作出自己小小的貢獻。</p><p>如果以後過去台北的話,我也可以過去拜會一下他們。</p><h2 id="食物"><a href="#食物" class="headerlink" title="食物"></a>食物</h2><img class="lozad" data-src="https://i.imgur.com/MaMW0xE.jpg" width="300" title="免費星巴克咖啡"><p>這次有星巴克的免費食物,比如說菠菜卷,冷麵,沙拉。味道不錯 XD</p><img class="lozad" data-src="https://i.imgur.com/ouO6EVo.jpg" width="300" title="北角雞蛋仔"><p>最後我離開數碼港,去北角嘗試北角雞蛋仔,其實味道也是不錯的。但是如果要說到最好吃的雞蛋仔的話,那還是九龍灣流動小販賣的炭燒雞蛋仔味道最好。</p><p>最後,感謝所有幫忙舉辦香港開源年會的人,讓我這樣的人也可以有一個渠道認識這個世界。</p>]]></content>
<summary type="html">
<p>大約兩個星期之前,我在 Facebook上看到 2017 年的香港開源年會的消息。我想,我是不是可以透過這個機會,認識一下不同領域的程序員呢。於是,我在 EventBrite 上面買了學生票。但最終我拿到 VIP 票了,感覺有點激動。我把這一次的會議做了幾點筆記,也許,每一
</summary>
<category term="Conference" scheme="https://calpa.me/Tags/Conference/"/>
<category term="Open Source" scheme="https://calpa.me/Tags/Open-Source/"/>
</entry>
<entry>
<title>香港開放數據平台 - 從入門到放棄</title>
<link href="https://calpa.me/2017/06/12/hong-kong-open-data-from-zero-to-giveup/"/>
<id>https://calpa.me/2017/06/12/hong-kong-open-data-from-zero-to-giveup/</id>
<published>2017-06-12T13:36:00.000Z</published>
<updated>2017-06-12T15:04:41.000Z</updated>
<content type="html"><![CDATA[<h2 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h2><p>經過 2017 年香港開源年會之後,我都沒有去看香港的開放數據做得怎麼樣。今天香港正懸掛八號風球,正好是一個機會去了解一下。香港政府有一個開放數據平台,<a href="https://data.gov.hk/tc-data/dataset" rel="external nofollow noopener noreferrer" target="_blank">資料一線通</a>,以多種檔案格式提供多個政府部門類別,機構的一些查詢資料,比如說天氣預報,中學教育統計資料。值得注意的是,這些檔案並不是 ODF,而是 xls, xml, csv, json, gif, txt, tif。。。</p><h2 id="使用-API"><a href="#使用-API" class="headerlink" title="使用 API"></a>使用 API</h2><p>第一眼看到的時候,我就想可不可以直接複製貼上測試一下,結果發現是不行的。。。</p><img class="lozad" data-src="https://i.imgur.com/cwI9gp7.png" width="600" title="auto"><p>“歷史檔案文件列表應用程式界面” 其實這個名字會不會有點長,我在閱讀下文的時候看到這麼長的字也很難聯想到剛才有看過。而且如果直接在瀏覽器輸入第一句的話,只會返回 400 Bad Request。。。<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line">{</div><div class="line"> "message" : "REQUEST ERROR: start parameter missing"</div><div class="line">}</div></pre></td></tr></table></figure></p><h2 id="香港天文台提供的數據"><a href="#香港天文台提供的數據" class="headerlink" title="香港天文台提供的數據"></a>香港天文台提供的數據</h2><p>如果想要獲取香港天文台在平台上,2016年1月1日到1月2日的開放資料,就可以輸入這一句到命令行里:<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">curl https://api.data.gov.hk/v1/historical-archive/list-files?start=20160101&end=20160102&provider=hk-hko</div></pre></td></tr></table></figure></p><p>返回的結果太長,prettify 後的檔案更加是高達 362 行。。。</p><p>有興趣的話,你可以透過<a href="https://gist.github.com/calpa/11b75ce631d9a3809e17fb6b9ed15d6b" rel="external nofollow noopener noreferrer" target="_blank">這個鏈接</a>看一下。。。</p><p>這個看起來不錯,有很多東西在裡面。但是,你可能會發現數據結構有點奇怪,一個數組去儲存所有的資料,這裡我就不展開了。</p><p>如果看到最後,你就會發現 <strong>file-count</strong> 提供文檔總數,其實直接計算一下 <strong>file</strong> 的長度就可以了,上面的例子共有21份文檔。<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line">file.length <span class="comment">// 21</span></div><div class="line">file-count <span class="comment">// 21</span></div></pre></td></tr></table></figure></p><img class="lozad" data-src="https://i.imgur.com/Hik48CC.png" width="600" title="auto 香港天文台開放數據"><center>香港天文台開放數據網頁</center><p>你可以進去下載數據,比如說進入<a href="http://rss.weather.gov.hk/rss/CurrentWeather_uc.xml" rel="external nofollow noopener noreferrer" target="_blank">本港地區天氣報告</a>,但你會發現它把最重要的資料放了在 description 裡面,用一個 tr, td, td 的形式展現出來,這就不如你用 HTML 展現吧。。。</p><h2 id="XML"><a href="#XML" class="headerlink" title="XML"></a>XML</h2><blockquote><p>與許多HTML元素不同的是,XML元素的基礎是其功能,而非其格式。你不應該根據標記,就假定任何的格式或樣式。相反地, XML把版面配置留給樣規。樣規是獨立的文件,把元素配上樣式。</p></blockquote><p>如果寫 XML 的話,最重要是把資料都顯示出來,格式都是其次的。在 XML 中,我們可以自由地定義標籤,充分地表達自己的意思。也許,我應該之後寫一篇關於 XML 的文章。。。</p><p>本來,我是想繼續寫的,但是看到那些莫名其妙的查詢方法,以及查詢的<a href="https://data.gov.hk/tc-data/provider/hk-hko" rel="external nofollow noopener noreferrer" target="_blank">香港天文台開放數據網頁</a>都只有 xml 格式,我就簡短寫一下就算了。</p><p>如果你好奇為什麼我會提到 ODF 的話,你可以去看一下台灣政府是<a href="https://onepiece.nchu.edu.tw/cofsys/plsql/odf" rel="external nofollow noopener noreferrer" target="_blank">如何推動開放數據</a>。</p><h2 id="題外話"><a href="#題外話" class="headerlink" title="題外話"></a>題外話</h2><p>我也不知道為什麼<a href="http://www.ceo.gov.hk/chi/blog/rss/blog_rss.xml" rel="external nofollow noopener noreferrer" target="_blank">特首博客的RSS</a>會報錯。。。</p><h2 id="參考資料"><a href="#參考資料" class="headerlink" title="參考資料"></a>參考資料</h2><ol><li><a href="https://onepiece.nchu.edu.tw/cofsys/plsql/odf" rel="external nofollow noopener noreferrer" target="_blank">ODF 政府文件標準格式宣導</a></li><li><a href="http://yes.nctu.edu.tw/lecture/web/xml/intro/chapter1.html" rel="external nofollow noopener noreferrer" target="_blank">國立交通大學 XML教學</a></li></ol>]]></content>
<summary type="html">
<h2 id="前言"><a href="#前言" class="headerlink" title="前言"></a>前言</h2><p>經過 2017 年香港開源年會之後,我都沒有去看香港的開放數據做得怎麼樣。今天香港正懸掛八號風球,正好是一個機會去了解一下。香港政府有一個開
</summary>
<category term="API" scheme="https://calpa.me/Tags/API/"/>
<category term="xml" scheme="https://calpa.me/Tags/xml/"/>
</entry>
<entry>
<title>5分鐘製作 Markdown PowerPoint</title>
<link href="https://calpa.me/2017/06/01/create-markdown-powerpoint-in-5-mins/"/>
<id>https://calpa.me/2017/06/01/create-markdown-powerpoint-in-5-mins/</id>
<published>2017-06-01T09:00:00.000Z</published>
<updated>2017-06-06T16:27:26.000Z</updated>
<content type="html"><![CDATA[<iframe width="100%" height="515" src="https://gitpitch.com/calpa/slides/master?grs=github&t=white" frameborder="0" allowfullscreen></iframe><h2 id="關於我"><a href="#關於我" class="headerlink" title="關於我"></a>關於我</h2><ul><li>自學 <span style=" color: #f48024">Web</span> 前端程序員</li><li>香港科技大學化學工程三年級學生</li><li>曾經參加過 6次 Hackathon</li><li>技術博客: <a href="https://calpa.me">https://calpa.me</a></li></ul><h2 id="以前製作-PowerPoint-的方法"><a href="#以前製作-PowerPoint-的方法" class="headerlink" title="以前製作 PowerPoint 的方法"></a>以前製作 PowerPoint 的方法</h2><p>Microsoft PowerPoint</p><p>Apache OpenOffice Impress</p><h2 id="Git-Pitch"><a href="#Git-Pitch" class="headerlink" title="Git Pitch"></a><span style="letter-spacing: 0.1em; color: #e49436; text-transform:none">Git</span> Pitch</h2><h2 id="前置技能"><a href="#前置技能" class="headerlink" title="前置技能"></a>前置技能</h2><ul><li>Github</li><li>Markdown</li></ul><h4 id="Github"><a href="#Github" class="headerlink" title="Github"></a>Github</h4><p><img class="lozad" data-src="https://i.imgur.com/Riz9ctd.png" height="200" width="200"></p><h4 id="Markdown"><a href="#Markdown" class="headerlink" title="Markdown"></a>Markdown</h4><h4 id="Markdown語法"><a href="#Markdown語法" class="headerlink" title="Markdown語法"></a>Markdown語法</h4><h5 id="標題"><a href="#標題" class="headerlink" title="標題"></a>標題</h5><figure class="highlight markdown"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div></pre></td><td class="code"><pre><div class="line"><span class="section"># h1</span></div><div class="line"><span class="section">## h2</span></div><div class="line"><span class="section">### h3</span></div><div class="line"><span class="section">#### h4</span></div><div class="line"><span class="section">##### h5</span></div></pre></td></tr></table></figure><h2 id="4個步驟"><a href="#4個步驟" class="headerlink" title="4個步驟"></a>4個步驟</h2><p><img class="lozad" data-src="https://i.imgur.com/HqSHVOy.png" alt="Imgur"></p><p><img class="lozad" data-src="https://i.imgur.com/ZwDgHFr.png" alt="Imgur"></p><p><img class="lozad" data-src="https://i.imgur.com/RLV4Ut0.png" alt="Imgur"></p><p><img class="lozad" data-src="https://i.imgur.com/uOoSrMa.png" alt="Imgur"></p><h3 id="GitPitch-Slideshow-URL"><a href="#GitPitch-Slideshow-URL" class="headerlink" title="GitPitch Slideshow URL"></a>GitPitch Slideshow URL</h3><p><a href="https://gitpitch.com/user/repo" rel="external nofollow noopener noreferrer" target="_blank">https://gitpitch.com/user/repo</a></p><p><img class="lozad" data-src="https://calpa.me/img/qrcode.png" height="200" width="200"></p>]]></content>
<summary type="html">
<iframe width="100%" height="515" src="https://gitpitch.com/calpa/slides/master?grs=github&t=white" frameborder="0" allowfullscreen></iframe
</summary>
<category term="Markdown" scheme="https://calpa.me/Tags/Markdown/"/>
</entry>
<entry>
<title>JavaScript Array.map(parseInt) 錯誤解決方案</title>
<link href="https://calpa.me/2017/05/31/javascript-array-map-parseint-solutions/"/>
<id>https://calpa.me/2017/05/31/javascript-array-map-parseint-solutions/</id>
<published>2017-05-31T03:06:00.000Z</published>
<updated>2017-07-13T23:11:43.000Z</updated>
<content type="html"><![CDATA[<p>如果我想轉換數組裡面的字符串為數字的話,很自然就會想到 <code>map</code> 和 <code>parseInt</code> 這兩個方法。但是用起來的時候卻不是我想要的結果。。。</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">var</span> a = [<span class="string">"1"</span>, <span class="string">"2"</span>, <span class="string">"3"</span>, <span class="string">"4"</span>, <span class="string">"5"</span>];</div><div class="line"></div><div class="line"><span class="keyword">var</span> b = a.map(<span class="built_in">parseInt</span>);</div><div class="line"></div><div class="line"><span class="built_in">console</span>.log(b); <span class="comment">// [1, NaN, NaN, NaN, NaN]</span></div></pre></td></tr></table></figure><h2 id="原因"><a href="#原因" class="headerlink" title="原因"></a>原因</h2><p>如果我們細看 map 的參數,就會發現它的 callback 會有三個 arguments:<code>currentValue</code>, <code>index</code> 和 <code>array</code>。</p><p>對於 <code>parseInt</code> 來說, 它會接收<code>currentValue</code>和 <code>index</code>,並用 index 作為 index 進制。。。<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div></pre></td><td class="code"><pre><div class="line"><span class="built_in">parseInt</span>(<span class="string">'1'</span>, <span class="number">0</span>); <span class="comment">// OK => 1</span></div><div class="line"><span class="built_in">parseInt</span>(<span class="string">'2'</span>, <span class="number">1</span>); <span class="comment">// 不合法的進制。。。</span></div><div class="line"><span class="built_in">parseInt</span>(<span class="string">'3'</span>, <span class="number">2</span>); <span class="comment">// NaN, 二進制沒有 3</span></div><div class="line"><span class="built_in">parseInt</span>(<span class="string">'4'</span>, <span class="number">3</span>); <span class="comment">// NaN, 三進制沒有 4</span></div><div class="line"><span class="built_in">parseInt</span>(<span class="string">'5'</span>, <span class="number">4</span>); <span class="comment">// NaN, 四進制沒有 5</span></div></pre></td></tr></table></figure></p><h2 id="解決方法"><a href="#解決方法" class="headerlink" title="解決方法"></a>解決方法</h2><ol><li><p>用<code>.map(parseFloat)</code>,因為它只接收一個參數。</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">var</span> c = a.map(<span class="built_in">parseFloat</span>);</div></pre></td></tr></table></figure></li><li><p>用<code>.map(Number)</code></p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">var</span> d = a.map(<span class="built_in">Number</span>);</div></pre></td></tr></table></figure></li><li><p>用<code>.map(num => parseInt(num))</code></p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">var</span> e = a.map(<span class="function"><span class="params">num</span> =></span> <span class="built_in">parseInt</span>(num));</div></pre></td></tr></table></figure></li></ol>]]></content>
<summary type="html">
<p>如果我想轉換數組裡面的字符串為數字的話,很自然就會想到 <code>map</code> 和 <code>parseInt</code> 這兩個方法。但是用起來的時候卻不是我想要的結果。。。</p>
<figure class="highlight javascript">
</summary>
<category term="JavaScript" scheme="https://calpa.me/Tags/JavaScript/"/>
</entry>
<entry>
<title>為什麼要寫技術博客?</title>
<link href="https://calpa.me/2017/05/30/why-i-write-blog-posts/"/>
<id>https://calpa.me/2017/05/30/why-i-write-blog-posts/</id>
<published>2017-05-30T12:00:00.000Z</published>
<updated>2017-05-30T14:26:17.000Z</updated>
<content type="html"><![CDATA[<p>從第一篇<a href="https://calpa.me/2017/01/08/hello-world/">《Hello World》</a>文章,我已經開始寫博客半年了,一共寫三十多篇,平均一個禮拜出一篇文章。其實,我沒有想那麼多,直接就開始寫文章了。可能我的博客沒有其他人寫得那麼好,但是我依然堅持寫博客。每一篇文章是需要一點時間構思、撰寫,但是這點時間是很值得的。</p><h2 id="原因"><a href="#原因" class="headerlink" title="原因"></a>原因</h2><ol><li><p>重用問題解決方案<br>我們在寫代碼的時候,經常會遇到一些問題,不是那麼容易直接去解決,每次都是用同樣,或差不多的解決方法。如果每一次去 Google 這些問題,就會顯得有點浪費時間了。透過博客記錄下來,我們可以很方便地讓自己重用這些方案,同時讓別人避免造同樣的輪子。</p></li><li><p>學習知識</p><p>分享是學習知識的其中一種好方法。透過分享知識,我們可以整理碎片化的知識,並把它組合起來成為一篇文章。如果有小夥伴指出那篇文章的問題,大家可以交流一下,互相提升技術水平。</p></li><li><p>整理思維</p><p>作為一個 Web 前端程序員,經常會接觸網絡上日新月異的工具,知識。如果可以整理他們出來,就可以更好地讓自己摸清脈絡,對他們有更好的認識。</p></li><li><p>了解自己</p><p>就如同寫日記一樣,寫博客是一個不錯的方法去尋找自己的路。我們可能會有很多的興趣,但只有一樣或數樣是真愛。如果把自己的興趣和學習的歷程寫下來,就會知道什麼才是自己持之以恆想做的事情,自己的熱情在哪裡。</p></li><li><p>認識不同的讀者</p><p>如果博客可以吸引讀者,這就代表文章的質量開始上升。透過與不同的人交流,學習不同的思想。寫著寫著博客文章,我開始和國內,台灣的程序員打開了溝通的渠道,博客也有開始有來自世界各地,包括日本,美國的讀者。</p></li></ol><h2 id="最初的動機"><a href="#最初的動機" class="headerlink" title="最初的動機"></a>最初的動機</h2><p>以前看到一些大牛經常發文,我就想:可不可以有一天我也可以發文呢?一開始我是打算把自己看到的好文章節錄出來,以及記錄自己遇到的坑,然後讓自己日後重用。沒有想到的是,那篇<a href="https://calpa.me/2017/05/21/learn-javascript-in-six-steps/">《打好 JavaScript 的6個步驟》</a>會為博客在兩日之內帶來 2000 多的流量,讓我感到有點高興。今後應該會繼續寫博客,記錄一下自己學了什麼。</p>]]></content>
<summary type="html">
<p>從第一篇<a href="https://calpa.me/2017/01/08/hello-world/">《Hello World》</a>文章,我已經開始寫博客半年了,一共寫三十多篇,平均一個禮拜出一篇文章。其實,我沒有想那麼多,直接就開始寫文章了。可能我的博客沒有其
</summary>
<category term="Blog" scheme="https://calpa.me/Tags/Blog/"/>
</entry>
<entry>
<title>打好 JavaScript 基礎的6個步驟</title>
<link href="https://calpa.me/2017/05/21/learn-javascript-in-six-steps/"/>
<id>https://calpa.me/2017/05/21/learn-javascript-in-six-steps/</id>
<published>2017-05-21T12:00:00.000Z</published>
<updated>2017-07-02T14:15:29.000Z</updated>
<content type="html"><![CDATA[<p>平日開發的時候,我們會選擇使用一些框架來避免重複製造輪子,減輕我們的工作量。然而,我們卻不能透過使用更好的工具,或者更換框架來解決一些基礎開發問題。因此打好基礎很重要,不但決定前端程序員解決基礎問題的能力,還決定了面對日新月異框架時的掌握能力。當我開發 React 應用的時候,遇到的問題多是我對於 JavaScript 的理解不夠充分。因此,我在這裡寫一下如何打好 JavaScript 基礎,希望拋磚引玉 XD</p><ol><li><p>看一些經典的書<br>JavaScript: 紅寶書 (JavaScript高級程序設計),犀牛書 (JavaScript: The Definitive Guide),You Don’t Know JS<br>計算機經典: 算法導論,SICP</p><img class="lozad" data-src="https://i.imgur.com/xm6R14W.jpg" width="300" title="JavaScript高級程序設計"><img class="lozad" data-src="https://i.imgur.com/autEZuV.jpg" width="300" title="JavaScript: The Definitive Guide"><img class="lozad" data-src="https://i.imgur.com/ajLLsUg.gif" width="300" title="You Don" alt="t Know JS"></li><li><p>嘗試用不同的工具,增加自己的視野。<br>你可以做一些玩具,自己嘗試一下寫TODO APP 的不同寫法。</p></li><li><p>看工具的源碼:React, Vue, Underscore.js<br>這些開源項目的代碼都已經放在 Github,網絡上也有對它們的源碼分析,隨便一找就有了。透過閱讀代碼,可以學習一下代碼規範,理解什麼才是好的代碼。</p></li><li><p>自己把這些工具、框架的某些功能做出來。<br>你可以實現<a href="http://underscorejs.org/" rel="external nofollow noopener noreferrer" target="_blank">Underscore.js</a>裡面的一些方法,例如<code>_.uniq(array, [isSorted], [iteratee])</code> 數組去重方法,然後看一下自己和人家寫得有什麼分別,為什麼人家會這樣寫?它有運用到什麼設計模式?</p></li><li><p>看ECMAScript規範。<br>你可以閱讀<a href="https://tc39.github.io/ecma262" rel="external nofollow noopener noreferrer" target="_blank">ECMAScript 規範</a>,人家對於不同的數據類型和函數是怎樣定義的,思考一下為什麼需要這樣定義,為什麼不這樣定義。<br>為什麼<code>typeof null</code>會是<code>object</code>?不定義為<code>null</code>?</p></li><li><p>記錄你學了什麼知識並分享。<br>記錄一下自己學習了什麼知識,遇到了什麼坑。透過和其他人交流一下,可以了解到自己有什麼不足之處。其中一個方法是利用 Hexo 建立博客,可以透過修改主題練習HTML, JavaScript, CSS。我也是這樣寫博客的:<a href="https://calpa.me">https://calpa.me</a></p></li></ol><p>這裡就作為我的一個學習小總結,不繼續展開了。。。</p>]]></content>
<summary type="html">
<p>平日開發的時候,我們會選擇使用一些框架來避免重複製造輪子,減輕我們的工作量。然而,我們卻不能透過使用更好的工具,或者更換框架來解決一些基礎開發問題。因此打好基礎很重要,不但決定前端程序員解決基礎問題的能力,還決定了面對日新月異框架時的掌握能力。當我開發 React 應用的時
</summary>
<category term="JavaScript" scheme="https://calpa.me/Tags/JavaScript/"/>
</entry>
<entry>
<title>利用 ECMAScript 学习如何判断数据类型</title>
<link href="https://calpa.me/2017/05/18/javascript-data-structures/"/>
<id>https://calpa.me/2017/05/18/javascript-data-structures/</id>
<published>2017-05-18T06:00:00.000Z</published>
<updated>2017-05-18T06:08:33.000Z</updated>
<content type="html"><![CDATA[<p>每一种编程语言都有数据结构,但他们各有不同之处。JavaScript 是一种动态语言,变量的类型不用提前声明,你可以使用同一个变量来保存不同的数据类型。<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">var</span> a = <span class="string">'apple'</span>; <span class="comment">// String type</span></div><div class="line"><span class="keyword">var</span> a = <span class="number">42</span>; <span class="comment">// Number type</span></div><div class="line"><span class="keyword">var</span> a = <span class="literal">true</span>; <span class="comment">// Boolean type</span></div></pre></td></tr></table></figure></p><p>这就和Python的写法差不多:<br><figure class="highlight python"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line">a = <span class="string">'apple'</span> // String type</div><div class="line">a = <span class="number">42</span> // Number type</div><div class="line">a = <span class="keyword">True</span> // Boolean type</div></pre></td></tr></table></figure></p><h2 id="数据类型"><a href="#数据类型" class="headerlink" title="数据类型"></a>数据类型</h2><p><a href="https://tc39.github.io/ecma262/#sec-ecmascript-overview" rel="external nofollow noopener noreferrer" target="_blank">ECMAScript 标準</a>明确定义了7种数据类型:6种原始类型 (Primitive value) 和Object。</p><img class="lozad" data-src="/img/javascript-data-structures.svg" width="300" title="auto JavaScript Data Structure"><p>原始数据类型:</p><ol><li>Undefined</li><li>Null</li><li>Boolean</li><li>Number</li><li>String</li><li>Symbol (ECMAScript 2015)</li></ol><h2 id="判断方法"><a href="#判断方法" class="headerlink" title="判断方法"></a>判断方法</h2><p>我们可以透过使用<code>typeof</code>和<code>Object.prototype.toString()</code>来判断数据类型。</p><h3 id="typeof"><a href="#typeof" class="headerlink" title="typeof"></a>typeof</h3><p>在一开始设计 JavaScript 时,数值是由一个标签以及实际数据值表示的。对于基本类型,标签是1;而对于对象类型,标签是0。由于null代表的是空指针(里面都是0),null的类型标签会是0。因此<code>typeof null</code>就会返回”object”;</p><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">typeof</span> <span class="literal">undefined</span>; <span class="comment">// "undefined"</span></div><div class="line"><span class="keyword">typeof</span> <span class="built_in">Boolean</span>; <span class="comment">// "function"</span></div><div class="line"><span class="keyword">typeof</span> <span class="literal">true</span>; <span class="comment">// "boolean"</span></div><div class="line"><span class="keyword">typeof</span> <span class="number">42</span>; <span class="comment">// "number"</span></div><div class="line"><span class="keyword">typeof</span> <span class="string">"42"</span>; <span class="comment">// "string"</span></div><div class="line"><span class="keyword">typeof</span> <span class="built_in">Symbol</span>(); <span class="comment">// "symbol"</span></div></pre></td></tr></table></figure><p>我们可以看一下ECMAScript是怎样定义typeof的:</p><ol><li>Let val be the result of evaluating UnaryExpression.</li><li>If Type(val) is Reference, then<br>a. If IsUnresolvableReference(val) is true, return “undefined”.</li><li>Set val to ? GetValue(val).</li><li>Return a String according to Table 35.</li></ol><p>Table 35: typeof Operator Results</p><table><thead><tr><th style="text-align:left">Typeof val</th><th style="text-align:left">结果</th></tr></thead><tbody><tr><td style="text-align:left">Item One</td><td style="text-align:left">Item Two</td></tr><tr><td style="text-align:left">Type of val</td><td style="text-align:left">Result</td></tr><tr><td style="text-align:left">Undefined</td><td style="text-align:left">“undefined”</td></tr><tr><td style="text-align:left">Null</td><td style="text-align:left">“object”</td></tr><tr><td style="text-align:left">Boolean</td><td style="text-align:left">“boolean”</td></tr><tr><td style="text-align:left">Number</td><td style="text-align:left">“number”</td></tr><tr><td style="text-align:left">String</td><td style="text-align:left">“string”</td></tr><tr><td style="text-align:left">Symbol</td><td style="text-align:left">“symbol”</td></tr><tr><td style="text-align:left">Object (ordinary and does not implement [[Call]])</td><td style="text-align:left">“object”</td></tr><tr><td style="text-align:left">Object (standard exotic and does not implement [[Call]])</td><td style="text-align:left">“object”</td></tr><tr><td style="text-align:left">Object (implements [[Call]])</td><td style="text-align:left">“function”</td></tr><tr><td style="text-align:left">Object (non-standard exotic and does not implement [[Call]])</td><td style="text-align:left">Implementation-defined. Must not be “undefined”, “boolean”, “function”, “number”, “symbol”, or “string”.</td></tr></tbody></table><p>另外,如果直接用<code>typeof</code>来判断 NaN 的话,它会返回<code>"number"</code>,对于 NaN 我们可以用<code>isNaN</code>方法来判断是否一个数字。<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">typeof</span> <span class="literal">NaN</span>; <span class="comment">// "number"</span></div><div class="line"><span class="built_in">isNaN</span>(<span class="literal">NaN</span>); <span class="comment">// true</span></div></pre></td></tr></table></figure></p><h3 id="Object-prototype-toString"><a href="#Object-prototype-toString" class="headerlink" title="Object.prototype.toString()"></a>Object.prototype.toString()</h3><p>我们可以利用<code>Object.prototype.toString.call()</code>或者<code>Object.prototype.toString.apply()</code>这两个方法判断 Object 的类型,以及 null:<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div></pre></td><td class="code"><pre><div class="line"><span class="built_in">Object</span>.prototype.toString.call(<span class="literal">undefined</span>); <span class="comment">// "[object Undefined]"</span></div><div class="line"><span class="built_in">Object</span>.prototype.toString.call(<span class="keyword">new</span> <span class="built_in">Date</span>); <span class="comment">// "[object Date]"</span></div><div class="line"><span class="built_in">Object</span>.prototype.toString.call(<span class="keyword">new</span> <span class="built_in">String</span>); <span class="comment">// "[object String]"</span></div><div class="line"><span class="built_in">Object</span>.prototype.toString.call(<span class="built_in">Math</span>); <span class="comment">// "[object Math]"</span></div><div class="line"><span class="built_in">Object</span>.prototype.toString.call(<span class="literal">null</span>); <span class="comment">// "[object Null]"</span></div></pre></td></tr></table></figure></p><p>ECMAScript 19.1.3.6 明确定义 Object.prototype.toString():</p><ol><li>If the <code>this</code> value is <code>undefined</code>, return <code>"[object Undefined]"</code>.</li><li>If the <code>this</code> value is <code>null</code>, return <code>"[object Null]"</code>.</li><li>Let <code>O</code> be ! <a href="https://tc39.github.io/ecma262/#sec-toobject" rel="external nofollow noopener noreferrer" target="_blank">ToObject</a>(<code>this</code> value).</li><li>Let <code>isArray</code> be ? <a href="https://tc39.github.io/ecma262/#sec-isarray" rel="external nofollow noopener noreferrer" target="_blank">IsArray</a>(<code>O</code>).</li><li>If <code>isArray</code> is <code>true</code>, let <code>builtinTag</code> be <code>"Array"</code>.</li><li>Else if <code>O</code> is a String exotic object, let <code>builtinTag</code> be <code>"String"</code>.</li><li>Else if <code>O</code> has a [[ParameterMap]] internal slot, let <code>builtinTag</code> be <code>"Arguments"</code>.</li><li>Else if <code>O</code> has a [[Call]] internal method, let <code>builtinTag</code> be <code>"Function"</code>.</li><li>Else if <code>O</code> has an [[ErrorData]] internal slot, let <code>builtinTag</code> be <code>"Error"</code>.</li><li>Else if <code>O</code> has a [[BooleanData]] internal slot, let <code>builtinTag</code> be <code>"Boolean"</code>.</li><li>Else if <code>O</code> has a [[NumberData]] internal slot, let <code>builtinTag</code> be <code>"Number"</code>.</li><li>Else if <code>O</code> has a [[DateValue]] internal slot, let <code>builtinTag</code> be <code>"Date"</code>.</li><li>Else if <code>O</code> has a [[RegExpMatcher]] internal slot, let <code>builtinTag</code> be <code>"RegExp"</code>.</li><li>Else, let <code>builtinTag</code> be <code>"Object"</code>.</li><li>Let <code>tag</code> be ? <a href="https://tc39.github.io/ecma262/#sec-get-o-p" rel="external nofollow noopener noreferrer" target="_blank">Get</a>(<code>O</code>, @@toStringTag).</li><li>If <a href="https://tc39.github.io/ecma262/#sec-ecmascript-data-types-and-values" rel="external nofollow noopener noreferrer" target="_blank">Type</a>(<code>tag</code>) is not String, let <code>tag</code> be <code>builtinTag</code>.</li><li>Return the String that is the result of concatenating <code>"[object "</code>, <code>tag</code>, and <code>"]"</code>.</li></ol><h2 id="参考资料"><a href="#参考资料" class="headerlink" title="参考资料"></a>参考资料</h2><ol><li><a href="https://tc39.github.io/ecma262/#sec-ecmascript-overview" rel="external nofollow noopener noreferrer" target="_blank">ECMAScript® 2018 Language Specification</a></li></ol>]]></content>
<summary type="html">
<p>每一种编程语言都有数据结构,但他们各有不同之处。JavaScript 是一种动态语言,变量的类型不用提前声明,你可以使用同一个变量来保存不同的数据类型。<br><figure class="highlight javascript"><table><tr><td class
</summary>
<category term="JavaScript" scheme="https://calpa.me/Tags/JavaScript/"/>
<category term="ECMAScript" scheme="https://calpa.me/Tags/ECMAScript/"/>
</entry>
<entry>
<title>React 組件生命週期 - 加載組件</title>
<link href="https://calpa.me/2017/05/16/react-component-lifecycle/"/>
<id>https://calpa.me/2017/05/16/react-component-lifecycle/</id>
<published>2017-05-16T14:40:00.000Z</published>
<updated>2017-05-18T06:07:19.000Z</updated>
<content type="html"><![CDATA[<h2 id="組件"><a href="#組件" class="headerlink" title="組件"></a>組件</h2><p><code>React</code>提供<code>React.Component</code>,我們可以透過使用組件,拆分UI為可以重複使用的獨立部分。<code>React.Component</code>是一個抽象的base class。我們甚少直接運用<code>React.Component</code>,通常是透過創建一個子類,並使用<code>render()</code>方法。</p><p>例子:<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div></pre></td><td class="code"><pre><div class="line"><span class="class"><span class="keyword">class</span> <span class="title">Greeting</span> <span class="keyword">extends</span> <span class="title">React</span>.<span class="title">Component</span> </span>{</div><div class="line"> render() {</div><div class="line"> <span class="keyword">return</span> <h1>Hello, {this.props.name}</h1>;</div><div class="line"> }</div><div class="line">}</div></pre></td></tr></table></figure></p><p>如果你不選擇使用ES6,你可以使用模組<code>create-react-class</code>。你可以參考<a href="https://facebook.github.io/react/docs/react-without-es6.html" rel="external nofollow noopener noreferrer" target="_blank">React Without ES6</a>。<br>下面這一段和ES6的寫法效果一樣:<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">var</span> createReactClass = <span class="built_in">require</span>(<span class="string">'create-react-class'</span>);</div><div class="line"><span class="keyword">var</span> Greeting = createReactClass({</div><div class="line"> render: <span class="function"><span class="keyword">function</span>(<span class="params"></span>) </span>{</div><div class="line"> <span class="keyword">return</span> <h1>Hello, {this.props.name}</h1>;</div><div class="line"> }</div><div class="line">});</div></pre></td></tr></table></figure></p><h2 id="組件生命週期"><a href="#組件生命週期" class="headerlink" title="組件生命週期"></a>組件生命週期</h2><p>每一個組件都會有幾個生命週期的方法,你可以在程序運行的指定時間,透過覆蓋他們來運行特定代碼。對於這些方法,我們會用<code>will-</code>來表示它會在某些事情發生之前的一刻被調用,而<code>did-</code>則是表示它會在某些事情發生之後的一刻被調用。本文會細說加載組件中發生了什麼事情。</p><h3 id="加載-Mounting"><a href="#加載-Mounting" class="headerlink" title="加載 (Mounting)"></a>加載 (Mounting)</h3><ol><li><code>constructor()</code></li><li><code>componentWillMount()</code></li><li><code>render()</code></li><li><code>componentDidMount()</code></li></ol><h3 id="更新-Updating"><a href="#更新-Updating" class="headerlink" title="更新 (Updating)"></a>更新 (Updating)</h3><p>當 props 或者 state 更新的時候,下面這些方法會被調用:</p><ol><li>componentWillReceiveProps()</li><li>shouldComponentUpdate()</li><li>componentWillUpdate()</li><li>render()</li><li>componentDidUpdate()</li></ol><h3 id="斷開連接-Unmounting"><a href="#斷開連接-Unmounting" class="headerlink" title="斷開連接 (Unmounting)"></a>斷開連接 (Unmounting)</h3><p>當組件脫離DOM的時候,下面這個方法回被調用:</p><ol><li>componentWillUnmount()</li></ol><h3 id="其他內置方法"><a href="#其他內置方法" class="headerlink" title="其他內置方法"></a>其他內置方法</h3><ol><li>setState()</li><li>forceUpdate()</li></ol><p>我們會在下文討論一下React是如何加載組件。</p><img class="lozad" data-src="/img/react-mount.svg" width="300" title="auto React LifeCycle Mount"><h4 id="constructor-NaN"><a href="#constructor-NaN" class="headerlink" title="constructor()"></a>constructor()</h4><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">constructor</span>(props)</div></pre></td></tr></table></figure><p>在React加載組件之前,它會調用<code>constructor</code>。你可以在<code>constructor</code>中去賦予組件的初始<code>state</code>。如果你使用<code>props</code>創造初始<code>state</code>的話,這也是可以接受的。這會很有效地<code>fork</code>組件的<code>props</code>,然後賦予初始<code>state</code>的值。</p><p>有效的<code>constructor</code>例子:<br><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">constructor</span>(props) {</div><div class="line"> <span class="keyword">super</span>(props);</div><div class="line"> <span class="keyword">this</span>.state = {</div><div class="line"> color: props.initialColor</div><div class="line"> };</div><div class="line">}</div></pre></td></tr></table></figure></p><h5 id="注意事項"><a href="#注意事項" class="headerlink" title="注意事項"></a>注意事項</h5><ol><li>如果你不需要賦予初始<code>state</code>,你不需要在 React 的組件中植入<code>constructor</code>。</li><li>當你使用在<code>React.Component</code>的子類中加載<code>constructor()</code>方法時,你應該第一時間調用<code>super(props)</code>,而不是在任何statement之後。不然,我們獲取<code>this.props</code>值的時候,它會是<code>undefined</code>。</li><li>在一些類似上面的例子,<code>state</code>未必會及時與任何的<code>props</code>更新。如果你需要同步<code>state</code>的話,你其實是想要<a href="https://facebook.github.io/react/docs/lifting-state-up.html" rel="external nofollow noopener noreferrer" target="_blank">lift the state up</a>。</li></ol><h4 id="componentWillMount"><a href="#componentWillMount" class="headerlink" title="componentWillMount()"></a>componentWillMount()</h4><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">componentWillMount()</div></pre></td></tr></table></figure><p>它會在組件<code>render()</code>之前執行一次,然後不能再執行。如果在這裡定義了<code>setState</code>方法,頁面只會在加載之前更新一次,不會重複渲染。React 官方推薦使用<code>constructor()</code>代替這個方法。</p><h4 id="render"><a href="#render" class="headerlink" title="render()"></a>render()</h4><p><code>React.Component</code>必須有這個方法,即使你返回<code>null</code>,或者<code>false</code>。當你返回<code>null</code>,或者<code>false</code>的時候,<code>ReactDOM.findDOMNode(this)</code> 會返回<code>null</code>。</p><p>當它被調用的時候,它會檢查<code>this.props</code>和<code>this.state</code>,然後返回一個單獨的 React 元素。這個元素會是一個純正的<code>DOM</code>組件,例如<div>,或者自定義的 composite 組件。</div></p><h5 id="注意事項-1"><a href="#注意事項-1" class="headerlink" title="注意事項"></a>注意事項</h5><ol><li><code>render()</code>方法應該是<code>pure</code>:它不會改寫任何組件的<code>state</code>。每一次調用它都會返回同樣的結果。它不會直接接觸到瀏覽器層面。</li><li>如果你需要接觸到瀏覽器層面,你應該在<code>componentDidMount()</code>或者其他生命週期方法中接觸瀏覽器。</li><li>保持<code>render()</code>方法 pure 來讓組件更加容易被人理解。</li></ol><h4 id="componentDidMount"><a href="#componentDidMount" class="headerlink" title="componentDidMount()"></a>componentDidMount()</h4><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">componentDidMount()</div></pre></td></tr></table></figure><p>它會在組件加載之後執行一次。如果你的初始程序需要DOM nodes,你應該在這裡寫。如果你需要從其他地方加載資料,這裡也是一個不錯的地方去執行網絡請求。如果在這裡定義了<code>setState</code>方法,會觸發重複渲染。</p><h4 id="測試代碼"><a href="#測試代碼" class="headerlink" title="測試代碼"></a>測試代碼</h4><figure class="highlight javascript"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div></pre></td><td class="code"><pre><div class="line"><span class="class"><span class="keyword">class</span> <span class="title">Greeting</span> <span class="keyword">extends</span> <span class="title">React</span>.<span class="title">Component</span> </span>{</div><div class="line"> _log(method, args) {</div><div class="line"> <span class="built_in">console</span>.log(method, args);</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="keyword">constructor</span>(props) {</div><div class="line"> <span class="keyword">super</span>(props);</div><div class="line"> <span class="built_in">console</span>.log(<span class="string">'constructor'</span>, props);</div><div class="line"> }</div><div class="line"></div><div class="line"> render() {</div><div class="line"> <span class="keyword">this</span>._log(<span class="string">'render'</span>, <span class="keyword">this</span>.props.name);</div><div class="line"> <span class="keyword">return</span> <h1>Hello, {this.props.name}</h1>;</div><div class="line"> }</div><div class="line"></div><div class="line"> componentWillMount() {</div><div class="line"> <span class="keyword">this</span>._log(<span class="string">'componentWillMount'</span>);</div><div class="line"> }</div><div class="line"></div><div class="line"> componentDidMount() {</div><div class="line"> <span class="keyword">this</span>._log(<span class="string">'componentDidMount'</span>);</div><div class="line"> }</div><div class="line">}</div><div class="line"></div><div class="line">ReactDOM.render(</div><div class="line"> <Greeting name=<span class="string">"Calpa"</span> />,</div><div class="line"> <span class="built_in">document</span>.getElementById(<span class="string">'app'</span>)</div><div class="line">);</div></pre></td></tr></table></figure><p>Console Output:<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div></pre></td><td class="code"><pre><div class="line">"constructor" Object {</div><div class="line"> name: "Calpa"</div><div class="line">}</div><div class="line">"componentWillMount" undefined</div><div class="line">"render" "Calpa"</div><div class="line">"componentDidMount" undefined</div></pre></td></tr></table></figure></p><p>你可以在<a href="https://codepen.io/calpa/full/xdJrQm/" rel="external nofollow noopener noreferrer" target="_blank">CodePen</a>中獲取,並測試這段代碼。</p><p>不知道拿哪一張當封面好。。。</p>]]></content>
<summary type="html">
<h2 id="組件"><a href="#組件" class="headerlink" title="組件"></a>組件</h2><p><code>React</code>提供<code>React.Component</code>,我們可以透過使用組件,拆分UI為可以重複使
</summary>
<category term="Web" scheme="https://calpa.me/Tags/Web/"/>
<category term="React" scheme="https://calpa.me/Tags/React/"/>
</entry>
<entry>
<title>初探正則表達式</title>
<link href="https://calpa.me/2017/05/06/introduction-to-regular-expression/"/>
<id>https://calpa.me/2017/05/06/introduction-to-regular-expression/</id>
<published>2017-05-06T12:13:00.000Z</published>
<updated>2017-05-18T06:07:19.000Z</updated>
<content type="html"><![CDATA[<p>正則表達式是一個非常簡單的語法,但它也是神兵利器,可以說是程序員必須要理解的工具之一。它就像一本會不斷成長的寶刀,隨著程序員對它的理解,它的威力也跟著增強。</p><p>一些當下熱門的編輯器(Atom, Sublime)或者 IDE (WebStorm)都支持正則表達式尋找。如果你有瞭解過JavaScript中的方法 (exec, test, match, search, replace, split)的話,做下面的題目時會更加得心應手。</p><h2 id="任務目的"><a href="#任務目的" class="headerlink" title="任務目的"></a>任務目的</h2><ol><li>掌握正則表達式編寫規則</li><li>瞭解正則表達式的特殊字元</li><li>瞭解JavaScript提供的正則表達式相關方法</li><li>能用正則表達式做一些簡單文本或者數字校驗</li></ol><h2 id="任務描述"><a href="#任務描述" class="headerlink" title="任務描述"></a>任務描述</h2><ol><li><p>編寫一個匹配URL的正則表達式,測試用例參照但不限於:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div></pre></td><td class="code"><pre><div class="line">https://calpa.me/2017/05/06/introduction-to-regular-expression/</div><div class="line">https://google.com</div><div class="line">https://github.com/leviding/T-Plan/blob/master/tasks/task0005/README.md</div><div class="line">http://blog.csdn.net/</div></pre></td></tr></table></figure></li><li><p>編寫一個驗證電子郵箱地址的正則表達式,測試用例參照但不限於:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line">[email protected]</div><div class="line">[email protected]</div></pre></td></tr></table></figure></li></ol><p>完成任務之後,可以對比別人的實現方案,但不建議未嘗試就直接搜索答案。<br>在正則表達式的世界中,一個問題往往不止一種方案,可以嘗試多種方法。</p><h2 id="提示"><a href="#提示" class="headerlink" title="提示"></a>提示</h2><p>你可以想利用一些工具,例如在線的正則表達式工具 (<a href="http://regexr.com/" rel="external nofollow noopener noreferrer" target="_blank">RegExr</a>, <a href="https://regex101.com/" rel="external nofollow noopener noreferrer" target="_blank">Regex101</a>)來幫助學習、編寫正則表達式。</p><h2 id="參考資料"><a href="#參考資料" class="headerlink" title="參考資料"></a>參考資料</h2><ol><li><a href="https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Guide/Regular_Expressions" rel="external nofollow noopener noreferrer" target="_blank">MDN Regular Expressions</a>: 瞭解JavaScript中正則表達式的基本知識</li></ol>]]></content>
<summary type="html">
<p>正則表達式是一個非常簡單的語法,但它也是神兵利器,可以說是程序員必須要理解的工具之一。它就像一本會不斷成長的寶刀,隨著程序員對它的理解,它的威力也跟著增強。</p>
<p>一些當下熱門的編輯器(Atom, Sublime)或者 IDE (WebStorm)都支持正則表達式尋
</summary>
<category term="JavaScript" scheme="https://calpa.me/Tags/JavaScript/"/>
<category term="Regular Expression" scheme="https://calpa.me/Tags/Regular-Expression/"/>
</entry>
<entry>
<title>CSS垂直置中的4種方法</title>
<link href="https://calpa.me/2017/05/06/vertical-align-with-css/"/>
<id>https://calpa.me/2017/05/06/vertical-align-with-css/</id>
<published>2017-05-06T04:59:00.000Z</published>
<updated>2017-05-06T06:33:18.000Z</updated>
<content type="html"><![CDATA[<p>這是一道送分題,如果想要垂直置中元素的話,起碼會有四種方法:<strong>padding</strong>, <strong>line-height</strong>, <strong>table</strong> 和 <strong>Flexbox</strong>。使用Flexbox的話,日後要更改元素的位置會非常方便。</p><h2 id="padding"><a href="#padding" class="headerlink" title="padding"></a>padding</h2><p>如果你要置中的元素是<code>inine</code>或者是<code>inline-*</code>的話,比如說文字和鏈接,你可以用<strong>padding</strong>來實現垂直置中:<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div></pre></td><td class="code"><pre><div class="line">.vCenter {</div><div class="line"> padding-top: 30px;</div><div class="line"> padding-bottom: 30px;</div><div class="line"> background: #eee;</div><div class="line"> text-align: center;</div><div class="line">}</div></pre></td></tr></table></figure></p><p>因為<code>padding-top</code>和<code>padding-bottom</code>的數值是一樣,所以我們可以透過這個方法來實現垂直置中。</p><iframe height="265" scrolling="no" title="padding 垂直置中" src="//codepen.io/calpa/embed/pPdowv/?height=265&theme-id=0&default-tab=css,result&embed-version=2" frameborder="no" allowtransparency="true" allowfullscreen="true" style="width: 100%;">See the Pen <a href="https://codepen.io/calpa/pen/pPdowv/" rel="external nofollow noopener noreferrer" target="_blank">padding 垂直置中</a> by Calpa Liu (<a href="http://codepen.io/calpa" rel="external nofollow noopener noreferrer" target="_blank">@calpa</a>) on <a href="http://codepen.io" rel="external nofollow noopener noreferrer" target="_blank">CodePen</a>.<br></iframe><h2 id="line-height"><a href="#line-height" class="headerlink" title="line-height"></a>line-height</h2><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div></pre></td><td class="code"><pre><div class="line">.anotherCenter {</div><div class="line"> height: 100px;</div><div class="line"> line-height: 100px;</div><div class="line"> background: #6cf;</div><div class="line"> text-align: center;</div><div class="line">}</div></pre></td></tr></table></figure><p>如果你不想用<code>padding</code>來實現垂直置中的話,你可以利用<code>line-height</code>等於<code>height</code>。</p><iframe height="265" scrolling="no" title="line-height 垂直置中" src="//codepen.io/calpa/embed/JNOjJJ/?height=265&theme-id=0&default-tab=css,result&embed-version=2" frameborder="no" allowtransparency="true" allowfullscreen="true" style="width: 100%;">See the Pen <a href="https://codepen.io/calpa/pen/JNOjJJ/" rel="external nofollow noopener noreferrer" target="_blank">line-height 垂直置中</a> by Calpa Liu (<a href="http://codepen.io/calpa" rel="external nofollow noopener noreferrer" target="_blank">@calpa</a>) on <a href="http://codepen.io" rel="external nofollow noopener noreferrer" target="_blank">CodePen</a>.<br></iframe><h2 id="table"><a href="#table" class="headerlink" title="table"></a>table</h2><p>你可以透過<code>valign</code>來控制位置。</p><p>另外,你可以利用<code>display: table-cell</code>來改變顯示的方式。<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div></pre></td><td class="code"><pre><div class="line">.fakeTable {</div><div class="line"> height: 200px;</div><div class="line"> width: 200px;</div><div class="line"> display: table-cell;</div><div class="line"> border: 1px solid black;</div><div class="line"> text-align: center;</div><div class="line"> vertical-align: middle;</div><div class="line">}</div></pre></td></tr></table></figure></p><iframe height="265" scrolling="no" title="Table 垂直置中" src="//codepen.io/calpa/embed/xdPxLr/?height=265&theme-id=0&default-tab=html,result&embed-version=2" frameborder="no" allowtransparency="true" allowfullscreen="true" style="width: 100%;">See the Pen <a href="http://codepen.io/calpa/pen/xdPxLr/" rel="external nofollow noopener noreferrer" target="_blank">Table 垂直置中</a> by Calpa Liu (<a href="http://codepen.io/calpa" rel="external nofollow noopener noreferrer" target="_blank">@calpa</a>) on <a href="http://codepen.io" rel="external nofollow noopener noreferrer" target="_blank">CodePen</a>.<br></iframe><h2 id="Flexbox"><a href="#Flexbox" class="headerlink" title="Flexbox"></a>Flexbox</h2><p>另外,你也可以使用<strong>Flexbox</strong>來實現垂直置中,只需要寫justify-content和align-items就可以了。<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div></pre></td><td class="code"><pre><div class="line">.vertical-center {</div><div class="line"> display: flex;</div><div class="line"> flex-direction: column;</div><div class="line"> justify-content: center;</div><div class="line"> align-items: center;</div><div class="line">}</div></pre></td></tr></table></figure></p><iframe height="265" scrolling="no" title="FlexBox 垂直置中" src="//codepen.io/calpa/embed/NjwWjV/?height=265&theme-id=0&default-tab=css,result&embed-version=2" frameborder="no" allowtransparency="true" allowfullscreen="true" style="width: 100%;">See the Pen <a href="https://codepen.io/calpa/pen/NjwWjV/" rel="external nofollow noopener noreferrer" target="_blank">FlexBox 垂直置中</a> by Calpa Liu (<a href="http://codepen.io/calpa" rel="external nofollow noopener noreferrer" target="_blank">@calpa</a>) on <a href="http://codepen.io" rel="external nofollow noopener noreferrer" target="_blank">CodePen</a>.<br></iframe><h2 id="延伸閱讀"><a href="#延伸閱讀" class="headerlink" title="延伸閱讀"></a>延伸閱讀</h2><ol><li><a href="https://css-tricks.com/snippets/css/a-guide-to-flexbox/" rel="external nofollow noopener noreferrer" target="_blank">A Complete Guide to Flexbox | CSS-Tricks</a></li><li><a href="https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Flexible_Box_Layout/Using_CSS_flexible_boxes" rel="external nofollow noopener noreferrer" target="_blank">Using CSS Flexible Boxes - CSS | MDN</a></li></ol>]]></content>
<summary type="html">
<p>這是一道送分題,如果想要垂直置中元素的話,起碼會有四種方法:<strong>padding</strong>, <strong>line-height</strong>, <strong>table</strong> 和 <strong>Flexbox</strong>。使
</summary>
<category term="CSS" scheme="https://calpa.me/Tags/CSS/"/>
</entry>
</feed>