A place to cache linked articles (think custom and personal wayback machine)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

index.html 58KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727
  1. <!doctype html><!-- This is a valid HTML5 document. -->
  2. <!-- Screen readers, SEO, extensions and so on. -->
  3. <html lang=fr>
  4. <!-- Has to be within the first 1024 bytes, hence before the <title>
  5. See: https://www.w3.org/TR/2012/CR-html5-20121217/document-metadata.html#charset -->
  6. <meta charset=utf-8>
  7. <!-- Why no `X-UA-Compatible` meta: https://stackoverflow.com/a/6771584 -->
  8. <!-- The viewport meta is quite crowded and we are responsible for that.
  9. See: https://codepen.io/tigt/post/meta-viewport-for-2015 -->
  10. <meta name=viewport content="width=device-width,minimum-scale=1,initial-scale=1,shrink-to-fit=no">
  11. <!-- Required to make a valid HTML5 document. -->
  12. <title>State of the Art JavaScript in 2016 (archive) — David Larlet</title>
  13. <!-- Generated from https://realfavicongenerator.net/ such a mess. -->
  14. <link rel="apple-touch-icon" sizes="180x180" href="/static/david/icons/apple-touch-icon.png">
  15. <link rel="icon" type="image/png" sizes="32x32" href="/static/david/icons/favicon-32x32.png">
  16. <link rel="icon" type="image/png" sizes="16x16" href="/static/david/icons/favicon-16x16.png">
  17. <link rel="manifest" href="/manifest.json">
  18. <link rel="mask-icon" href="/static/david/icons/safari-pinned-tab.svg" color="#5bbad5">
  19. <link rel="shortcut icon" href="/static/david/icons/favicon.ico">
  20. <meta name="apple-mobile-web-app-title" content="David Larlet">
  21. <meta name="application-name" content="David Larlet">
  22. <meta name="msapplication-TileColor" content="#da532c">
  23. <meta name="msapplication-config" content="/static/david/icons/browserconfig.xml">
  24. <meta name="theme-color" content="#f0f0ea">
  25. <!-- That good ol' feed, subscribe :p. -->
  26. <link rel=alternate type="application/atom+xml" title=Feed href="/david/log/">
  27. <meta name="robots" content="noindex, nofollow">
  28. <meta content="origin-when-cross-origin" name="referrer">
  29. <!-- Canonical URL for SEO purposes -->
  30. <link rel="canonical" href="https://medium.com/@fward/state-of-the-art-javascript-in-2016-ab67fc68eb0b">
  31. <style>
  32. /* http://meyerweb.com/eric/tools/css/reset/ */
  33. html, body, div, span,
  34. h1, h2, h3, h4, h5, h6, p, blockquote, pre,
  35. a, abbr, address, big, cite, code,
  36. del, dfn, em, img, ins,
  37. small, strike, strong, tt, var,
  38. dl, dt, dd, ol, ul, li,
  39. fieldset, form, label, legend,
  40. table, caption, tbody, tfoot, thead, tr, th, td,
  41. article, aside, canvas, details, embed,
  42. figure, figcaption, footer, header, hgroup,
  43. menu, nav, output, ruby, section, summary,
  44. time, mark, audio, video {
  45. margin: 0;
  46. padding: 0;
  47. border: 0;
  48. font-size: 100%;
  49. font: inherit;
  50. vertical-align: baseline;
  51. }
  52. /* HTML5 display-role reset for older browsers */
  53. article, aside, details, figcaption, figure,
  54. footer, header, hgroup, menu, nav, section { display: block; }
  55. body { line-height: 1; }
  56. blockquote, q { quotes: none; }
  57. blockquote:before, blockquote:after,
  58. q:before, q:after {
  59. content: '';
  60. content: none;
  61. }
  62. table {
  63. border-collapse: collapse;
  64. border-spacing: 0;
  65. }
  66. /* http://practicaltypography.com/equity.html */
  67. /* https://calendar.perfplanet.com/2016/no-font-face-bulletproof-syntax/ */
  68. /* https://www.filamentgroup.com/lab/js-web-fonts.html */
  69. @font-face {
  70. font-family: 'EquityTextB';
  71. src: url('/static/david/css/fonts/Equity-Text-B-Regular-webfont.woff2') format('woff2'),
  72. url('/static/david/css/fonts/Equity-Text-B-Regular-webfont.woff') format('woff');
  73. font-weight: 300;
  74. font-style: normal;
  75. font-display: swap;
  76. }
  77. @font-face {
  78. font-family: 'EquityTextB';
  79. src: url('/static/david/css/fonts/Equity-Text-B-Italic-webfont.woff2') format('woff2'),
  80. url('/static/david/css/fonts/Equity-Text-B-Italic-webfont.woff') format('woff');
  81. font-weight: 300;
  82. font-style: italic;
  83. font-display: swap;
  84. }
  85. @font-face {
  86. font-family: 'EquityTextB';
  87. src: url('/static/david/css/fonts/Equity-Text-B-Bold-webfont.woff2') format('woff2'),
  88. url('/static/david/css/fonts/Equity-Text-B-Bold-webfont.woff') format('woff');
  89. font-weight: 700;
  90. font-style: normal;
  91. font-display: swap;
  92. }
  93. @font-face {
  94. font-family: 'ConcourseT3';
  95. src: url('/static/david/css/fonts/concourse_t3_regular-webfont-20190806.woff2') format('woff2'),
  96. url('/static/david/css/fonts/concourse_t3_regular-webfont-20190806.woff') format('woff');
  97. font-weight: 300;
  98. font-style: normal;
  99. font-display: swap;
  100. }
  101. /* http://practice.typekit.com/lesson/caring-about-opentype-features/ */
  102. body {
  103. /* http://www.cssfontstack.com/ Palatino 99% Win 86% Mac */
  104. font-family: "EquityTextB", Palatino, serif;
  105. background-color: #f0f0ea;
  106. color: #07486c;
  107. font-kerning: normal;
  108. -moz-osx-font-smoothing: grayscale;
  109. -webkit-font-smoothing: subpixel-antialiased;
  110. text-rendering: optimizeLegibility;
  111. font-variant-ligatures: common-ligatures contextual;
  112. font-feature-settings: "kern", "liga", "clig", "calt";
  113. }
  114. pre, code, kbd, samp, var, tt {
  115. font-family: 'TriplicateT4c', monospace;
  116. }
  117. em {
  118. font-style: italic;
  119. color: #323a45;
  120. }
  121. strong {
  122. font-weight: bold;
  123. color: black;
  124. }
  125. nav {
  126. background-color: #323a45;
  127. color: #f0f0ea;
  128. display: flex;
  129. justify-content: space-around;
  130. padding: 1rem .5rem;
  131. }
  132. nav:last-child {
  133. border-bottom: 1vh solid #2d7474;
  134. }
  135. nav a {
  136. color: #f0f0ea;
  137. }
  138. nav abbr {
  139. border-bottom: 1px dotted white;
  140. }
  141. h1 {
  142. border-top: 1vh solid #2d7474;
  143. border-bottom: .2vh dotted #2d7474;
  144. background-color: #e3e1e1;
  145. color: #323a45;
  146. text-align: center;
  147. padding: 5rem 0 4rem 0;
  148. width: 100%;
  149. font-family: 'ConcourseT3';
  150. display: flex;
  151. flex-direction: column;
  152. }
  153. h1.single {
  154. padding-bottom: 10rem;
  155. }
  156. h1 span {
  157. position: absolute;
  158. top: 1vh;
  159. left: 20%;
  160. line-height: 0;
  161. }
  162. h1 span a {
  163. line-height: 1.7;
  164. padding: 1rem 1.2rem .6rem 1.2rem;
  165. border-radius: 0 0 6% 6%;
  166. background: #2d7474;
  167. font-size: 1.3rem;
  168. color: white;
  169. text-decoration: none;
  170. }
  171. h2 {
  172. margin: 4rem 0 1rem;
  173. border-top: .2vh solid #2d7474;
  174. padding-top: 1vh;
  175. }
  176. h3 {
  177. text-align: center;
  178. margin: 3rem 0 .75em;
  179. }
  180. hr {
  181. height: .4rem;
  182. width: .4rem;
  183. border-radius: .4rem;
  184. background: #07486c;
  185. margin: 2.5rem auto;
  186. }
  187. time {
  188. display: bloc;
  189. margin-left: 0 !important;
  190. }
  191. ul, ol {
  192. margin: 2rem;
  193. }
  194. ul {
  195. list-style-type: square;
  196. }
  197. a {
  198. text-decoration-skip-ink: auto;
  199. text-decoration-thickness: 0.05em;
  200. text-underline-offset: 0.09em;
  201. }
  202. article {
  203. max-width: 50rem;
  204. display: flex;
  205. flex-direction: column;
  206. margin: 2rem auto;
  207. }
  208. article.single {
  209. border-top: .2vh dotted #2d7474;
  210. margin: -6rem auto 1rem auto;
  211. background: #f0f0ea;
  212. padding: 2rem;
  213. }
  214. article p:last-child {
  215. margin-bottom: 1rem;
  216. }
  217. p {
  218. padding: 0 .5rem;
  219. margin-left: 3rem;
  220. }
  221. p + p,
  222. figure + p {
  223. margin-top: 2rem;
  224. }
  225. blockquote {
  226. background-color: #e3e1e1;
  227. border-left: .5vw solid #2d7474;
  228. display: flex;
  229. flex-direction: column;
  230. align-items: center;
  231. padding: 1rem;
  232. margin: 1.5rem;
  233. }
  234. blockquote cite {
  235. font-style: italic;
  236. }
  237. blockquote p {
  238. margin-left: 0;
  239. }
  240. figure {
  241. border-top: .2vh solid #2d7474;
  242. background-color: #e3e1e1;
  243. text-align: center;
  244. padding: 1.5rem 0;
  245. margin: 1rem 0 0;
  246. font-size: 1.5rem;
  247. width: 100%;
  248. }
  249. figure img {
  250. max-width: 250px;
  251. max-height: 250px;
  252. border: .5vw solid #323a45;
  253. padding: 1px;
  254. }
  255. figcaption {
  256. padding: 1rem;
  257. line-height: 1.4;
  258. }
  259. aside {
  260. display: flex;
  261. flex-direction: column;
  262. background-color: #e3e1e1;
  263. padding: 1rem 0;
  264. border-bottom: .2vh solid #07486c;
  265. }
  266. aside p {
  267. max-width: 50rem;
  268. margin: 0 auto;
  269. }
  270. /* https://fvsch.com/code/css-locks/ */
  271. p, li, pre, code, kbd, samp, var, tt, time, details, figcaption {
  272. font-size: 1rem;
  273. line-height: calc( 1.5em + 0.2 * 1rem );
  274. }
  275. h1 {
  276. font-size: 1.9rem;
  277. line-height: calc( 1.2em + 0.2 * 1rem );
  278. }
  279. h2 {
  280. font-size: 1.6rem;
  281. line-height: calc( 1.3em + 0.2 * 1rem );
  282. }
  283. h3 {
  284. font-size: 1.35rem;
  285. line-height: calc( 1.4em + 0.2 * 1rem );
  286. }
  287. @media (min-width: 20em) {
  288. /* The (100vw - 20rem) / (50 - 20) part
  289. resolves to 0-1rem, depending on the
  290. viewport width (between 20em and 50em). */
  291. p, li, pre, code, kbd, samp, var, tt, time, details, figcaption {
  292. font-size: calc( 1rem + .6 * (100vw - 20rem) / (50 - 20) );
  293. line-height: calc( 1.5em + 0.2 * (100vw - 50rem) / (20 - 50) );
  294. margin-left: 0;
  295. }
  296. h1 {
  297. font-size: calc( 1.9rem + 1.5 * (100vw - 20rem) / (50 - 20) );
  298. line-height: calc( 1.2em + 0.2 * (100vw - 50rem) / (20 - 50) );
  299. }
  300. h2 {
  301. font-size: calc( 1.5rem + 1.5 * (100vw - 20rem) / (50 - 20) );
  302. line-height: calc( 1.3em + 0.2 * (100vw - 50rem) / (20 - 50) );
  303. }
  304. h3 {
  305. font-size: calc( 1.35rem + 1.5 * (100vw - 20rem) / (50 - 20) );
  306. line-height: calc( 1.4em + 0.2 * (100vw - 50rem) / (20 - 50) );
  307. }
  308. }
  309. @media (min-width: 50em) {
  310. /* The right part of the addition *must* be a
  311. rem value. In this example we *could* change
  312. the whole declaration to font-size:2.5rem,
  313. but if our baseline value was not expressed
  314. in rem we would have to use calc. */
  315. p, li, pre, code, kbd, samp, var, tt, time, details, figcaption {
  316. font-size: calc( 1rem + .6 * 1rem );
  317. line-height: 1.5em;
  318. }
  319. p, li, pre, details {
  320. margin-left: 3rem;
  321. }
  322. h1 {
  323. font-size: calc( 1.9rem + 1.5 * 1rem );
  324. line-height: 1.2em;
  325. }
  326. h2 {
  327. font-size: calc( 1.5rem + 1.5 * 1rem );
  328. line-height: 1.3em;
  329. }
  330. h3 {
  331. font-size: calc( 1.35rem + 1.5 * 1rem );
  332. line-height: 1.4em;
  333. }
  334. figure img {
  335. max-width: 500px;
  336. max-height: 500px;
  337. }
  338. }
  339. figure.unsquared {
  340. margin-bottom: 1.5rem;
  341. }
  342. figure.unsquared img {
  343. height: inherit;
  344. }
  345. @media print {
  346. body { font-size: 100%; }
  347. a:after { content: " (" attr(href) ")"; }
  348. a, a:link, a:visited, a:after {
  349. text-decoration: underline;
  350. text-shadow: none !important;
  351. background-image: none !important;
  352. background: white;
  353. color: black;
  354. }
  355. abbr[title] { border-bottom: 0; }
  356. abbr[title]:after { content: " (" attr(title) ")"; }
  357. img { page-break-inside: avoid; }
  358. @page { margin: 2cm .5cm; }
  359. h1, h2, h3 { page-break-after: avoid; }
  360. p3 { orphans: 3; widows: 3; }
  361. img {
  362. max-width: 250px !important;
  363. max-height: 250px !important;
  364. }
  365. nav, aside { display: none; }
  366. }
  367. ul.with_columns {
  368. column-count: 1;
  369. }
  370. @media (min-width: 20em) {
  371. ul.with_columns {
  372. column-count: 2;
  373. }
  374. }
  375. @media (min-width: 50em) {
  376. ul.with_columns {
  377. column-count: 3;
  378. }
  379. }
  380. ul.with_two_columns {
  381. column-count: 1;
  382. }
  383. @media (min-width: 20em) {
  384. ul.with_two_columns {
  385. column-count: 1;
  386. }
  387. }
  388. @media (min-width: 50em) {
  389. ul.with_two_columns {
  390. column-count: 2;
  391. }
  392. }
  393. .gallery {
  394. display: flex;
  395. flex-wrap: wrap;
  396. justify-content: space-around;
  397. }
  398. .gallery figure img {
  399. margin-left: 1rem;
  400. margin-right: 1rem;
  401. }
  402. .gallery figure figcaption {
  403. font-family: 'ConcourseT3'
  404. }
  405. footer {
  406. font-family: 'ConcourseT3';
  407. display: flex;
  408. flex-direction: column;
  409. border-top: 3px solid white;
  410. padding: 4rem 0;
  411. background-color: #07486c;
  412. color: white;
  413. }
  414. footer > * {
  415. max-width: 50rem;
  416. margin: 0 auto;
  417. }
  418. footer a {
  419. color: #f1c40f;
  420. }
  421. footer .avatar {
  422. width: 200px;
  423. height: 200px;
  424. border-radius: 50%;
  425. float: left;
  426. -webkit-shape-outside: circle();
  427. shape-outside: circle();
  428. margin-right: 2rem;
  429. padding: 2px 5px 5px 2px;
  430. background: white;
  431. border-left: 1px solid #f1c40f;
  432. border-top: 1px solid #f1c40f;
  433. border-right: 5px solid #f1c40f;
  434. border-bottom: 5px solid #f1c40f;
  435. }
  436. </style>
  437. <h1>
  438. <span><a id="jumper" href="#jumpto" title="Un peu perdu ?">?</a></span>
  439. State of the Art JavaScript in 2016 (archive)
  440. <time>Pour la pérennité des contenus liés. Non-indexé, retrait sur simple email.</time>
  441. </h1>
  442. <section>
  443. <article>
  444. <h3><a href="https://medium.com/@fward/state-of-the-art-javascript-in-2016-ab67fc68eb0b">Source originale du contenu</a></h3>
  445. <figure name="977f" id="977f" class="graf--figure graf--layoutOutsetLeft graf-after--h3"><figcaption class="imageCaption">Image “Question!” by<a href="https://www.flickr.com/photos/-bast-/349497988/in/photolist-wTgzo-4ms8ZA-5DeuzB-8JkcMH-5CCQse-wRSNhj-6nCmik-rphyCW-5huQJc-bTQwfx-6S4XJJ-9grzfE-6Vmcpf-56eXRT-7VhPft-u5Gjqy-azGM3y-i6cpkf-7Er6af-7kZ57d-bTQwf4-5uCCw4-4vz7rG-ediLaQ-5JE9tz-5UnDmk-rrtnoF-8qQBZ9-KGgU8-9SScHJ-5YpgQU-do8Bez-5Ttgxf-oqtM3G-p9e9F3-s29nxg-v2dmxU-9uZpk3-uZot4q-u5RNwp-e5A9GJ-LaARx-cxUcBu-bncE6P-hyjkR3-fvAqY1-sQzvg-9v3xhu-6CrL7s-snRpm3/" data-href="https://www.flickr.com/photos/-bast-/349497988/in/photolist-wTgzo-4ms8ZA-5DeuzB-8JkcMH-5CCQse-wRSNhj-6nCmik-rphyCW-5huQJc-bTQwfx-6S4XJJ-9grzfE-6Vmcpf-56eXRT-7VhPft-u5Gjqy-azGM3y-i6cpkf-7Er6af-7kZ57d-bTQwf4-5uCCw4-4vz7rG-ediLaQ-5JE9tz-5UnDmk-rrtnoF-8qQBZ9-KGgU8-9SScHJ-5YpgQU-do8Bez-5Ttgxf-oqtM3G-p9e9F3-s29nxg-v2dmxU-9uZpk3-uZot4q-u5RNwp-e5A9GJ-LaARx-cxUcBu-bncE6P-hyjkR3-fvAqY1-sQzvg-9v3xhu-6CrL7s-snRpm3/" class="markup--anchor markup--figure-anchor" rel="nofollow"> Stefan Baudy</a>, CC BY 2.0</figcaption></figure>
  446. <p name="7f70" id="7f70" class="graf--p graf-after--figure">So, you’re starting a brand new JavaScript front end project or overhauling an old one, and maybe you haven’t kept up with the breakneck pace of the ecosystem. Or you did, but there’s too many things to choose from. React, Flux, Angular, Aurelia, Mocha, Jasmine, Babel, TypeScript, Flow, oh my! By trying to make things simpler, some fall into a trap captured by one of my favorite XKCD comics.</p>
  447. <p name="04b5" id="04b5" class="graf--p graf-after--figure">Well, the good news is the ecosystem is starting to slow down. Projects are merging. Best practices are starting to become clear. People are building on top of existing stuff instead of building new frameworks.</p>
  448. <p name="9f8c" id="9f8c" class="graf--p graf-after--p">As a starting point, here’s my personal picks for most pieces of a modern web application. Some choices are likely controversial and I will only give basic reasoning behind each choices. Keep in mind they’re mostly my opinion based on what I’m seeing in the community and personal experiences. Your mileage may vary.</p>
  449. <h3 name="090f" id="090f" class="graf--h3 graf-after--p">Core library: React</h3>
  450. <p name="c96f" id="c96f" class="graf--p graf-after--figure">The clear winner right now, is <em class="markup--em markup--p-em">React</em>.</p>
  451. <ul class="postList"><li name="c1b1" id="c1b1" class="graf--li graf-after--p">Components all the way down makes your application much easier to reason about.</li><li name="3442" id="3442" class="graf--li graf-after--li">The learning curve is very flat. The important APIs fit would fit on one page.</li><li name="f26e" id="f26e" class="graf--li graf-after--li">JSX is awesome. You get all the power of JavaScript and its tooling when writing your markup.</li><li name="50db" id="50db" class="graf--li graf-after--li">It is the natural match for <a href="https://facebook.github.io/flux/" data-href="https://facebook.github.io/flux/" class="markup--anchor markup--li-anchor" rel="nofollow">Flux</a> and Redux (more on that later).</li><li name="6863" id="6863" class="graf--li graf-after--li">The React community is amazing, and produced many best of breed tools such as Redux (also more on that later).</li><li name="b9fa" id="b9fa" class="graf--li graf-after--li">Writing high quality data flow is much easier in large applications than dealing with 2 way data binding (eg: Knockout)</li><li name="ee28" id="ee28" class="graf--li graf-after--li">If you ever need to do server side rendering, React is where it’s at.</li></ul>
  452. <p name="385a" id="385a" class="graf--p graf-after--li">There’s plenty of monolithic frameworks like Ember, Aurelia and Angular that promise to take care of everything, but the React ecosystem, while requiring a few more decisions (that’s why you’re reading this!), is much more robust. Many of these frameworks, such as Angular 2.0, are playing catch up with React.</p>
  453. <p name="59c8" id="59c8" class="graf--p graf-after--p">Picking React isn’t a technology decision, it’s a <a href="https://blog.formidable.com/using-react-is-a-business-decision-not-a-technology-choice-63c4641c5f7" data-href="https://blog.formidable.com/using-react-is-a-business-decision-not-a-technology-choice-63c4641c5f7" class="markup--anchor markup--p-anchor" rel="nofollow">business decision</a>.</p>
  454. <blockquote name="f370" id="f370" class="graf--blockquote graf-after--p"><em class="markup--em markup--blockquote-em">Bonus points: Once you start working on your mobile apps, you’ll be ready for it thanks to </em><a href="https://facebook.github.io/react-native/" data-href="https://facebook.github.io/react-native/" class="markup--anchor markup--blockquote-anchor" rel="nofollow"><em class="markup--em markup--blockquote-em">React Native</em></a><em class="markup--em markup--blockquote-em">.</em></blockquote>
  455. <h3 name="7629" id="7629" class="graf--h3 graf-after--blockquote">Application life cycle: Redux</h3>
  456. <figure name="05d7" id="05d7" class="graf--figure graf-after--h3"><figcaption class="imageCaption">This isn’t the final logo!</figcaption></figure>
  457. <p name="01c9" id="01c9" class="graf--p graf-after--figure">Now that we have our view and component layer, we need something to manage state and the lifecycle of our application. <a href="https://github.com/reactjs/redux" data-href="https://github.com/reactjs/redux" class="markup--anchor markup--p-anchor" rel="nofollow">Redux</a> is also a clear winner here.</p>
  458. <p name="ac4f" id="ac4f" class="graf--p graf-after--p">Alongside React, Facebook presented a design pattern for one way data flow called <a href="https://facebook.github.io/flux/" data-href="https://facebook.github.io/flux/" class="markup--anchor markup--p-anchor" rel="nofollow">Flux</a>. Flux largely delivered on its promise of simplifying state management, but it also brought with it more questions, such as how to store that state and where to do Ajax requests.</p>
  459. <p name="07a7" id="07a7" class="graf--p graf-after--p">To answer those questions, countless frameworks were built on top of the Flux pattern: Fluxible, Reflux, Alt, Flummox, Lux, Nuclear, Fluxxor and many, many more.</p>
  460. <p name="dcbb" id="dcbb" class="graf--p graf-after--p">One Flux-like implementation eventually caught the community’s attention, and for good reasons: Redux.</p>
  461. <p name="d147" id="d147" class="graf--p graf-after--p">In Redux, almost all of the moving parts are <a href="https://en.wikipedia.org/wiki/Pure_function" data-href="https://en.wikipedia.org/wiki/Pure_function" class="markup--anchor markup--p-anchor" rel="nofollow">pure functions</a>. There is one centralized store and source of truth. Reducer functions are responsible for manipulating data that makes up the store. Everything is much clearer than in vanilla Flux.</p>
  462. <p name="1005" id="1005" class="graf--p graf-after--p">More importantly, learning Redux is a snap. Redux’s author, <a href="https://twitter.com/dan_abramov" data-href="https://twitter.com/dan_abramov" class="markup--anchor markup--p-anchor" rel="nofollow">Dan Abramov</a> is a fantastic teacher, and his training videos are fantastic. Watch the videos, become a Redux expert. I’ve seen a team of engineers go from nearly zero React experience to having a production ready application with top notch code in a few weeks.</p>
  463. <p name="6db4" id="6db4" class="graf--p graf-after--p">Redux’s ecosystem is as top notch as Redux itself. From the nearly magical <a href="https://github.com/gaearon/redux-devtools" data-href="https://github.com/gaearon/redux-devtools" class="markup--anchor markup--p-anchor" rel="nofollow">devtool</a> to the amazing memoization utility <a href="https://github.com/reactjs/reselect" data-href="https://github.com/reactjs/reselect" class="markup--anchor markup--p-anchor" rel="nofollow">reselect</a>, the Redux community got your back.</p>
  464. <p name="4bc5" id="4bc5" class="graf--p graf-after--p">One thing to be careful is the natural instinct to try and abstract away the Redux boilerplate. There’s good reasons behind all those pieces. Make sure you tried it and understand the “why” before trying to blindly improve on it.</p>
  465. <h3 name="f06a" id="f06a" class="graf--h3 graf-after--p">Language: ES6 with Babel. No types (yet)</h3>
  466. <p name="9d29" id="9d29" class="graf--p graf-after--figure">Avoid CoffeeScript. Most of its better features are now in ES6, a standard. Tooling (such as CoffeeLint) is very weak. Its community is also rapidly declining.</p>
  467. <p name="0af6" id="0af6" class="graf--p graf-after--p">ES6 is a standard. Most of it <a href="https://kangax.github.io/compat-table/es6/" data-href="https://kangax.github.io/compat-table/es6/" class="markup--anchor markup--p-anchor" rel="nofollow">is supported</a> in the latest version of major browsers. Babel is an amazing “pluggable” ES6 compiler. Configure it with the right presets for your target browsers and you’re good to go.</p>
  468. <p name="1355" id="1355" class="graf--p graf-after--p">What about types? <a href="http://www.typescriptlang.org/" data-href="http://www.typescriptlang.org/" class="markup--anchor markup--p-anchor" rel="nofollow">TypeScript</a> and <a href="http://flowtype.org/" data-href="http://flowtype.org/" class="markup--anchor markup--p-anchor" rel="nofollow">Flow</a> both offer ways to add static typing to JavaScript, enhancing tooling and catching bugs without needing tests. With that said, I suggest a wait and see approach for now.</p>
  469. <p name="c9f3" id="c9f3" class="graf--p graf-after--p">TypeScript tries too hard to make JavaScript like C# or Java, lacking on modern type system features such as <a href="https://en.wikipedia.org/wiki/Algebraic_data_type" data-href="https://en.wikipedia.org/wiki/Algebraic_data_type" class="markup--anchor markup--p-anchor" rel="nofollow">algebraic data types</a> (and you really want those if you’re going to do static types!). It also doesn’t handle nulls as well as Flow.</p>
  470. <p name="cf56" id="cf56" class="graf--p graf-after--p">Flow can be much more powerful, catching a wider variety of bugs, but it can be hard to setup. It’s also behind Babel in terms of language features and has poor Windows support.</p>
  471. <p name="6cec" id="6cec" class="graf--p graf-after--p">I’ll say something controversial: Types are not nearly as critical to front end development as some will have you believe (the whole argument will have to be in a future blog post). Wait until the type systems are more robust and stick to Babel for now, keeping an eye on Flow as it matures.</p>
  472. <h3 name="3cd7" id="3cd7" class="graf--h3 graf-after--p">Linting &amp; style: ESLint with AirBNB</h3>
  473. <p name="c696" id="c696" class="graf--p graf-after--figure">Another clear winner <a href="http://eslint.org/" data-href="http://eslint.org/" class="markup--anchor markup--p-anchor" rel="nofollow">ESLint</a>. With its React plugin and awesome ES6 support, one could not ask for more of a linter. <a href="http://www.jslint.com/" data-href="http://www.jslint.com/" class="markup--anchor markup--p-anchor" rel="nofollow">JSLint</a> is dated. ESlint does what the <a href="http://jshint.com/" data-href="http://jshint.com/" class="markup--anchor markup--p-anchor" rel="nofollow">JSHint</a> + <a href="http://jscs.info/" data-href="http://jscs.info/" class="markup--anchor markup--p-anchor" rel="nofollow">JSCS</a> combo does in a single tool.</p>
  474. <p name="ff10" id="ff10" class="graf--p graf-after--p">You do have to configure it with your style preferences. I highly recommend <a href="https://github.com/airbnb/javascript" data-href="https://github.com/airbnb/javascript" class="markup--anchor markup--p-anchor" rel="nofollow">AirBNB’s styleguide</a>, most of which can be enforced via the <a href="https://www.npmjs.com/package/eslint-config-airbnb" data-href="https://www.npmjs.com/package/eslint-config-airbnb" class="markup--anchor markup--p-anchor" rel="nofollow">ESlint airbnb config</a>. If your team is the kind that will argue on code style, just use this style guide as gospel and the end all be all of arguments. It isn’t perfect, but the value of having consistent code is highly underestimated.</p>
  475. <p name="0f82" id="0f82" class="graf--p graf-after--p">Once you’re comfortable with it, I’d suggest enabling even more rules. The more that can be caught while typing (with an ESlint plugin for your favorite editor), the less decision fatigue you’ll have and the more productive you and your team will be.</p>
  476. <h3 name="58d1" id="58d1" class="graf--h3 graf-after--p">Dependency management: It’s all about NPM, CommonJS and ES6 modules</h3>
  477. <p name="cf13" id="cf13" class="graf--p graf-after--figure">This one is easy. Use NPM. For everything. Forget about Bower. Build tools such as Browserify and Webpack brings NPM’s power to the web. Versioning is handled easily and you get most of the Node.js ecosystem. Handling of CSS is still less than optimal though.</p>
  478. <p name="e8ed" id="e8ed" class="graf--p graf-after--p">One thing you’ll want to consider is how to handle building on your deployment server. Unlike Ruby’s <a href="http://bundler.io/" data-href="http://bundler.io/" class="markup--anchor markup--p-anchor" rel="nofollow">Bundler</a>, NPM uses wildcard versions, and packages can change between the time you finish coding and you start deploying. Use a <a href="https://docs.npmjs.com/cli/shrinkwrap" data-href="https://docs.npmjs.com/cli/shrinkwrap" class="markup--anchor markup--p-anchor" rel="nofollow">shrinkwrap</a> file to freeze your dependencies (I recommend using <a href="https://github.com/uber/npm-shrinkwrap" data-href="https://github.com/uber/npm-shrinkwrap" class="markup--anchor markup--p-anchor" rel="nofollow">Uber’s shrinkwrap</a> to get more consistent output). Also consider hosting your own private NPM server using something like <a href="https://www.npmjs.com/package/sinopia" data-href="https://www.npmjs.com/package/sinopia" class="markup--anchor markup--p-anchor" rel="nofollow">Sinopia</a>.</p>
  479. <p name="f737" id="f737" class="graf--p graf-after--p">Babel will compile <a href="http://www.2ality.com/2014/09/es6-modules-final.html" data-href="http://www.2ality.com/2014/09/es6-modules-final.html" class="markup--anchor markup--p-anchor" rel="nofollow">ES6 module</a> syntax to <a href="https://nodejs.org/docs/latest/api/modules.html" data-href="https://nodejs.org/docs/latest/api/modules.html" class="markup--anchor markup--p-anchor" rel="nofollow">CommonJS</a>. You’ll get a future proof syntax, and the benefits of static code analysis, such as <a href="http://www.2ality.com/2015/12/webpack-tree-shaking.html" data-href="http://www.2ality.com/2015/12/webpack-tree-shaking.html" class="markup--anchor markup--p-anchor" rel="nofollow">tree shaking</a> when using a build tool that supports it (Webpack 2.0 or <a href="http://http//rollupjs.org/" data-href="http://http//rollupjs.org/" class="markup--anchor markup--p-anchor" rel="nofollow">Rollup</a>).</p>
  480. <h3 name="521b" id="521b" class="graf--h3 graf-after--p">Build tool: Webpack</h3>
  481. <p name="b109" id="b109" class="graf--p graf-after--figure">Unless you fancy adding hundreds of script tags to your pages, you need a build tool to bundle your dependencies. You also need something to allow NPM packages to work in browsers. This is where Webpack comes in.</p>
  482. <p name="12ca" id="12ca" class="graf--p graf-after--p">A year ago you had a lot of potential options here. Your environment, such as Rails’ <a href="https://github.com/rails/sprockets" data-href="https://github.com/rails/sprockets" class="markup--anchor markup--p-anchor" rel="nofollow">sprockets</a> could do it. <a href="http://requirejs.org/" data-href="http://requirejs.org/" class="markup--anchor markup--p-anchor" rel="nofollow">RequireJS</a>, <a href="http://browserify.org/" data-href="http://browserify.org/" class="markup--anchor markup--p-anchor" rel="nofollow">Browserify</a> and Webpack were the JavaScript based solutions. Now, <a href="http://rollupjs.org/" data-href="http://rollupjs.org/" class="markup--anchor markup--p-anchor" rel="nofollow">RollupJS</a> promises to handle ES6 modules optimally.</p>
  483. <p name="5045" id="5045" class="graf--p graf-after--p">After trying them all, I highly recommend Webpack:</p>
  484. <ul class="postList"><li name="f802" id="f802" class="graf--li graf-after--p">It is more opinionated yet can be configured to handle even the craziest scenarios.</li><li name="622d" id="622d" class="graf--li graf-after--li">All main module formats (AMD, CommonJS, globals) are supported.</li><li name="43f1" id="43f1" class="graf--li graf-after--li">It has features to fix broken modules.</li><li name="a9c2" id="a9c2" class="graf--li graf-after--li">It can handle CSS.</li><li name="7344" id="7344" class="graf--li graf-after--li">It has the most comprehensive cache busting/hashing system (if you push your stuff to CDNs).</li><li name="0ab5" id="0ab5" class="graf--li graf-after--li">It supports hot reload out of the box.</li><li name="25e0" id="25e0" class="graf--li graf-after--li">It can load almost <a href="https://webpack.github.io/docs/list-of-loaders.html" data-href="https://webpack.github.io/docs/list-of-loaders.html" class="markup--anchor markup--li-anchor" rel="nofollow">anything</a>.</li><li name="f536" id="f536" class="graf--li graf-after--li">It has an impressive list of <a href="https://github.com/webpack/docs/wiki/optimization" data-href="https://github.com/webpack/docs/wiki/optimization" class="markup--anchor markup--li-anchor" rel="nofollow">optimizations</a>.</li></ul>
  485. <p name="4072" id="4072" class="graf--p graf-after--li">Webpack is also by far the best to handle extremely large SPA applications with built in code splitting and lazy loading.</p>
  486. <p name="6b9f" id="6b9f" class="graf--p graf-after--p">Be warned that the learning curve is brutal! But once you get it, you’ll be rewarded with the best build system available.</p>
  487. <p name="b611" id="b611" class="graf--p graf-after--p">But what about Gulp or Grunt? Webpack is much better at processing assets. They can still be useful if you need to run other kind of tasks though (usually you won’t). For basic tasks (such as running Webpack or ESlint), I recommend simply using <a href="https://docs.npmjs.com/cli/run-script" data-href="https://docs.npmjs.com/cli/run-script" class="markup--anchor markup--p-anchor" rel="nofollow">NPM scripts</a>.</p>
  488. <h3 name="7085" id="7085" class="graf--h3 graf-after--p">Testing: Mocha + Chai + Sinon (but it’s not that simple)</h3>
  489. <p name="74f0" id="74f0" class="graf--p graf-after--figure">There are a LOT of options for unit testing in JavaScript, and you can’t go wrong with any of them. If you have unit tests, that’s already good!</p>
  490. <p name="e8d6" id="e8d6" class="graf--p graf-after--p">Some choices are <a href="http://jasmine.github.io/" data-href="http://jasmine.github.io/" class="markup--anchor markup--p-anchor" rel="nofollow">Jasmine</a>, <a href="https://mochajs.org/" data-href="https://mochajs.org/" class="markup--anchor markup--p-anchor" rel="nofollow">Mocha</a>, <a href="https://github.com/substack/tape" data-href="https://github.com/substack/tape" class="markup--anchor markup--p-anchor" rel="nofollow">Tape</a> and <a href="https://github.com/sindresorhus/ava" data-href="https://github.com/sindresorhus/ava" class="markup--anchor markup--p-anchor" rel="nofollow">Ava</a> and <a href="https://facebook.github.io/jest/" data-href="https://facebook.github.io/jest/" class="markup--anchor markup--p-anchor" rel="nofollow">Jest</a>. I’m sure I’m forgetting some. They all have something they do better than the rest.</p>
  491. <p name="adc0" id="adc0" class="graf--p graf-after--p">My criteria for a test framework are as follow:</p>
  492. <ul class="postList"><li name="7c8a" id="7c8a" class="graf--li graf-after--p">It should work in the browser for ease of debugging</li><li name="2be2" id="2be2" class="graf--li graf-after--li">It should be fast</li><li name="f7c3" id="f7c3" class="graf--li graf-after--li">It should easily handle asynchronous tests</li><li name="dfe1" id="dfe1" class="graf--li graf-after--li">It should be easy to use from the command line</li><li name="79a0" id="79a0" class="graf--li graf-after--li">It should let me use whatever assertion and mock library I want</li></ul>
  493. <p name="2925" id="2925" class="graf--p graf-after--li">The first criteria knocks out Ava (even though it looks awesome) and Jest (auto-mocking isn’t nearly as nice as it sounds, and is very slow anyway).</p>
  494. <p name="362a" id="362a" class="graf--p graf-after--p">You can’t really go wrong with Jasmine, Mocha or Tape. I prefer Chai asserts because of all available plugins and Sinon’s mocks to Jasmine’s built in construct, and Mocha’s asynchronous test support is superior (you don’t have to deal with done callbacks). <a href="https://github.com/domenic/chai-as-promised" data-href="https://github.com/domenic/chai-as-promised" class="markup--anchor markup--p-anchor" rel="nofollow">Chai as Promised</a> is amazing. I highly recommend using <a href="https://github.com/prodatakey/dirty-chai" data-href="https://github.com/prodatakey/dirty-chai" class="markup--anchor markup--p-anchor" rel="nofollow">Dirty Chai</a> to avoid some headaches, though. Webpack’s <a href="https://github.com/webpack/mocha-loader" data-href="https://github.com/webpack/mocha-loader" class="markup--anchor markup--p-anchor" rel="nofollow">mocha-leader</a> let’s you automatically run tests as you code.</p>
  495. <p name="2490" id="2490" class="graf--p graf-after--p">For React specific tooling, look at AirBNB’s <a href="https://github.com/airbnb/enzyme" data-href="https://github.com/airbnb/enzyme" class="markup--anchor markup--p-anchor" rel="nofollow">Enzyme</a> and <a href="https://github.com/jquense/teaspoon" data-href="https://github.com/jquense/teaspoon" class="markup--anchor markup--p-anchor" rel="nofollow">Teaspoon</a> (this isn’t the Rails based Teaspoon).</p>
  496. <p name="64c6" id="64c6" class="graf--p graf-after--p">I really enjoy Mocha’s features and support. If you want something more minimalist, read <a href="https://medium.com/javascript-scene/why-i-use-tape-instead-of-mocha-so-should-you-6aa105d8eaf4" data-href="https://medium.com/javascript-scene/why-i-use-tape-instead-of-mocha-so-should-you-6aa105d8eaf4" class="markup--anchor markup--p-anchor">this article</a> about Tape.</p>
  497. <h3 name="6727" id="6727" class="graf--h3 graf-after--p">Utility library: Lodash is king, but look at Ramda</h3>
  498. <p name="e078" id="e078" class="graf--p graf-after--h3">JavaScript doesn’t have a strong core of utilities like Java or .NET does, so you’ll most likely want to include one.</p>
  499. <p name="3733" id="3733" class="graf--p graf-after--p">Lodash is by far the king and contains the entire kitchen sink. It is also one of the most performant, with features such as <a href="http://filimanjaro.com/blog/2014/introducing-lazy-evaluation/" data-href="http://filimanjaro.com/blog/2014/introducing-lazy-evaluation/" class="markup--anchor markup--p-anchor" rel="nofollow">lazy evaluation</a>. You don’t have to include the whole thing if you don’t want to, either: Lodash lets you include only the functions you use (pretty important considering how large it has become). As of 4.x, Lodash also natively supports an optional “functional” mode for the FP geeks among us.</p>
  500. <p name="2d42" id="2d42" class="graf--p graf-after--p">If you’re into functional programming, however, take a look at the fantastic <a href="http://ramdajs.com/0.19.1/index.html" data-href="http://ramdajs.com/0.19.1/index.html" class="markup--anchor markup--p-anchor" rel="nofollow">Ramda</a>. If you decide to use it, you might still need to include some Lodash functions (Ramda is focused on data manipulation and functional construct almost exclusively), but you’ll get a lot of the power of functional programming languages in a JavaScript friendly way.</p>
  501. <h3 name="cd8b" id="cd8b" class="graf--h3 graf-after--p">Http requests: Just use fetch!</h3>
  502. <p name="0c32" id="0c32" class="graf--p graf-after--h3">Many React applications don’t need jQuery at all anymore. Unless you’re working on a legacy application or have 3rd party libraries that depend on it, there’s no reason to include it. That means you need to replace $.ajax.</p>
  503. <p name="fed1" id="fed1" class="graf--p graf-after--p">I like to keep it simple and just use <a href="https://fetch.spec.whatwg.org/" data-href="https://fetch.spec.whatwg.org/" class="markup--anchor markup--p-anchor" rel="nofollow">fetch</a>. It’s promise based, it’s built in Firefox and Chrome, and it Just Works (tm). For other browsers, you’ll need to include a polyfill. I suggest <a href="https://github.com/matthew-andrews/isomorphic-fetch" data-href="https://github.com/matthew-andrews/isomorphic-fetch" class="markup--anchor markup--p-anchor" rel="nofollow">isomorphic-fetch</a>, to ensure you have all your bases covered, including server side.</p>
  504. <p name="aa5f" id="aa5f" class="graf--p graf-after--p">There are other good libraries such as <a href="https://github.com/mzabriskie/axios" data-href="https://github.com/mzabriskie/axios" class="markup--anchor markup--p-anchor" rel="nofollow">Axios</a>, but I haven’t needed much beyond fetch.</p>
  505. <blockquote name="b4ec" id="b4ec" class="graf--blockquote graf-after--p"><em class="markup--em markup--blockquote-em">For more details about why promises are important, see my post on </em><a href="http://eng.localytics.com/better-asynchronous-javascript/" data-href="http://eng.localytics.com/better-asynchronous-javascript/" class="markup--anchor markup--blockquote-anchor" rel="nofollow"><em class="markup--em markup--blockquote-em">asynchronous programming</em></a><em class="markup--em markup--blockquote-em">.</em></blockquote>
  506. <h3 name="6b95" id="6b95" class="graf--h3 graf-after--blockquote">Styling: Consider CSS modules</h3>
  507. <p name="fc18" id="fc18" class="graf--p graf-after--h3">This is an area I feel is lagging behind. <a href="http://sass-lang.com/" data-href="http://sass-lang.com/" class="markup--anchor markup--p-anchor" rel="nofollow">SASS</a> is the current go to, and <a href="https://github.com/sass/node-sass" data-href="https://github.com/sass/node-sass" class="markup--anchor markup--p-anchor" rel="nofollow">node-sass</a> is a great way to use it in your JavaScript project. That said, I feel it’s missing a lot to be a perfect solution. Lack of reference imports (a way to import just variables and mixins from a file, without duplicating selectors) and native URL rewriting makes it harder than needed to keep things lean and clean in production. node-sass is a C library, and will have to be kept in sync with your Node version.</p>
  508. <p name="fe67" id="fe67" class="graf--p graf-after--p"><a href="http://lesscss.org/" data-href="http://lesscss.org/" class="markup--anchor markup--p-anchor" rel="nofollow">LESS</a> does not suffer from these issues, but has fallen out of favor due to lacking many of SASS’ features.</p>
  509. <p name="ba06" id="ba06" class="graf--p graf-after--p"><a href="https://github.com/postcss/postcss" data-href="https://github.com/postcss/postcss" class="markup--anchor markup--p-anchor" rel="nofollow">PostCSS</a> is much more promising, allowing you to kind of “make your own CSS processor”. I’d recommend using it on its own, or even in ADDITION to your preferred processor for things such as <a href="https://github.com/postcss/autoprefixer" data-href="https://github.com/postcss/autoprefixer" class="markup--anchor markup--p-anchor" rel="nofollow">AutoPrefixer</a> instead of importing a big library like <a href="http://bourbon.io/" data-href="http://bourbon.io/" class="markup--anchor markup--p-anchor" rel="nofollow">Bourbon</a>.</p>
  510. <p name="0c8d" id="0c8d" class="graf--p graf-after--p">One thing worthy of attention though, are <a href="http://glenmaddern.com/articles/css-modules" data-href="http://glenmaddern.com/articles/css-modules" class="markup--anchor markup--p-anchor" rel="nofollow">CSS modules</a>. CSS modules prevents the “cascading” part of CSS, allowing us to keep our dependencies explicit, and prevents conflict. You’ll never have to worry about overriding classes by accident or having to make ultra explicit names for your classes. It works great with React, too. One drawback: <a href="https://github.com/webpack/css-loader" data-href="https://github.com/webpack/css-loader" class="markup--anchor markup--p-anchor" rel="nofollow">css-loader</a> with CSS modules enabled is REALLY slow, so if you plan on having hundreds of kilobytes of CSS, you may want to avoid it until it gets better.</p>
  511. <p name="f9be" id="f9be" class="graf--p graf-after--p">If I was to start a large project from scratch today, I’d probably just use PostCSS along with pre-compiled versions of my favorite CSS libraries.</p>
  512. <p name="64b8" id="64b8" class="graf--p graf-after--p">Regardless of what you choose, you may want to look at my post on <a href="http://eng.localytics.com/faster-sass-builds-with-webpack/" data-href="http://eng.localytics.com/faster-sass-builds-with-webpack/" class="markup--anchor markup--p-anchor" rel="nofollow">CSS performance with Webpack</a>, especially if you go with SASS.</p>
  513. <h3 name="66f3" id="66f3" class="graf--h3 graf-after--p">Universal (Isomorphic) JavaScript: Make sure you need it.</h3>
  514. <p name="6fb6" id="6fb6" class="graf--p graf-after--h3">Universal or Isomorphic JavaScript refers to JavaScript that can be used on both the client and the server. This is primarily used to pre-render pages server side for performance and SEO purpose. Thanks to React, what was once only the realm of giants such as Ebay or Facebook is now within reach of most development shops. It is still not “free” though, adding significant complexity and limiting your options in term of libraries and tooling.</p>
  515. <p name="a086" id="a086" class="graf--p graf-after--p">If you are building a B2C (Business to Customer) website, such as an e-commerce website, you may not have a choice but to go that route. For internal web or B2B (Business to Business) applications however, that kind of initial performance may not be required. Discuss with your product manager to see if the cost:benefit ratio is worth the trouble.</p>
  516. <h3 name="0deb" id="0deb" class="graf--h3 graf-after--p">The API: There’s still no true answer.</h3>
  517. <p name="5788" id="5788" class="graf--p graf-after--h3">It seems everyone lately is asking themselves what to do for API. Everyone is jumping in the <a href="https://en.wikipedia.org/wiki/Representational_state_transfer" data-href="https://en.wikipedia.org/wiki/Representational_state_transfer" class="markup--anchor markup--p-anchor" rel="nofollow">RESTful API</a> bandwagon, and <a href="https://en.wikipedia.org/wiki/SOAP" data-href="https://en.wikipedia.org/wiki/SOAP" class="markup--anchor markup--p-anchor" rel="nofollow">SOAP</a> is a memory of the past. There are various specifications such as <a href="https://en.wikipedia.org/wiki/HATEOAS" data-href="https://en.wikipedia.org/wiki/HATEOAS" class="markup--anchor markup--p-anchor" rel="nofollow">HATEOAS</a>, <a href="http://jsonapi.org/" data-href="http://jsonapi.org/" class="markup--anchor markup--p-anchor" rel="nofollow">JSON API</a>, <a href="http://stateless.co/hal_specification.html" data-href="http://stateless.co/hal_specification.html" class="markup--anchor markup--p-anchor" rel="nofollow">HAL</a>, <a href="https://facebook.github.io/react/blog/2015/05/01/graphql-introduction.html" data-href="https://facebook.github.io/react/blog/2015/05/01/graphql-introduction.html" class="markup--anchor markup--p-anchor" rel="nofollow">GraphQL</a> among others.</p>
  518. <p name="81df" id="81df" class="graf--p graf-after--p">GraphQL gives a large amount of power (and responsibility) to the client, allowing it to make nearly arbitrary queries. Along with <a href="https://facebook.github.io/relay/" data-href="https://facebook.github.io/relay/" class="markup--anchor markup--p-anchor" rel="nofollow">Relay</a>, it handles client state and caching for you. Implementing the server side portion of GraphQL is difficult and most of the documentation is for Node though.</p>
  519. <p name="031e" id="031e" class="graf--p graf-after--p">Netflix’s <a href="https://github.com/Netflix/falcor" data-href="https://github.com/Netflix/falcor" class="markup--anchor markup--p-anchor" rel="nofollow">Falcor</a> looks like it will eventually give us a lot of what GraphQL/Relay offers, with simpler server requirements. It is however only a developer preview and not ready for prime time.</p>
  520. <p name="829a" id="829a" class="graf--p graf-after--p">All the well known specifications have their quirks. Some are overly complex. Some only handle reads and don’t cover update. Some stray significantly from REST. Many people choose to make their own, but then have to solve all the design problems on their own.</p>
  521. <p name="4ca3" id="4ca3" class="graf--p graf-after--p">I don’t think any solutions out there is a slam dunk, but here’s what I think your API should have:</p>
  522. <ul class="postList"><li name="00c1" id="00c1" class="graf--li graf-after--p">It should be predictable. Your endpoints should follow consistent conventions.</li><li name="2e03" id="2e03" class="graf--li graf-after--li">It should allow fetching multiple entities in one round trip: needing 15 queries to fetch everything you need on page load will give poor performance.</li><li name="fab5" id="fab5" class="graf--li graf-after--li">Make sure you have a good update story: many specifications only covers reads, and you’ll need to update stuff sometimes.</li><li name="6adc" id="6adc" class="graf--li graf-after--li">It should be easy to debug: looking at the Chrome inspector’s network tab should easily let me see what happened.</li><li name="05e6" id="05e6" class="graf--li graf-after--li">It should be easy to consume: I should be able to easily consume it with fetch, or have a well supported client library (like Relay)</li></ul>
  523. <p name="6fd1" id="6fd1" class="graf--p graf-after--li">I haven’t found a solution that covers all of the above. If there is one, let me know.</p>
  524. <p name="f36c" id="f36c" class="graf--p graf-after--p">Consider looking at <a href="http://swagger.io/" data-href="http://swagger.io/" class="markup--anchor markup--p-anchor" rel="nofollow">Swagger</a> to document your API if you go the standard RESTful path.</p>
  525. <h3 name="6599" id="6599" class="graf--h3 graf-after--p">Desktop applications: Electron.</h3>
  526. <p name="7582" id="7582" class="graf--p graf-after--h3"><a href="https://github.com/atom/electron" data-href="https://github.com/atom/electron" class="markup--anchor markup--p-anchor" rel="nofollow">Electron</a> is the foundation of the great <a href="https://atom.io/" data-href="https://atom.io/" class="markup--anchor markup--p-anchor" rel="nofollow">Atom</a> editor and can be used to make your own applications. At it’s core, it is a version of Node that can open Chrome windows to render a GUI, and has access to the operating system’s native APIs without a browser’s typical security sandboxing. You’ll be able to package your application and distribute it like any other desktop application, complete with an installer and auto-updates.</p>
  527. <p name="febc" id="febc" class="graf--p graf-after--p">This is one of the easiest ways to make an application that can run on OSX, Windows and Linux while reusing all the tools listed above. It is well documented and has a very active community.</p>
  528. <p name="0053" id="0053" class="graf--p graf-after--p">You may have heard of <a href="http://nwjs.io/" data-href="http://nwjs.io/" class="markup--anchor markup--p-anchor" rel="nofollow">nw.js</a> (formerly node-webkit) which has existed longer (and does almost the same thing), but Electron is now more stable and is easier to use.</p>
  529. <p name="de1e" id="de1e" class="graf--p graf-after--p">Take a look at this <a href="https://github.com/chentsulin/electron-react-boilerplate" data-href="https://github.com/chentsulin/electron-react-boilerplate" class="markup--anchor markup--p-anchor" rel="nofollow">great boilerplate</a> to play around with Electron, React and hot reload. You’ll probably want to start from scratch if you’re serious about making your own application so you understand how all the pieces work.</p>
  530. <h3 name="829b" id="829b" class="graf--h3 graf-after--p">Who to follow and where to learn more?</h3>
  531. <p name="feaa" id="feaa" class="graf--p graf-after--h3">This is a place where I’m falling short, but on Twitter I follow the following people:</p>
  532. <ul class="postList"><li name="0050" id="0050" class="graf--li graf-after--p"><a href="https://github.com/gaearon" data-href="https://github.com/gaearon" class="markup--anchor markup--li-anchor" rel="nofollow">Dan Abramov</a>, author of Redux</li><li name="2539" id="2539" class="graf--li graf-after--li"><a href="https://twitter.com/Vjeux" data-href="https://twitter.com/Vjeux" class="markup--anchor markup--li-anchor" rel="nofollow">Christopher Chedeau</a> aka Vjeux, a React developer at Facebook very active in the community.</li><li name="dd61" id="dd61" class="graf--li graf-after--li"><a href="https://github.com/jeffmo" data-href="https://github.com/jeffmo" class="markup--anchor markup--li-anchor" rel="nofollow">Jeff Morrison</a>, one of the main Flow contributors.</li><li name="84be" id="84be" class="graf--li graf-after--li"><a href="https://twitter.com/sebmarkbage" data-href="https://twitter.com/sebmarkbage" class="markup--anchor markup--li-anchor" rel="nofollow">Sebastian Markbåge</a>, another React developer at Facebook, involved with the TC39</li><li name="05b9" id="05b9" class="graf--li graf-after--li"><a href="https://twitter.com/floydophone" data-href="https://twitter.com/floydophone" class="markup--anchor markup--li-anchor" rel="nofollow">Pete Hunt</a>. Originally from Instagram and Facebook, famous for his <a href="https://www.youtube.com/watch?v=x7cQ3mrcKaY" data-href="https://www.youtube.com/watch?v=x7cQ3mrcKaY" class="markup--anchor markup--li-anchor" rel="nofollow">Rethinking best practices</a> talk, partly responsible for putting React on the map.</li><li name="2735" id="2735" class="graf--li graf-after--li"><a href="https://twitter.com/reactjs" data-href="https://twitter.com/reactjs" class="markup--anchor markup--li-anchor" rel="nofollow">React</a>, because duh.</li><li name="a9f4" id="a9f4" class="graf--li graf-after--li">The above are more are aggregated in <a href="https://twitter.com/oguzbilgic/lists/react-influencers" data-href="https://twitter.com/oguzbilgic/lists/react-influencers" class="markup--anchor markup--li-anchor" rel="nofollow">React Influencers</a></li></ul>
  533. <p name="2cd8" id="2cd8" class="graf--p graf-after--li">While there’s many more worth noting, those people retweet almost anything worth looking at, so they’re a good start.</p>
  534. <p name="b1f6" id="b1f6" class="graf--p graf-after--p">Consider reading Pete Hunt’s <a href="https://github.com/petehunt/react-howto" data-href="https://github.com/petehunt/react-howto" class="markup--anchor markup--p-anchor" rel="nofollow">Learning React</a>. Follow the order!</p>
  535. <p name="39a6" id="39a6" class="graf--p graf-after--p">Dan Abramov published the <a href="https://egghead.io/series/getting-started-with-redux" data-href="https://egghead.io/series/getting-started-with-redux" class="markup--anchor markup--p-anchor" rel="nofollow">Getting started with Redux</a> video series. I can’t overstate how amazing it is at teaching Redux.</p>
  536. <p name="8577" id="8577" class="graf--p graf-after--p">Dan also published <a href="https://medium.com/@dan_abramov/my-react-list-862227952a8c#.740o0wzee" data-href="https://medium.com/@dan_abramov/my-react-list-862227952a8c#.740o0wzee" class="markup--anchor markup--p-anchor">his own list</a>, and it’s probably better than mine.</p>
  537. <p name="fbcb" id="fbcb" class="graf--p graf-after--p">Mark Erikson’s collection of <a href="https://github.com/markerikson/react-redux-links" data-href="https://github.com/markerikson/react-redux-links" class="markup--anchor markup--p-anchor" rel="nofollow">React/Redux links</a> is an ever growing gold mine.</p>
  538. <p name="d25a" id="d25a" class="graf--p graf-after--p">Read <a href="http://jlongster.com/Removing-User-Interface-Complexity,-or-Why-React-is-Awesome" data-href="http://jlongster.com/Removing-User-Interface-Complexity,-or-Why-React-is-Awesome" class="markup--anchor markup--p-anchor" rel="nofollow">Removing user interface complexity, or why React is awesome</a> to get a walkthrough of how React is designed and why.</p>
  539. <h3 name="f58c" id="f58c" class="graf--h3 graf-after--p">If you don’t need it, don’t use it</h3>
  540. <p name="100c" id="100c" class="graf--p graf-after--h3">The JavaScript ecosystem is thriving and moving quickly, but there’s finally an end at the light of the tunnel. Best practices are no longer changing constantly, and it is becoming increasingly clear which tools are worth learning.</p>
  541. <p name="5316" id="5316" class="graf--p graf-after--p">The most important thing to remember is to keep it simple and only use what you need.</p>
  542. <p name="5310" id="5310" class="graf--p graf-after--p">Is your application only 2–3 screens? Then you don’t need a router. Are you making a single page? Then you don’t even need Redux, just use React’s own state. Are you making a simple CRUD application? You don’t need Relay. Are you learning ES6? You don’t need Async/Await or Decorators. Are you just starting to learn React? You don’t need Hot reload and server rendering. Are you starting out with Webpack? You don’t need code splitting and multiple chunks. Are you starting with Redux? You don’t need Redux-Form or Redux-Sagas.</p>
  543. <p name="d089" id="d089" class="graf--p graf-after--p">Keep it simple, one thing at a time, and you’ll wonder why people ever complained about JavaScript fatigue.</p>
  544. <h3 name="d085" id="d085" class="graf--h3 graf-after--p">Did I miss anything?</h3>
  545. <p name="de51" id="de51" class="graf--p graf-after--h3 graf--last">And there you have it, my view of the current state of JavaScript. Do you think I forgot an important category? Do you think I’m objectively wrong on one of these choices? Do you recommend something else? Let me know!</p>
  546. </article>
  547. </section>
  548. <nav id="jumpto">
  549. <p>
  550. <a href="/david/blog/">Accueil du blog</a> |
  551. <a href="https://medium.com/@fward/state-of-the-art-javascript-in-2016-ab67fc68eb0b">Source originale</a> |
  552. <a href="/david/stream/2019/">Accueil du flux</a>
  553. </p>
  554. </nav>
  555. <footer>
  556. <div>
  557. <img src="/static/david/david-larlet-avatar.jpg" loading="lazy" class="avatar" width="200" height="200">
  558. <p>
  559. Bonjour/Hi!
  560. Je suis <a href="/david/" title="Profil public">David&nbsp;Larlet</a>, je vis actuellement à Montréal et j’alimente cet espace depuis 15 ans. <br>
  561. Si tu as apprécié cette lecture, n’hésite pas à poursuivre ton exploration. Par exemple via les <a href="/david/blog/" title="Expériences bienveillantes">réflexions bimestrielles</a>, la <a href="/david/stream/2019/" title="Pensées (dés)articulées">veille hebdomadaire</a> ou en t’abonnant au <a href="/david/log/" title="S’abonner aux publications via RSS">flux RSS</a> (<a href="/david/blog/2019/flux-rss/" title="Tiens c’est quoi un flux RSS ?">so 2005</a>).
  562. </p>
  563. <p>
  564. Je m’intéresse à la place que je peux avoir dans ce monde. En tant qu’humain, en tant que membre d’une famille et en tant qu’associé d’une coopérative. De temps en temps, je fais aussi des <a href="https://github.com/davidbgk" title="Principalement sur Github mais aussi ailleurs">trucs techniques</a>. Et encore plus rarement, <a href="/david/talks/" title="En ce moment je laisse plutôt la place aux autres">j’en parle</a>.
  565. </p>
  566. <p>
  567. Voici quelques articles choisis :
  568. <a href="/david/blog/2019/faire-equipe/" title="Accéder à l’article complet">Faire équipe</a>,
  569. <a href="/david/blog/2018/bivouac-automnal/" title="Accéder à l’article complet">Bivouac automnal</a>,
  570. <a href="/david/blog/2018/commodite-effondrement/" title="Accéder à l’article complet">Commodité et effondrement</a>,
  571. <a href="/david/blog/2017/donnees-communs/" title="Accéder à l’article complet">Des données aux communs</a>,
  572. <a href="/david/blog/2016/accompagner-enfant/" title="Accéder à l’article complet">Accompagner un enfant</a>,
  573. <a href="/david/blog/2016/senior-developer/" title="Accéder à l’article complet">Senior developer</a>,
  574. <a href="/david/blog/2016/illusion-sociale/" title="Accéder à l’article complet">L’illusion sociale</a>,
  575. <a href="/david/blog/2016/instantane-scopyleft/" title="Accéder à l’article complet">Instantané Scopyleft</a>,
  576. <a href="/david/blog/2016/enseigner-web/" title="Accéder à l’article complet">Enseigner le Web</a>,
  577. <a href="/david/blog/2016/simplicite-defaut/" title="Accéder à l’article complet">Simplicité par défaut</a>,
  578. <a href="/david/blog/2016/minimalisme-esthetique/" title="Accéder à l’article complet">Minimalisme et esthétique</a>,
  579. <a href="/david/blog/2014/un-web-omni-present/" title="Accéder à l’article complet">Un web omni-présent</a>,
  580. <a href="/david/blog/2014/manifeste-developpeur/" title="Accéder à l’article complet">Manifeste de développeur</a>,
  581. <a href="/david/blog/2013/confort-convivialite/" title="Accéder à l’article complet">Confort et convivialité</a>,
  582. <a href="/david/blog/2013/testament-numerique/" title="Accéder à l’article complet">Testament numérique</a>,
  583. et <a href="/david/blog/" title="Accéder aux archives">bien d’autres…</a>
  584. </p>
  585. <p>
  586. On peut <a href="mailto:david%40larlet.fr" title="Envoyer un courriel">échanger par courriel</a>. Si éventuellement tu souhaites que l’on travaille ensemble, tu devrais commencer par consulter le <a href="http://larlet.com">profil dédié à mon activité professionnelle</a> et/ou contacter directement <a href="http://scopyleft.fr/">scopyleft</a>, la <abbr title="Société coopérative et participative">SCOP</abbr> dont je fais partie depuis six ans. Je recommande au préalable de lire <a href="/david/blog/2018/cout-site/" title="Attention ce qui va suivre peut vous choquer">combien coûte un site</a> et pourquoi je suis plutôt favorable à une <a href="/david/pro/devis/" title="Discutons-en !">non-demande de devis</a>.
  587. </p>
  588. <p>
  589. Je ne traque pas ta navigation mais mon
  590. <abbr title="Alwaysdata, 62 rue Tiquetonne 75002 Paris, +33.184162340">hébergeur</abbr>
  591. conserve des logs d’accès.
  592. </p>
  593. </div>
  594. </footer>
  595. <script type="text/javascript">
  596. ;(_ => {
  597. const jumper = document.getElementById('jumper')
  598. jumper.addEventListener('click', e => {
  599. e.preventDefault()
  600. const anchor = e.target.getAttribute('href')
  601. const targetEl = document.getElementById(anchor.substring(1))
  602. targetEl.scrollIntoView({behavior: 'smooth'})
  603. })
  604. })()
  605. </script>