-
Notifications
You must be signed in to change notification settings - Fork 1
/
15281298530120.html
601 lines (329 loc) · 27.1 KB
/
15281298530120.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
<!doctype html>
<html class="no-js" lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>
How to build your own React boilerplate - Junkman
</title>
<link href="atom.xml" rel="alternate" title="Junkman" type="application/atom+xml">
<link rel="stylesheet" href="asset/css/foundation.min.css" />
<link rel="stylesheet" href="asset/css/docs.css" />
<script src="asset/js/vendor/modernizr.js"></script>
<script src="asset/js/vendor/jquery.js"></script>
<script src="asset/highlightjs/highlight.pack.js"></script>
<link href="asset/highlightjs/styles/github.css" media="screen, projection" rel="stylesheet" type="text/css">
<script>hljs.initHighlightingOnLoad();</script>
<script type="text/javascript">
function before_search(){
var searchVal = 'site:panlw.github.io ' + document.getElementById('search_input').value;
document.getElementById('search_q').value = searchVal;
return true;
}
</script>
</head>
<body class="antialiased hide-extras">
<div class="marketing off-canvas-wrap" data-offcanvas>
<div class="inner-wrap">
<nav class="top-bar docs-bar hide-for-small" data-topbar>
<section class="top-bar-section">
<div class="row">
<div style="position: relative;width:100%;"><div style="position: absolute; width:100%;">
<ul id="main-menu" class="left">
<li id=""><a target="self" href="index.html">Home</a></li>
<li id=""><a target="_self" href="archives.html">Archives</a></li>
</ul>
<ul class="right" id="search-wrap">
<li>
<form target="_blank" onsubmit="return before_search();" action="http://google.com/search" method="get">
<input type="hidden" id="search_q" name="q" value="" />
<input tabindex="1" type="search" id="search_input" placeholder="Search"/>
</form>
</li>
</ul>
</div></div>
</div>
</section>
</nav>
<nav class="tab-bar show-for-small">
<a href="javascript:void(0)" class="left-off-canvas-toggle menu-icon">
<span> Junkman</span>
</a>
</nav>
<aside class="left-off-canvas-menu">
<ul class="off-canvas-list">
<li><a href="index.html">HOME</a></li>
<li><a href="archives.html">Archives</a></li>
<li><a href="about.html">ABOUT</a></li>
<li><label>Categories</label></li>
<li><a href="Infra.html">Infra</a></li>
<li><a href="Coding.html">Coding</a></li>
<li><a href="Modeling.html">Modeling</a></li>
<li><a href="Archtecting.html">Archtecting</a></li>
</ul>
</aside>
<a class="exit-off-canvas" href="#"></a>
<section id="main-content" role="main" class="scroll-container">
<script type="text/javascript">
$(function(){
$('#menu_item_index').addClass('is_active');
});
</script>
<div class="row">
<div class="large-8 medium-8 columns">
<div class="markdown-body article-wrap">
<div class="article">
<h1>How to build your own React boilerplate</h1>
<div class="read-more clearfix">
<span class="date">2018/6/5</span>
<span>posted in </span>
<span class="posted-in"><a href='Node.js.html'>Node.js</a></span>
<span class="comments">
</span>
</div>
</div><!-- article -->
<div class="article-content">
<blockquote>
<p><a href="https://medium.com/@sethalexander/how-to-build-your-own-react-boilerplate-1a97d09337fd">https://medium.com/@sethalexander/how-to-build-your-own-react-boilerplate-1a97d09337fd</a><br/>
Seth Alexander, May 12 2018</p>
</blockquote>
<h1 id="toc_0">How to build your own React boilerplate</h1>
<p>So you’ve learned some <a href="https://reactjs.org/">React</a> and built a few things. You’ve probably used <a href="https://github.com/facebook/create-react-app">create-react-app</a> or <a href="https://github.com/coryhouse/react-slingshot">react-slingshot</a> to get off the ground quickly with minimal configuration. However, now you’re ready to venture out on your own with your very own React boilerplate.</p>
<p><img src="https://cdn-images-1.medium.com/max/800/0*2WYxr-sEuxS0piH6.gif" alt=""/></p>
<h3 id="toc_1">WHERE. TO. START?</h3>
<p>I recently faced this same dilemma. It was a struggle, but at the end of it, I had a solid repo that I could use as a basis for future React projects.</p>
<p>I realized I wanted to use <a href="https://webpack.js.org/">Webpack</a> because it’s the new hotness (well not so new), but I wouldn’t have a lot of resources to pull from to figure it out.</p>
<p>I have <strong>zero</strong> working knowledge of <a href="https://gruntjs.com/">Grunt</a> or <a href="https://gulpjs.com/">Gulp</a>, although after looking at them briefly, I know they do some cools things in their own right.</p>
<p>Also, the people I know who <strong>know</strong> more than I do use Webpack. I also had a reference React boilerplate Webpack config I was going to use as a base (but I quickly realized I was going to have to rewrite most of this config).</p>
<h3 id="toc_2">Back to the beginning</h3>
<p>Let’s take it back, though. What really is a boilerplate? <a href="https://en.oxforddictionaries.com/definition/boilerplate">Dictionary.com</a> failed in getting me a definition that would work. <a href="https://en.oxforddictionaries.com/definition/boilerplate">Oxford Dictionaries</a>, on the other hand, landed the W with:</p>
<blockquote>
<p><strong>_3.1_</strong> <u>Standardized pieces of text for use as clauses in contracts or as part of a computer program.</u></p>
</blockquote>
<p>This works. So it’s something that’s standard across computer programs. As in some code that’s always the same at least in theory. So instead of having to run things like <code>npm i react react-dom webpack</code> and so on every time we start a project, we can copy our boilerplate and be off to the races knowing all the essential pieces we want are ready to go.</p>
<p>And since we’ll be building our own boilerplate, we’ll know that everything is being maintained the way <strong>we</strong> want it to, because it’s ours. We will also learn <strong>a lot</strong> during the process, and possibly even decide to make decisions that differ from what others have instructed us to do.</p>
<h3 id="toc_3">Get Git</h3>
<p>First let’s create a local folder and make this a Git repository.</p>
<p><img src="https://cdn-images-1.medium.com/max/800/0*92nYSWFkxFnzhxom.png" alt=""/></p>
<h3 id="toc_4">First things first</h3>
<p>Now, what type of project would this be without a <code>README.md</code>? Every repository should have a readme file. Even if it’s just to remind <strong>you</strong> about how things work. Trust me, it may seem like you’ll remember exactly what each script does and why right now. However, a year from now, these readme’s come in handy! Trust me. So, create a <code>README.md</code> in the root of the project. Put something like this in there:</p>
<p><img src="https://cdn-images-1.medium.com/max/800/0*qB4QoPyvIIjaF5Lh.png" alt=""/></p>
<p>Make sure to commit your files to Git after any changes you make:</p>
<p><img src="https://cdn-images-1.medium.com/max/800/0*fpBsmbW-AeQiaaqX.png" alt=""/></p>
<h3 id="toc_5">Folder structure</h3>
<p>This one is pretty straightforward. Make the following folder structure to house everything:</p>
<p><img src="https://cdn-images-1.medium.com/max/800/0*XA_6Y4HbQG1bVbO_.png" alt=""/></p>
<p>You can accomplish this easily with this command:</p>
<p><img src="https://cdn-images-1.medium.com/max/800/0*W5jZA0cJguUxiOE4.png" alt=""/></p>
<h3 id="toc_6">.gitignore</h3>
<p>An essential part of any Git project is the <code>.gitignore</code> file. This tells Git to not put certain files under version control. This is important for things like packages and other things that we will retrieve from repositories. Not only do we not need these in version control, but it’s actually detrimental if we do include them in version control. At least I’m pretty sure it’s detrimental.</p>
<p>Create a <code>.gitignore</code> file in the root of your project and add the following to it:</p>
<p><img src="https://cdn-images-1.medium.com/max/800/0*uq8MctPHdRBAwoHb.png" alt=""/></p>
<p>There are generators for this file, like <a href="https://www.gitignore.io/">this one</a>, but this should be enough for what we’re doing today.</p>
<h3 id="toc_7">npm</h3>
<p>All node projects must be initialized so we can use the package manager. This will create a <code>package.json</code> file for us, which must be in version control.</p>
<p>It contains many things, but the most important are:</p>
<ul>
<li> A list of all the installed packages and their semantic version allowed</li>
<li> Scripts</li>
</ul>
<p>To start this process, enter the following in your terminal in the root of your project:</p>
<p><img src="https://cdn-images-1.medium.com/max/800/0*yW-u991aXCNqz-zi.png" alt=""/></p>
<p>You’ll be asked more than a few questions, but feel free to just press Enter and leave it all blank. In the end you’ll have a shiny new <code>package.json</code> that looks something like this:</p>
<p><img src="https://cdn-images-1.medium.com/max/800/0*NPlQqu8mBV6nyT8e.png" alt=""/></p>
<h3 id="toc_8">HTML</h3>
<p>Yes! Time to write some code! Well, this is going to be the most boring HTML you’ll probably ever write. Create an <code>index.html</code> in the root of your project and set it up like so:</p>
<p><img src="https://cdn-images-1.medium.com/max/800/0*Fb3KAWcWthmyOr1g.png" alt=""/></p>
<h3 id="toc_9">React</h3>
<p>Now, let’s add React to our project.</p>
<p><img src="https://cdn-images-1.medium.com/max/800/0*Ean3wrHFOffJxLrw.png" alt=""/></p>
<p>Create this file <code>/src/components/App.js</code> and in it put the following:</p>
<p><img src="https://cdn-images-1.medium.com/max/800/0*_MoFAJv6Q67MPdZM.png" alt=""/></p>
<p>Then we will render the App via an index which we will create here at <code>/src/index.js</code> and put the following in:</p>
<p><img src="https://cdn-images-1.medium.com/max/800/0*R6dXNZsV87UgBKfo.png" alt=""/></p>
<h3 id="toc_10">Babel</h3>
<p>Babel is awesome. It lets us write the latest and greatest JavaScript while ensuring we have maximum compatibility with the code we ship. First thing is we have to install Babel and a few additional Babel packages to make this all work together. Don’t worry, I’ll explain it soon.</p>
<p><img src="https://cdn-images-1.medium.com/max/800/0*V1zp2qsT6h8VeyIc.png" alt=""/></p>
<p>Then we need to create a <code>.babelrc</code> in the root of our project and add the following to it:</p>
<p><img src="https://cdn-images-1.medium.com/max/800/0*sMLcbLkO-PpW1sJ8.png" alt=""/></p>
<p>Now, what does this do exactly? The <code>env</code> preset implicitly includes <code>babel-preset-es2015</code>, <code>babel-preset-es2016</code>, and <code>babel-preset-es2017</code> together, which means you can run ES6, ES7, and ES8 code.</p>
<p>The <code>react</code> preset I <strong>think</strong> is pretty self-explanatory, but, you might be wondering why we need it if React is JavaScript. That’s because Babel doesn’t know what to do with React & JSX.</p>
<p>Finally, <code>stage-2</code> allows us to utilize the JavaScript features that are currently at Stage 2 or later in the process. To learn more than you probably want to know, check out <a href="http://2ality.com/2015/11/tc39-process.html">The TC39 process for ECMAScript features</a> for more info. The key being that at stage 2, <strong>an eventual inclusion of the feature in the standard is likely</strong>, so we might as well start using it, right?</p>
<h3 id="toc_11">Tests</h3>
<p>So we’re making progress. Now that we have a React component with our <code>App.js</code> let’s make sure to create a simple associated test for that component. This way we’re starting to implement some good practices, like having tests for the things we build. We will be using Jest with Enzyme for this project. First things first, let’s install it with:</p>
<p><img src="https://cdn-images-1.medium.com/max/800/0*cXHuNAsv_Hx0WiL-.png" alt=""/></p>
<p>Now create <code>/test/enzyme.setup.js</code> and put in it:</p>
<p><img src="https://cdn-images-1.medium.com/max/800/0*frY42A7_35JY53JQ.png" alt=""/></p>
<p>We’ll need to add Jest functionality into our <code>package.json</code> so add the following to it:</p>
<p><img src="https://cdn-images-1.medium.com/max/800/0*00Hwe158-rvXI2ge.png" alt=""/></p>
<p>Next, we should add our first component test! So, create a file at <code>/test/App.test.js</code> to test that our App component renders as expected. We are also going to implement a snapshot test to ensure our component’s structure doesn’t change from test to test. To do that we’ll need the following:</p>
<p><img src="https://cdn-images-1.medium.com/max/800/0*cVzP2dCxIldszNhf.png" alt=""/></p>
<p>You might be wondering how to run this new test. To do so, we need to change the <code>test</code> script in the <code>package.json</code> to this:</p>
<p><img src="https://cdn-images-1.medium.com/max/800/0*-Jzpfbvf2F9XD1ue.png" alt=""/></p>
<p>You can now run the test from your terminal with <code>npm test</code> and should see something like this:</p>
<p><img src="https://cdn-images-1.medium.com/max/800/0*556y3LdrI4wrbrWi.png" alt=""/></p>
<h3 id="toc_12">Break Time</h3>
<p>If you’ve made it this far with your React boilerplate, CONGRATS! Mostly because you’ve realized that I’m using images for my code and you have to type it all out. That’s a pain in the butt, I know. Trust me though, you’re learning more than you know by being forced to type it all out, and the muscle memory is going to serve you well long after this tutorial.</p>
<h3 id="toc_13">Webpack</h3>
<p>Webpack will allow us to modularize our code and easily bundle it into a single file for production. Something I think a lot of people really like about Webpack, though, is the development server. We’ll start by just installing Webpack with:</p>
<p><img src="https://cdn-images-1.medium.com/max/800/0*c0p_-oAvwVzpwpwV.png" alt=""/></p>
<p>Webpack looks for a <code>webpack.config.js</code> file by default in the root of the project, so let’s create that and add to it a couple things:</p>
<p><img src="https://cdn-images-1.medium.com/max/800/0*SlQTqp8Ca-bAh2v0.png" alt=""/></p>
<p>The <code>entry</code> is telling Webpack where to find the base JavaScript file. In our application, that’s <code>index.js</code>. Then it tells it where to output the built file when it’s done with it.</p>
<h3 id="toc_14">Webpack loaders</h3>
<p>Loaders are helpful pieces we can add to Webpack to make it more powerful and do things to other file types. Before Webpack will work properly, we need to set it up to work with ES6 and JSX. We’ll do this through the <code>babel-loader</code>. Add the <code>babel-loader</code> to your project with:</p>
<p><img src="https://cdn-images-1.medium.com/max/800/0*zXf29F04uzIi5oDK.png" alt=""/></p>
<p>Then add the loader to your <code>webpack.config.js</code> like so:</p>
<p><img src="https://cdn-images-1.medium.com/max/800/0*5CRMb3rDDg5xydIi.png" alt=""/></p>
<p>To utilize Sass and SCSS, we’ll need another loader. Now to get the best “bang for our buck” we’re going to chain three loaders together so our styles are applied immediately to the DOM. Let’s install the loaders:</p>
<p><img src="https://cdn-images-1.medium.com/max/800/0*-ICXu4VHvyElCoIy.png" alt=""/></p>
<p>And configure it like so in our <code>webpack.config.js</code>:</p>
<p><img src="https://cdn-images-1.medium.com/max/800/0*xyRAib0DelV-b1qK.png" alt=""/></p>
<p>Since we just enabled some style support, let’s add some. Create <code>/src/styles/style.sass</code> and put in it:</p>
<p><img src="https://cdn-images-1.medium.com/max/800/0*das9iIjQuzsA9wA8.png" alt=""/></p>
<p>Then add it to your <code>index.js</code> like so:</p>
<p><img src="https://cdn-images-1.medium.com/max/800/0*QUPugYHTy7spv3Il.png" alt=""/></p>
<p>Up next are Webpack plugins. So, we need a way to include the built JavaScript in our <code>index.html</code> and of course, there’s a way to do this automatically. This is also going to take the <code>index.html</code> file and drop it into our build folder (more on the build later). Let’s add the <code>HtmlWebPackPlugin</code> and include it in our <code>webpack.config.js</code> like so:</p>
<p><img src="https://cdn-images-1.medium.com/max/800/0*FIwyAEw_4n99_7BE.png" alt=""/></p>
<p>Then:</p>
<p><img src="https://cdn-images-1.medium.com/max/800/0*18qOQVxQIIkwe41_.png" alt=""/></p>
<p>Our next plugin is going to ensure that the directory we put our build in is cleaned out of any former files every time we run a build. We do that with these two steps:</p>
<p><img src="https://cdn-images-1.medium.com/max/800/0*DzhmgthF4vle9Gzy.png" alt=""/></p>
<p>Then:</p>
<p><img src="https://cdn-images-1.medium.com/max/800/0*R3p50_B65hR4fxVq.png" alt=""/></p>
<p>The moment we’ve all been waiting for! Let’s get the development server set up. So we’re going to add two packages in this step. <code>webpack-cli</code> is going to be used to run our commands from our <code>package.json</code> file. First:</p>
<p><img src="https://cdn-images-1.medium.com/max/800/0*IGHtuoKZZu69mWli.png" alt=""/></p>
<p>Then update our <code>webpack.config.js</code>:</p>
<p><img src="https://cdn-images-1.medium.com/max/800/0*iirbAytQ0N8sWjYJ.png" alt=""/></p>
<p>Finally add to the scripts section of the <code>package.json</code>:</p>
<p><img src="https://cdn-images-1.medium.com/max/800/0*96k0tCdU9yKoJHEa.png" alt=""/></p>
<p>Now fire up your development server and your default browser will open. It’ll take a second while Webpack does its thing, but you’ll soon see your React live in the browser.</p>
<p><img src="https://cdn-images-1.medium.com/max/800/0*u-SpQQFtVjO5BDZY.png" alt=""/></p>
<p>So right now we could say success! However, our code isn’t optimized for production use. But we don’t want to optimize our code while we’re in development either, because it takes a lot longer to build. So let’s create separate build files for our production and development environments and tell Webpack how to handle that. I promise we’re almost done. Really we are…</p>
<p>Up next is:</p>
<p><img src="https://cdn-images-1.medium.com/max/800/0*PlSBA34kM63ex9WR.png" alt=""/></p>
<p>This is going to allow us to have three Webpack config files. So let’s get that setup. Rename your <code>webpack.config.js</code> to <code>webpack.common.js</code>. Then create <code>webpack.dev.js</code> and <code>webpack.prod.js</code>. The idea is one will have configuration used in both development and production, one will be development only, and one will be production only.</p>
<p>So first thing, let’s remove the development server code from common we just added in the last step and add it to <code>webpack.dev.js</code>. We’ll utilize <code>webpack-merge</code> to include everything from <code>webpack.common.js</code> and add on <code>webpack.dev.js</code>. So now your <code>webpack.common.js</code> looks like this:</p>
<p><img src="https://cdn-images-1.medium.com/max/800/0*hIbPOh_uwBimE1p6.png" alt=""/></p>
<p>Your <code>webpack.dev.js</code> should look like this:</p>
<p><img src="https://cdn-images-1.medium.com/max/800/0*jtMKTRLUVCjH1jr2.png" alt=""/></p>
<p>Your <code>webpack.prod.js</code> should look like this:</p>
<p><img src="https://cdn-images-1.medium.com/max/800/0*2mHw3JrENOizgUN7.png" alt=""/></p>
<p>The last step here is to update the <code>scripts</code> in our <code>package.json</code> file to utilize these different files at different times. Your new <code>scripts</code> sections should look like:</p>
<p><img src="https://cdn-images-1.medium.com/max/800/0*LKSauxx8B6LiVRva.png" alt=""/></p>
<h3 id="toc_15">What now?</h3>
<p>Now you can go ahead and start your development server with:</p>
<p><img src="https://cdn-images-1.medium.com/max/800/0*sYXHRufDR0sNg9p5.png" alt=""/></p>
<p>You can build your application and have all the advantages of everything we’ve put together. When you’re ready to deploy your production application just run:</p>
<p><img src="https://cdn-images-1.medium.com/max/800/0*9WoL_3BK8Jrhl3nY.png" alt=""/></p>
<p>This will output an optimized version of your code into the <code>/dist</code> folder. Take those files and upload them to your favorite host and you’re good to go!</p>
<h3 id="toc_16">What’s Next With Your React Boilerplate?</h3>
<p>Well, nothing from me! Ha, I think you’ve had enough by now. Hopefully, this empowers you to dive into creating your own boilerplate. You’ll start your personal projects steps ahead and really get an understanding of what each piece does.</p>
<p>I <strong>highly</strong> recommend the <a href="https://webpack.js.org/concepts/">Webpack docs</a> for further reading if you want to continue to add configuration to your Webpack setup. There is <strong>a lot</strong> more you can do with it.</p>
<p>Another thing you might want to do is set up something like <a href="https://eslint.org/">ESLint</a> in your project as well. You can also dive deep into <a href="https://babeljs.io/">Babel</a> and all that it allows you to do.</p>
<p>Thanks for reading! I’d love to hear what you think about this setup. Anything you’d add, remove, or change, please leave in the comments below.</p>
<p>I ALMOST FORGOT! <u>Actually I did, I’m adding this after I clicked “Publish”</u>. If you want to find all this code, I have it in a repo <a href="https://github.com/itzsaga/react-boilerplate-blog">here</a>.</p>
</div>
<div class="row">
<div class="large-6 columns">
<p class="text-left" style="padding:15px 0px;">
<a href="15281300875751.html"
title="Previous Post: Bash variables and command substitution">« Bash variables and command substitution</a>
</p>
</div>
<div class="large-6 columns">
<p class="text-right" style="padding:15px 0px;">
<a href="15281297267376.html"
title="Next Post: 中国式微服务技术栈2.0">中国式微服务技术栈2.0 »</a>
</p>
</div>
</div>
<div class="comments-wrap">
<div class="share-comments">
<script type="text/javascript" src="//s7.addthis.com/js/300/addthis_widget.js#pubid=ra-5ae58078c0d7b2ab"></script>
</div>
</div>
</div><!-- article-wrap -->
</div><!-- large 8 -->
<div class="large-4 medium-4 columns">
<div class="hide-for-small">
<div id="sidebar" class="sidebar">
<div id="site-info" class="site-info">
<div class="site-a-logo"><img src="./asset/img/logo.jpg" /></div>
<h1>Junkman</h1>
<div class="site-des">“拾荒者”一词来自凯文・凯利的《失控》中关于机器学习的故事(“收集癖好机”如何完成他的收集工作)。</div>
<div class="social">
<a target="_blank" class="github" target="_blank" href="https://github.com/panlw/" title="GitHub">GitHub</a>
<a target="_blank" class="rss" href="atom.xml" title="RSS">RSS</a>
</div>
</div>
<div id="site-categories" class="side-item ">
<div class="side-header">
<h2>Categories</h2>
</div>
<div class="side-content">
<p class="cat-list">
<a href="Infra.html"><strong>Infra</strong></a>
<a href="Coding.html"><strong>Coding</strong></a>
<a href="Modeling.html"><strong>Modeling</strong></a>
<a href="Archtecting.html"><strong>Archtecting</strong></a>
</p>
</div>
</div>
<div id="site-categories" class="side-item">
<div class="side-header">
<h2>Recent Posts</h2>
</div>
<div class="side-content">
<ul class="posts-list">
<li class="post">
<a href="15517999043443.html">The Art of Crafting Architectural Diagrams</a>
</li>
<li class="post">
<a href="15517997955971.html">为什么说我们需要软件架构图?</a>
</li>
<li class="post">
<a href="15516128677869.html">DNS Servers That Offer Privacy and Filtering</a>
</li>
<li class="post">
<a href="15516123108194.html">Airbnb's Migration from Monolith to Services</a>
</li>
<li class="post">
<a href="15516097487470.html">Events As First-Class Citizens</a>
</li>
</ul>
</div>
</div>
</div><!-- sidebar -->
</div><!-- hide for small -->
</div><!-- large 4 -->
</div><!-- row -->
<div class="page-bottom clearfix">
<div class="row">
<p class="copyright">Copyright © 2015
Powered by <a target="_blank" href="http://www.mweb.im">MWeb</a>,
Theme used <a target="_blank" href="http://github.com">GitHub CSS</a>.</p>
</div>
</div>
</section>
</div>
</div>
<script src="asset/js/foundation.min.js"></script>
<script>
$(document).foundation();
function fixSidebarHeight(){
var w1 = $('.markdown-body').height();
var w2 = $('#sidebar').height();
if (w1 > w2) { $('#sidebar').height(w1); };
}
$(function(){
fixSidebarHeight();
})
$(window).load(function(){
fixSidebarHeight();
});
</script>
<script src="asset/chart/all-min.js"></script><script type="text/javascript">$(function(){ var mwebii=0; var mwebChartEleId = 'mweb-chart-ele-'; $('pre>code').each(function(){ mwebii++; var eleiid = mwebChartEleId+mwebii; if($(this).hasClass('language-sequence')){ var ele = $(this).addClass('nohighlight').parent(); $('<div id="'+eleiid+'"></div>').insertAfter(ele); ele.hide(); var diagram = Diagram.parse($(this).text()); diagram.drawSVG(eleiid,{theme: 'simple'}); }else if($(this).hasClass('language-flow')){ var ele = $(this).addClass('nohighlight').parent(); $('<div id="'+eleiid+'"></div>').insertAfter(ele); ele.hide(); var diagram = flowchart.parse($(this).text()); diagram.drawSVG(eleiid); } });});</script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script><script type="text/x-mathjax-config">MathJax.Hub.Config({TeX: { equationNumbers: { autoNumber: "AMS" } }});</script>
</body>
</html>