<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Jan Paul Posma on Medium]]></title>
        <description><![CDATA[Stories by Jan Paul Posma on Medium]]></description>
        <link>https://medium.com/@JanPaul123?source=rss-51e73dbd24ba------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/0*xDQejzi6UugOKsrT.jpeg</url>
            <title>Stories by Jan Paul Posma on Medium</title>
            <link>https://medium.com/@JanPaul123?source=rss-51e73dbd24ba------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sun, 24 May 2026 01:48:58 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@JanPaul123/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com" rel="hub"/>
        <item>
            <title><![CDATA[Request queuing]]></title>
            <link>https://medium.com/@JanPaul123/request-queuing-965ea7f917f7?source=rss-51e73dbd24ba------2</link>
            <guid isPermaLink="false">https://medium.com/p/965ea7f917f7</guid>
            <category><![CDATA[product-at-remix]]></category>
            <category><![CDATA[public-transit]]></category>
            <category><![CDATA[programming]]></category>
            <category><![CDATA[design-and-development]]></category>
            <category><![CDATA[product]]></category>
            <dc:creator><![CDATA[Jan Paul Posma]]></dc:creator>
            <pubDate>Thu, 17 May 2018 05:00:28 GMT</pubDate>
            <atom:updated>2018-08-17T02:58:17.874Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*RZkGtfVeoN0FyQUlAGkZOA.jpeg" /><figcaption>This article is part of Remix’s series on the software engineering challenges we face. In this installment, Remix engineer Jan Paul Posma talks about managing communication between the front-end browser application and the back-end server. (Photo: <a href="https://www.flickr.com/photos/hktang/4243300265/in/photolist-7sY2kp-7qqLVH-6sry1L-6srxXj-aLv7Yp-C5o73-5WVmVK-5WVJ2X-7YiSK-5WVM38-5Adtde-9YXXMn-rDS4R6-9j2zkk-qjgT9m-WfcVG3-dcXgXU-pPcUnL-pXcgU4-bTY3u4-GE9zYX-b4vjUn-bUnkip-6xfFVu-bE87xA-7rZ5Ud-6kiqCD-4trp9p-8Gg4Jc-e2PU8G-5AhS55-5WZxWj-5WZrjh-5WV5Np-tnT8w-bo3r2D-4N6DkN-2woH2r-cPJq4m-mzLSdd-6SEpm6-5jeJEG-5WVqzk-5WUXZa-deoZGJ-cguM5j-ayef6k-6yKUcL-9Za3Wq-bCgv3M">Xiaojun Deng</a>)</figcaption></figure><p>Remix’s products are write-heavy. In our transit planning product, users can quickly sketch out changes to bus routes, and Remix will show the resulting demographic and cost updates.</p><p>To manage these updates, we initially started with simple XHR requests and callbacks. Save something, and when that’s done, refetch the demographics and costs:</p><pre>function saveBusStops(project_id, stops) {<br>  xhr({ <br>    method: &#39;POST&#39;, <br>    url: `${project_id}/bus_stops`, <br>    json: {stops},<br>  }).then(() =&gt; <br>    xhr({ url: `${project_id}/stats`})<br>      .then((body) =&gt; updateStats(body))<br>  );<br>}</pre><p>This has a problem though. While drawing a new bus route, saveBusStops would get called many times in a row. So first we debounced it, every second or so:</p><pre>const saveBusStops = debounce((project_id, stops) =&gt; {<br>  xhr({ <br>    method: &#39;POST&#39;, <br>    url: `${project_id}/bus_stops`, <br>    json: {stops},<br>  }).then(() =&gt; <br>    xhr({ url: `${project_id}/stats`})<br>      .then((body) =&gt; updateStats(body))<br>  );<br>}, 3000);</pre><p>This worked fine for a while, but at some point we got larger customers, for which the /stats call would take several seconds to complete. This meant that sometimes the /stats call was still in progress when new bus stops were saved, which led to our <strong>core problem: overlapping API calls conflict with each other.</strong> While we’re querying the database in the /stats endpoint, the data changes because of a later /bus_stops call, which could cause the /stats endpoint to return incorrect data in the best case, or crash in the worst case (e.g. because of missing/changed ids).</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/991/1*lRKzXp8cruBZBVYP5np1Kw.gif" /><figcaption>We refetch all sorts of things when editing a route.</figcaption></figure><h3>Serializable transactions</h3><p>The bugs resulting from this were hard to anticipate, track down, and fix. Initially we tried to solve this using serializable database transactions for all of our endpoints, guaranteeing a sequential order to transactions. While this fixed the bugs, it had a couple of downsides:</p><ul><li>PostgreSQL implements serializable transactions by throwing an error if two transactions conflict. You then have to retry those transactions. If those conflicts happen a lot (which for us they did), this significantly slows down endpoints.</li><li>Slower endpoints meant that the problem of conflicts got worse, as more endpoint calls would conflict with each other.</li><li>Our serializable transactions would take a lot of locks. When there are too many locks, they become less granular. Often entire tables would be locked by a transaction, which would cause them to routinely conflict with other transactions.</li></ul><h3>Other problems</h3><p>Besides the problems with serializable transactions, the frontend code devolved into callback hell. Instead of just having to call the /stats endpoint, we introduced many different analytical models, which the user could turn on or off at will, and which all had different dependencies on different data that could change. This became hard to maintain.</p><p>We also ended up with a lot of debounced functions, with high timeouts, in order to mitigate the issues with slow endpoints. This meant that the user would have to wait sometimes several seconds before we would even start persisting their changes, and even longer before the models would refresh. This was a terrible user experience, especially given one of our main value propositions is a snappy, live-updating product.</p><p>So we had to come up with something better.</p><h3>Introducing xhrQueue</h3><p>We realised that we have a particular usage pattern. Each project could only be edited by one user at the time: the author of that project. Collaboration was still possible, but done by copying projects. This worked pretty well for our users, so we decided to exploit this usage pattern to make a simple change to solve a lot of our problems.</p><p>We made one additional assumption: that each user would typically be editing each project in only one browser window, on only one computer. We could even easily enforce this (by having the browser window request a “lock” on the project), but we found that in most cases this assumption holds well enough.</p><p>With these assumptions, we can move the sequential ordering of transactions from the database to the frontend, by simply queueing up network requests. This has a few advantages:</p><ul><li>No need for serializable transactions on the backend, removing all the problems of having to retry transactions, not granular enough locks, and so on.</li><li>No need for callbacks, just queue requests up in order.</li><li>Instead of debouncing, we can instead just remove duplicate requests from the queue.</li></ul><p>This is how code ends up looking:</p><pre>function saveBusStops(project_id, stops) {<br>  window.xhrQueue.xhr({<br>    method: &#39;POST&#39;,<br>    url: `${project_id}/bus_stops`,<br>    json: {stops},<br>    ignorePreviousByUrl: true,<br>  });<br>  window.xhrQueue.xhr({<br>    url: `${project_id}/stats`,<br>    ignorePreviousByUrl: true,<br>  }, (error, response, body) =&gt; updateStats(body));<br>}</pre><p>The ignorePreviousByUrl will remove any existing requests in the queue that have the same URL.</p><h3>More benefits</h3><p>Once you have the basic model of a queue for endpoint requests, you can layer some optimizations on top. One would be to specify which requests are allowed to run in parallel, since they don’t conflict with each other. For now we have a simple optimisation like that: GET requests are allowed to run in parallel, since they are assumed not to mutate data. You can override this using overrideQueueItemType: &#39;read&#39; or &#39;write&#39;.</p><p>Another thing you basically get for free, is a system to retry saving when the connection drops. Just retry failed items in the queue until it works again!</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/991/1*NnZ1iMrGuRuMRYTNdowVCA.gif" /><figcaption>When the connection drops, we can easily retry until the connection comes back online, and then finish going through the queue.</figcaption></figure><h3>Conclusion</h3><p>For us, queuing up requests enabled us to build a better user experience while simultaneously resolving some tricky database issues.</p><p>We released the xhrQueue as <a href="https://github.com/remix/xhr-queue">open source</a>. If your application has similar usage patterns, give it a try, and let us know how it works for you. We’d happily take contributions to make it better.</p><p>In the future we might want to loosen our assumptions and allow full-blown collaboration by multiple users on one project (<a href="https://en.wikipedia.org/wiki/Operational_transformation">OT!</a>), but until then, this is a great stepping stone.</p><p><em>If any of this interests you, take a look at our </em><a href="https://www.remix.com/jobs"><em>open roles</em></a><em>. We use all this to help create more livable cities. :)</em></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=965ea7f917f7" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Remix’s Tech Stack: Jasmine]]></title>
            <link>https://medium.com/@JanPaul123/remixs-tech-stack-jasmine-f492446b5b05?source=rss-51e73dbd24ba------2</link>
            <guid isPermaLink="false">https://medium.com/p/f492446b5b05</guid>
            <category><![CDATA[jasmine]]></category>
            <category><![CDATA[javascript]]></category>
            <category><![CDATA[engineering]]></category>
            <dc:creator><![CDATA[Jan Paul Posma]]></dc:creator>
            <pubDate>Sat, 16 Sep 2017 00:08:19 GMT</pubDate>
            <atom:updated>2017-09-16T00:08:19.448Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*CLdywFJwqT5Jcimhjgzk-g.jpeg" /><figcaption><em>This is the latest in a series about Remix’s tech stack. We’ve worked hard on setting up our ideal stack, and we’re proud of what we’ve built. Now it’s time to share it.</em></figcaption></figure><h3>How We Configure Jasmine</h3><p>Testing front-end code is tricky. It’s full of asynchronicity (back-and-forths with the user and the back-end), browser-specific behavior (and bugs), visuals (the correctness of which can be fuzzy), and state (management of which is still much less mature than on the back-end, where we have fantastic decades-old databases). Therefore, it’s extra important to have good automated testing tools for the front-end.</p><p>At Remix we use various tools for this, which we’ve covered in the <a href="https://blog.remix.com/preventing-regressions-f9cac1180a9">Preventing Regressions</a> article. This time we’ll focus on Jasmine, our unit testing tool. Over the last few years we’ve built some configuration on top of it, all for very specific reasons, which we’ll look at in detail.</p><p>Our full setup is available as open source <a href="https://github.com/remix/remix-jasmine-setup">here</a>. Maybe some day some of this configuration can be added to Jasmine by default! 📈</p><h3>Random Test Order</h3><p>First of all, we want to run our tests in random order, <a href="http://jakegoulding.com/blog/2012/10/18/run-your-tests-in-a-deterministic-random-order/">to prevent dependencies between tests</a>. (This is one of the reasons we use Jasmine and not Mocha, which <a href="https://github.com/mochajs/mocha/issues/902">doesn’t support random test order</a>.)</p><pre>// Prevent dependencies between tests by randomizing tests.<br>jasmine.getEnv().randomizeTests(true);</pre><p>The downside of this is that tests that are dependent on each other will sporadically fail based on the test order, which can be hard to debug. When you see such a failure in CI, you want to be able to run the tests locally in the same order so you can debug the problem. For this we can print the seed to the console:</p><pre>// Generate our own seed so we can print it in the console,<br>// for CI debugging.<br>const seed = jasmine.getEnv().seed() ||<br>  String(Math.random()).slice(-5); // Same seed function as Jasmine<br>jasmine.getEnv().seed(seed);<br>console.log(`Jasmine seed used: ${seed}`);</pre><p>Now we can just plug the seed into the URL like ?seed=12345. 🎉</p><h3>Asynchronous Behavior</h3><p>The trickiest thing in testing front-end code is probably dealing with asynchronous behavior, so we’ve spent a lot of time on setting this up right. There are two main approaches to this:</p><ol><li>Keep the application code asynchronous, and in tests wait until the code is finished running before making assertions.</li><li>Stub asynchronous browser functions by introducing an artificial clock that we can move forward arbitrarily in tests to simulate time moving forward.</li></ol><p>(1) has the downside of having to wait in tests for application code to finish. It can also be difficult to know exactly when it has finished—you have to always pass through a callback or <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise">Promise</a> for the test to use. So we went with option (2).</p><p>First we set up fake clock and date, which is built into Jasmine. This replaces functions like setTimeout and new Date(). It’s important to do this before any libraries and polyfills are loaded, as they can store handles to those functions.</p><pre>jasmine.clock().mockDate();<br>jasmine.clock().install();</pre><p>Then there are some other asynchronous functions that Jasmine currently doesn’t replace, so we replace them ourselves. One example is setImmediate, which we can replace by a timeout with 0 milliseconds:</p><pre>window.setImmediate = fn =&gt; window.setTimeout(fn, 0);<br>window.clearImmediate = id =&gt; window.clearTimeout(id);</pre><p>Some libraries use it internally, in which case you’d have to call jasmine.clock().tick(1) in your tests. Another example is requestAnimationFrame, but there we want to replace it with at least 1 millisecond per frame, so we can step through it if we need to:</p><pre>window.requestAnimationFrame = fn =&gt; window.setTimeout(fn, 1);<br>window.cancelAnimationFrame = id =&gt; window.clearTimeout(id);</pre><p>We also install jasmine.Ajax to stub out calls to the server:</p><pre>jasmine.Ajax.install();</pre><p>Now there should not be any asynchronous waiting in tests any more! So we can tighten the timeout on asynchronous tests (in case you still want to use <a href="https://jasmine.github.io/api/2.8/global.html#implementationCallback">that syntax</a>):</p><pre>jasmine.DEFAULT_TIMEOUT_INTERVAL = 10; // milliseconds</pre><h4>Asynchronous Test Example</h4><p>To see what an asynchronous test looks like with this setup, let’s try to test this function:</p><pre>function ajaxCallWithTimeout(url, timeoutMs, onFinish, onTimeout) {<br>  let done = false;</pre><pre>  const xhr = new XMLHttpRequest();<br>  xhr.onreadystatechange = () =&gt; {<br>    if (!done) onFinish(xhr);<br>    done = true;<br>  };<br>  xhr.open(&#39;GET&#39;, url);<br>  xhr.send();</pre><pre>  setTimeout(() =&gt; {<br>    if (!done) onTimeout();<br>    done = true;<br>  }, timeoutMs);<br>}</pre><p>This is what the happy-path test would look like:</p><pre>it(&#39;calls `onFinish` when the request comes back in time&#39;, () =&gt; {<br>  const onFinish = jasmine.createSpy(&#39;onFinish&#39;);<br>  const onTimeout = jasmine.createSpy(&#39;onTimeout&#39;);</pre><pre>  ajaxCallWithTimeout(&#39;test.json&#39;, 100, onFinish, onTimeout);</pre><pre>  jasmine.clock().tick(99); // Move clock forward by 99ms.<br>  jasmine.Ajax.requests.mostRecent().respondWith({ status: 200 });</pre><pre>  expect(onFinish).toHaveBeenCalled();<br>  expect(onTimeout).not.toHaveBeenCalled();</pre><pre>  jasmine.clock().tick(20); // Move clock forward some more<br>  expect(onTimeout).not.toHaveBeenCalled(); // Still not called.<br>});</pre><p>Hurray for arbitrarily manipulating time! ⏰</p><h4>Tightening Asynchronous Tests</h4><p>We noticed that we often want to make sure that at the end of a test nothing changes if you move forward time a bit more, like the last two lines of the test above. Typically this means that no more callbacks should be called, and no more Ajax requests should be made. We haven’t yet figured out how to do the first part (no more callbacks), but we did tighten against any more Ajax requests:</p><pre>afterEach(() =&gt; {<br>  jasmine.Ajax.requests.reset();<br>  jasmine.Ajax.stubs.reset();</pre><pre>  jasmine.clock().tick(1000000);</pre><pre>  if (jasmine.Ajax.requests.count() &gt; 0) {<br>    fail(&#39;Requests were made after the test.&#39;);<br>  }<br>  if (jasmine.Ajax.stubs.count &gt; 0) {<br>    fail(&#39;Stubs were set after the test.&#39;);<br>  }<br>});</pre><h4>Promises</h4><p>One more source of asynchronicity is Promises. According to the spec, <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/then#Return_value">handler functions should execute asynchronously</a>. Because of this we use a <a href="https://github.com/taylorhakes/promise-polyfill">Promise polyfill</a> that internally uses setTimeout, even if the browser we run our tests in supports Promises natively.</p><p>We can even write a test to make sure Promises use the Jasmine clock:</p><pre>it(&#39;uses the Jasmine clock&#39;, () =&gt; {<br>  const onThen = jasmine.createSpy(&#39;onThen&#39;);<br>  window.Promise.resolve().then(onThen);<br>  expect(onThen).not.toHaveBeenCalled();</pre><pre>  jasmine.clock().tick(1);<br>  expect(onThen).toHaveBeenCalled();<br>});</pre><h3>Tightening Tests</h3><p>We try to tighten our tests as much as possible in order to catch as many bugs as possible, like how we tightened asynchronous tests above. Another example is not allowing logging to the console in any way. This catches errors and warnings from libraries, like <a href="https://facebook.github.io/react/docs/typechecking-with-proptypes.html">React’s PropTypes</a>. When legitimately logging to the console, you can still stub out the console method, which we do in a few places. We also ignore some logging by tools:</p><pre>const oldConsoleFunctions = {};<br>Object.keys(console).forEach(key =&gt; {<br>  if (typeof console[key] === &#39;function&#39;) {<br>    oldConsoleFunctions[key] = console[key];<br>    console[key] = (...args) =&gt; {<br>      // Detect Karma logging to console.error <br>      // by looking at the stack trace.<br>      if (key === &#39;error&#39;) {<br>        const error = new Error();<br>        if (error.stack &amp;&amp; <br>            error.stack.match(/KarmaReporter\.specDone/)) {<br>          return;<br>        }<br>      }</pre><pre>      // Don&#39;t fail tests when React shamelessly self-promotes.<br>      if (args[0].match &amp;&amp; args[0].match(/React DevTools/)) {<br>        return;<br>      }</pre><pre>      oldConsoleFunctions[key].apply(console, args);<br>      throw new Error(&quot;Don&#39;t log to console during tests&quot;);<br>    };<br>  }<br>});</pre><p>Another way to tighten tests is to make sure there are no DOM elements from tests left on the page after running a test, as that could leak state between tests. Since we always mount elements on &lt;body&gt;, we can just check if its number of children have changed:</p><pre>let numberOfElementsInBody;<br>beforeEach(() =&gt; {<br>  numberOfElementsInBody = document.body.childElementCount;<br>});<br>afterEach(() =&gt; {<br>  if (document.body.childElementCount !== numberOfElementsInBody) {<br>    throw new Error(&#39;Forgot to clean up elements in &lt;body&gt;&#39;);<br>  }<br>});</pre><p>This is an assertion on global state, to make sure it doesn’t leak between tests. The alternative would be to clear out the global state before each test (e.g. having a special &lt;div&gt; that all DOM elements get mounted into, and clearing it out before each test), which also works.</p><p>These are just some examples we came up with as we developed our product, but the principle of tightening tests can be more widely applied to any invariants you might have in your application. For example, on the backend you could check complicated database invariants that cannot be expressed as table constraints.</p><h3>Conclusion</h3><p>We showed how we configure Jasmine, but the underlying ideas are more widely applicable. For example, on the backend we use <a href="http://rspec.info/">RSpec</a>, which supports random test order, we stub out external requests using <a href="https://github.com/bblimke/webmock">WebMock</a> and <a href="https://github.com/oesmith/puffing-billy">Puffing Billy</a>, and we tighten tests by running database invariant checks after each test and not allowing any warnings to be logged.</p><p>If you have any suggestions for how to configure Jasmine, be sure to leave a comment below. And of course we welcome contributions to <a href="https://github.com/remix/remix-jasmine-setup">our config</a>! 🌟</p><p><em>If any of this interests you, take a look at our </em><a href="https://www.remix.com/jobs"><em>open roles</em></a><em>. We care about livable cities even more than developer tools. :)</em></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=f492446b5b05" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Preventing regressions]]></title>
            <link>https://medium.com/@JanPaul123/preventing-regressions-f9cac1180a9?source=rss-51e73dbd24ba------2</link>
            <guid isPermaLink="false">https://medium.com/p/f9cac1180a9</guid>
            <category><![CDATA[javascript]]></category>
            <category><![CDATA[engineering]]></category>
            <category><![CDATA[computer-science]]></category>
            <category><![CDATA[product-at-remix]]></category>
            <dc:creator><![CDATA[Jan Paul Posma]]></dc:creator>
            <pubDate>Thu, 13 Jul 2017 23:20:50 GMT</pubDate>
            <atom:updated>2017-07-13T23:34:43.327Z</atom:updated>
            <content:encoded><![CDATA[<h3>Preventing Regressions</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*INBa8eomXpJHlorHr8VCkg.jpeg" /><figcaption><em>This article is part of Remix’s series on the software engineering challenges we face. In this installment, Remix engineer Jan Paul Posma talks about preventing software bugs from appearing again.</em></figcaption></figure><h4>Fixing Bugs Forever</h4><p>When fixing a bug, you want to make sure that it doesn’t appear again. The typical tool for this is adding an automated test, also called a <a href="https://en.wikipedia.org/wiki/Regression_testing">regression test</a>. But this is just one tool in our toolbox.</p><p>In this article, we’ll look at various techniques for preventing regressions that we use at Remix, such as screenshot tests, linters, commit hooks, approval tests, assertions, bot warnings, and conventions.</p><h4>Cost vs. Effectiveness</h4><p>When preventing regressions, there is often a tradeoff between <em>cost</em> and <em>effectiveness</em>. A technique is <em>cheap</em> if:</p><ul><li>it’s quick to write;</li><li>it’s easy for others to understand;</li><li>it’s reliable (no false positives);</li><li>it’s loosely coupled (changing the code doesn’t require changing the detection of bugs);</li><li>it executes quickly, and early on.</li></ul><p>A technique is <em>effective</em> if:</p><ul><li>it covers as much as possible (ideally we prevent <em>entire classes</em> of bugs);</li><li>it’s resilient to change (changing the code doesn’t affect us detecting the bug; it doesn’t lead to false negatives);</li><li>it points immediately to the problem (no digging around required).</li></ul><p>We’ll examine all our techniques in terms of <em>cost</em> and <em>effectiveness. </em>Ideal techniques have both, but as we’ll see, that’s hard to find!</p><h4>Unit Tests</h4><p>Let’s start with a traditional technique. A <a href="https://en.wikipedia.org/wiki/Unit_testing">unit test</a> runs a small piece of code in the actual codebase, and then makes some assertions on the result. Here’s an actual example from our codebase:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*1o7o91LtxfQWDsHNkNkMhQ.png" /><figcaption>Unit test for a simple function. (format-test.js)</figcaption></figure><p>In this case, the <em>cost</em> is fairly low: it’s quick to write, easy to understand, runs quickly, and has never resulted in a false positive (as far as I know). It’s fairly loosely coupled, but would need updating if we change the API of the function, e.g. by changing the input from minutes to hours. In this case, it’s also fairly <em>effective</em>: we can be pretty sure that this piece of code works properly, even when changing it, and it immediately points to the problem when one of the tests fail.</p><p>But this is a pretty ideal case. Let’s look at another one, of a <a href="https://facebook.github.io/react/">React component</a>:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*3XeMPOIoXRops0uYchqkIQ.png" /><figcaption>Unit test for a React component. (InputComponent-test.js)</figcaption></figure><p>Still looks pretty straightforward, but in this case the test is less <em>resilient to change: </em>if we change the name of “onChange” to, say, “onEdit”, we might forget to update this test, which will make this test <em>do nothing!</em></p><p>The reason is that in React, it is allowed to pass in properties that the component does not actually use. One way to make this test more resilient is disallowing that and instead throwing an error. That is basically an <em>assertion,</em> which we will look at in detail later.</p><p>Let’s look at one more, which has several problems:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*BuTemzddarverxZJ8kSYsQ.png" /><figcaption>More complicated unit test. (FormattedDistanceComponent-test.js)</figcaption></figure><p>In this case the component depends on <a href="https://ampersandjs.com/docs/#ampersand-app">global Ampersand state</a>, which makes it hard to change this global state (e.g. by replacing it with <a href="http://redux.js.org/">Redux</a>). We also have to deal with asynchronicity, as the component debounces changes to <em>selectedMap</em>. All in all, the test is not <em>loosely coupled</em>.</p><p>Overall, unit tests are cheapest and most effective for relatively small units which don’t require a world of context. And there is an upper limit to their effectiveness: they only test what you assert—rarely entire classes of bugs.</p><h4><strong>Screenshot Tests</strong></h4><p>Let’s look at another technique of preventing bugs from happening: screenshot tests. The way we use them, they are similar to unit tests, in that you run a small piece of code in your actual codebase, and make assertions. In this case, though, the assertions involve taking screenshots of what has rendered in the browser, and comparing that to previous screenshots.</p><p>We use <a href="https://github.com/Galooshi/happo">Happo</a> to take screenshots of “examples” (rendered components with specific properties) in our component library. This is such an example:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/934/1*rKb7pEp9J4tZCMq8o41F7g.png" /><figcaption>Screenshot tests like this one in Happo are cheap<em>: </em>they are extremely easy to write and understand, and execute quite quickly. (TimetableComponent-examples.js)</figcaption></figure><p>Fixing a bug in the timetable causes a bot to comment on the Github Pull Request, like this:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*qD8mo3Ba1VUgq8sF1ao6sQ.png" /><figcaption>Our bot Mrv1n adds a comment when a screenshot changes.</figcaption></figure><p>When clicking on the link, you would see something like this:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*_k7jGCUweQc3oJyhxSfHUg.png" /><figcaption>Happo shows how React components change. Before (left), diff (middle), after (right).</figcaption></figure><p>Screenshot tests like this are <em>cheap: </em>they are extremely easy to write and understand, and execute quite quickly. They are more loosely coupled to the code than unit tests typically are, as they don’t have to do any prodding into the DOM to make assertions. They are pretty reliable, with false positives only occasionally happening.</p><p>But most of all, they are <em>effective: </em>they cover so much at once — rendering logic of all the components in the tree, and even CSS. They point to problems in a direct, visual way. And they are fairly resilient to change, although one has to be careful to create new examples to explicitly cover bugs, otherwise it can become hard to determine what kinds of bugs a particular example is supposed to cover. They also have some side benefits: the examples serve as code documentation, and as a “component library” / “style guide”.</p><p>Screenshot tests are so effective at preventing bugs in rendering logic, that we often forgo having unit tests for that at all. We save unit tests for interaction and business logic, such as mutating state.</p><h4>Approval Tests</h4><p>Screenshot tests are like a big assertion that covers a lot of things. We can do something similar for text outputs: <a href="http://approvaltests.com/">approval tests</a>, where you store the text output of (for example) a JSON endpoint, and alert the programmer when it changes. Those text outputs are called the <em>golden masters.</em> In the backend we use the <a href="https://github.com/kytrinyx/approvals">Approvals gem</a>, which looks something like this:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/996/1*dUEkvp90yzumYGCxyQj41g.png" /><figcaption>Approval tests, like this one for a JSON endpoint, cover the entire output of an endpoint with ease, especially with good fixture data that covers edge cases. (maps_controller_spec.rb)</figcaption></figure><p>Here we use a common fixture throughout the codebase, called <em>map_with_lots_of_stuff, </em>which contains various edge-cases. Because we use it in most of our tests, we know what to expect from it. And adding an edge case is easy: we just update the golden masters!</p><p>This is what the golden master for the test above looks like:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/708/1*ftdhucchscdDwfym-trI2w.png" /><figcaption>The “golden master” of a JSON endpoint. (get_apimaps_id/browser_request.approved.json)</figcaption></figure><p>Since it’s checked into git, we get a nice diff view for free. And again, this is a <em>cheap </em>way of preventing bugs: extremely easy to set up and understand, just like the screenshot tests, and it runs just as fast as other backend tests. It’s fairly <em>effective</em>, too: you can cover the entire output of an endpoint with ease, especially with good fixture data that covers edge cases. When debugging, it gives a good indication of what might be going wrong, although it might be harder to trace down than with a pointed unit test.</p><p>It should be noted that approval tests can be flakey (false positives), especially if the <em>order</em> in which results are returned is poorly defined. So we changed our fixture framework to generate predictable IDs, and we changed the application logic to establish a well-defined order. This has the side-benefit that bugs become more reproducible.</p><p>Approval tests also have the same downside as screenshot tests: you have to be careful to be explicit about all the edge cases you are testing for. It can be confusing to have one fixture with all the things you want to test for. If that’s the case, just split out some separate tests. It’s cheap and effective, after all!</p><p>We’ve also started using Approvals for testing which SQL gets executed during an endpoint call, which can prevent certain performance regressions in a cheap way. Read more in our blog post on the topic, <a href="https://blog.remix.com/orm-we-approve-60f2a68f73fb">ORM: We Approve</a>.</p><h4>External APIs Reminders</h4><p>We also use golden masters to warn programmers when they change an API used by an external service (as opposed to the front-end). Ideally, we would have systems test that boot up multiple services and test their integration; that would be <em>effective</em>. However, that is not always <em>cheap: </em>it can be tricky to write these tests, they are typically slow, and can be flakey.</p><p>Instead, our bot posts a comment (using a <a href="https://gist.github.com/janpaul123/f607fada739578ce5a8cfd41a1b24538">custom Pronto matcher</a>) when the golden master of an externally used API changes to remind the programmer to manually test the integration. This can be cheaper for APIs that don’t change much and is still quite effective. It looks like this:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*nnnPtQVVXQI3tKkkmRflgQ.png" /><figcaption>Our bot Mrv1n adds a comment when an external API changes.</figcaption></figure><h4>Linters</h4><p>Linters are great to reduce discussion about code style, but they can also prevent bugs. For example, we once used <a href="https://lodash.com/docs/4.17.4#find">Lodash’s <em>find()</em></a> method but forgot to actually include it, leading to confusing bugs, as the browser resolved it to <a href="https://developer.mozilla.org/en-US/docs/Web/API/Window/find">window.find()</a>. This was easily solved by adding a <a href="http://eslint.org/docs/rules/no-restricted-globals">linter rule</a> disallowing use of <em>find()</em> as a global method.</p><p>In this case, the <em>effectiveness </em>of the linter is limited (it only covers one particular case), but it’s extremely cheap to implement and use, especially because of the feedback cycle that is almost instant, if the programmer has an IDE that automatically runs the linter. If they don’t, it would be caught when committing, using <a href="https://github.com/brigade/overcommit">Overcommit</a> (our pre-commit hook tool).</p><h4>Different Language</h4><p>More elaborate than linting, is introducing extensions to the language, in order to prevent bugs. For example, <a href="https://flow.org">Flow</a> adds static type checking to Javascript. One could even go as far as using a different language altogether, such as <a href="http://elm-lang.org/">Elm</a>, which eliminates entire classes of bugs because of how the language is structured.</p><p>A classical example of this is C++ vs. Java. Traditionally, programmers had to manage memory carefully, making sure to deallocate memory when the last reference to an object was removed. This could cause <a href="https://en.wikipedia.org/wiki/Memory_leak">memory leaks</a>, a particularly hard kind of bug to track down. In modern languages such as Java—while keeping similar syntax as C++— has <a href="https://en.wikipedia.org/wiki/Garbage_collection_(computer_science)">automatic memory management</a>. A garbage collector automatically deallocates unused objects, which removes an entire class of bugs.</p><p>In our case, we use <a href="https://github.com/css-modules/css-modules">CSS Modules</a>, which is an extension to the CSS language that adds better scoping of class names. We’ve never had clashing class names ever since.</p><h4>Assertions</h4><p>While tests and static checks can prevent a lot of bugs, they can rarely cover all combinations of user interactions. For this we use <a href="https://en.wikipedia.org/wiki/Assertion_(software_development)">runtime assertions</a>, which are checks in the application code.</p><p>For Ruby, we have written a <a href="https://gist.github.com/janpaul123/1f2ad60d691f85b6bb23e2c9d4ba5a52">small helper</a>. In order to have it catch problems as early as possible, it raises an exception in tests and in development mode. When an assertion fails in production, we log an error to <a href="https://sentry.io">Sentry</a>, but let the program continue executing. We use it like this:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/790/1*EXBMUxI4ilDewt4pWpEXwQ.png" /><figcaption>Runtime assertions, like this one in Ruby, are easy to sprinkle throughout your codebase, but effectiveness depends on how actively the team monitors reported errors. (get_new_trip_params.rb)</figcaption></figure><p>It is very <em>cheap</em> to sprinkle assertions like this throughout your codebase. It can even serve as additional documentation for the code, by making any <a href="https://en.wikipedia.org/wiki/Precondition">pre-</a> and <a href="https://en.wikipedia.org/wiki/Postcondition">post-conditions</a> explicit. They also have barely any performance overhead.</p><p>The <em>effectiveness</em> varies wildly per assertion. In this case, it’s in a file that gets called from many places in the codebase, making it more effective. Also, since assertions are embedded in runtime code, they rarely get out of sync (no false negatives). However, the team needs to be actively monitoring reported errors.</p><p>A special case of assertions that we use in the front-end (besides regular assertions), is immutable data. For example, <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze"><em>Object.freeze()</em></a> raises an error when trying to change a “frozen” object.</p><h4>Data Integrity Checks</h4><p>Another special case of assertions, <a href="https://en.wikipedia.org/wiki/Data_integrity">data integrity</a> checks make sure that persisted data (in a database) is of a certain form. For this we use several techniques. First, we try to use the most appropriate <a href="https://www.postgresql.org/docs/9.5/static/datatype.html">type</a> for each column. Second, we use <a href="https://en.wikipedia.org/wiki/Relational_database#Constraints">database constraints</a> for simple checks. Third, for more complicated checks we have a script that runs queries against a <a href="https://en.wikipedia.org/wiki/Replication_(computing)#Database_replication">follower database</a>, and notifies us when an assertion fails.</p><p>These methods are increasingly <em>expensive</em> and decreasingly <em>effective</em> as they become more and more specific. But like other assertions, they operate on real-world data—full of edge cases—making it more likely to catch bugs with them than with tests.</p><h4>“How can I prevent this bug from happening again?”</h4><p>All these techniques are the result of us constantly asking ourselves the question: “How can I prevent this bug from happening again, in the cheapest, most effective way?” This is a more open-ended question than, “Is there a unit test for this,” or, “what is our test coverage percentage?” After all, there are more techniques than unit testing, and many of them are either cheaper, or more effective, or both.</p><p>To encourage asking this question, we have the convention to write a “test plan” in every commit. We have even <a href="https://gist.github.com/janpaul123/4df2223b1b8883976378e831ba59cbc9">configured Overcommit</a> to remind us of this. These are some actual commits:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*IY47lqr0QuVhuZf3Sw75vw.png" /><figcaption>Actual commits from our codebase, showing our “test plan” convention.</figcaption></figure><p>Note that the test plan doesn’t always involve writing code. Sometimes just testing something manually is enough, if the cost of automating it outweighs the chance that the bug regresses.</p><p>For different types of commits, different test plans are useful. For pure refactors, ideally you don’t need to change your tests. For bug fixes, you want to write how that bug—or similar ones—will be prevented in the future. For new functionality, think about how to guarantee its correctness.</p><h4>Conclusion</h4><p>We’ve looked at various techniques of preventing bugs from regressing and a way of evaluating these techniques. In the end, this is only what we came up with, and we are always looking for new ideas!</p><p>Most importantly, though, is the mindset. Whenever you fix a bug, think to yourself: how can I prevent this bug from happening again, in the cheapest, most effective way? And then extend this line of thinking to refactors and new functionality, too.</p><p><em>If any of this interests you, take a look at our </em><a href="https://www.remix.com/jobs"><em>open roles</em></a><em>. We use all this to help create more livable cities. :)</em></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=f9cac1180a9" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Remix’s Tech Stack: Webpack]]></title>
            <link>https://medium.com/@JanPaul123/remixs-software-stack-webpack-34990de9d803?source=rss-51e73dbd24ba------2</link>
            <guid isPermaLink="false">https://medium.com/p/34990de9d803</guid>
            <category><![CDATA[eng]]></category>
            <category><![CDATA[engineering]]></category>
            <category><![CDATA[software-engineering]]></category>
            <category><![CDATA[javascript]]></category>
            <dc:creator><![CDATA[Jan Paul Posma]]></dc:creator>
            <pubDate>Mon, 10 Oct 2016 22:31:06 GMT</pubDate>
            <atom:updated>2017-07-24T22:14:52.425Z</atom:updated>
            <content:encoded><![CDATA[<p><em>This is the first in a series about Remix’s tech stack. Over the last few months we’ve worked on setting up our ideal stack, and we’re proud of what we’ve built. Now it’s time to share it.</em></p><p>We’ll start with our front-end build tools. We wanted to use the latest Javascript features without worrying about older browsers (<a href="https://babeljs.io/">Babel</a>), confidence when changing CSS by scoping classes (<a href="https://github.com/css-modules/css-modules">CSS Modules</a>), immediate feedback when changing code (<a href="http://gaearon.github.io/react-hot-loader/">React Hot Loader</a>), and so on. All of this is easy to set up when using <a href="https://webpack.github.io/">Webpack</a>, which is why we switched to that. In this article we’ll look at how we’ve set this up.</p><h4>Webpack config</h4><p>There are a few ways we want Webpack to behave, based on the context. The first is <strong>dev-server</strong> vs <strong>static build</strong>.</p><ul><li>When developing we use the <a href="https://webpack.github.io/docs/webpack-dev-server.html">webpack-dev-server</a>, which caches files in memory and serves them from a web server, which in turn saves time. It also supports hot module loading.</li><li>When building on the Continuous Integration, or CI, server (we use <a href="https://circleci.com/">CircleCI</a>), or when deploying using <a href="https://www.heroku.com/">Heroku</a>, we want to generate a static build, so we can host them statically in production. That way we can set proper caching headers.</li></ul><p>We also use both <strong>minified</strong> and <strong>non-minified</strong> versions of our builds, depending on whether it’s in production or still in development.</p><ul><li>In production, we want a gzipped and minified build, so it downloads and parses faster. We also enable all React optimisations, so it runs faster. Sometimes we also want to do this when developing locally, when measuring performance.</li><li>Usually though, we want to disable minifying when developing. This way development is faster, as minifying is an additional step. We also want to get all of React’s warnings when developing.</li></ul><p>To set this context, we use two environment variables, which we use like this in our <em>package.json</em>:</p><pre>&quot;scripts&quot;: {<br>  &quot;build&quot;: &quot;webpack&quot;,<br>  &quot;build-min&quot;: &quot;WEBPACK_MINIFY=true npm run build&quot;,<br>  &quot;dev-server&quot;: &quot;WEBPACK_DEV_SERVER=true webpack-dev-server&quot;,<br>  &quot;dev-server-min&quot;: &quot;WEBPACK_MINIFY=true npm run dev-server&quot;<br>},</pre><p>In our <a href="https://webpack.github.io/docs/configuration.html"><em>webpack.config.js</em></a><em> </em>we first set up some common stuff:</p><pre>const config = {<br>  plugins: [ /* Some plugins here. */ ],<br>  module: {<br>    loaders: [ /* Some loaders here. */ ],<br>  },<br>  entry: {<br>    build: [&#39;client/build&#39;], // Our main entry point.<br>    tests: [&#39;client/tests&#39;], // Jasmine unit tests.<br>    happo: [&#39;client/happo&#39;], // Happo screenshot tests.<br>  },<br>  resolve: {<br>    alias: {<br>      client: path.resolve(&#39;./client&#39;),<br>    },<br>  },<br>};</pre><p>Nothing too exciting here. All our code is in the <em>client</em> directory, plus <em>node_modules</em> for libraries (which Webpack finds by default). We alias the <em>client </em>directory, so we can easily refer to it. We have three entry points, one for our app (<em>client/build.js</em>) and two for tests (which we’ll get into in a later article).</p><p>We then look at if we’re minifying or not:</p><pre>if (process.env.WEBPACK_MINIFY) {<br>  config.plugins.push(new webpack.DefinePlugin({<br>    &#39;process.env&#39;: {<br>      // Disable React warnings and assertions.<br>      &#39;NODE_ENV&#39;: JSON.stringify(&#39;production&#39;),<br>    },<br>    &#39;__DEV__&#39;: false, // For internal use.<br>  }));<br>  config.plugins.push(new webpack.optimize.UglifyJsPlugin({<br>    compress: { warnings: false },<br>  }));<br>} else {<br>  // Only use source maps when not minifying.<br>  config.devtool = &#39;eval-source-map&#39;; <br>  config.plugins.push(new webpack.DefinePlugin({<br>    &#39;__DEV__&#39;: true,<br>  }));<br>}</pre><p>If we’re minifying, we want to set <em>NODE_ENV </em>to “production”, as React uses this to strip away all sorts of assertions and warnings, making it faster. When not minifying we enable source maps.</p><p>Then we have setup specific for when using the dev-server:</p><pre>if (process.env.WEBPACK_DEV_SERVER) {<br>  // Development configuration, assumes this is loaded with <br>  // webpack-dev-server, running on port 8080 (default).</pre><pre>  // Hot loading for build.js.<br>  config.devServer = { noInfo: true, host: &#39;0.0.0.0&#39;, hot: true};<br>  config.entry.build.unshift(<br>    &#39;webpack-dev-server/client?<a href="http://localhost:8080&#39;">http://localhost:8080&#39;</a>);<br>  config.entry.build.unshift(&#39;webpack/hot/dev-server&#39;);<br>  config.plugins.push(new webpack.HotModuleReplacementPlugin());<br>  config.plugins.push(new webpack.NoErrorsPlugin());</pre><pre>  // React components hot loading.<br>  config.module.loaders.unshift({<br>    test: /\.js$/,<br>    include: path.resolve(__dirname, &#39;client/components&#39;),<br>    loader: &#39;react-hot&#39;,<br>  });</pre><pre>  // Expose Jasmine test page as index page on <a href="http://localhost:8080">http://localhost:8080</a><br>  config.plugins.push(new JasmineWebpackPlugin({<br>    htmlOptions: {<br>      chunks: [&#39;tests&#39;],<br>      filename: &#39;index.html&#39;,<br>    },<br>  }));</pre><pre>  config.output = { <br>    publicPath: &#39;<a href="http://localhost:8080/%27">http://localhost:8080/&#39;</a>,<br>    filename: &#39;[name].js&#39;,</pre><pre>    // In case this is run without webpack-dev-server.<br>    path: &#39;public/client&#39;,<br>  };<br>}</pre><ul><li>We initialise the dev-server with <em>noInfo,</em> making it less verbose, and bind it to <em>0.0.0.0</em> so you can access it from other machines on the network (useful for debugging).</li><li>We enable Hot Module Replacement, <a href="https://webpack.github.io/docs/webpack-dev-server.html#hot-module-replacement-with-node-js-api">per instructions here</a>. We also enable the <a href="http://gaearon.github.io/react-hot-loader/">React Hot Loader</a>, but only on actual React components (<em>client/components</em>).</li><li>Then we host the <a href="https://github.com/iredelmeier/jasmine-webpack-plugin">Jasmine index page</a> on the same port, so you can just navigate there to run the tests.</li><li>Finally we set <em>config.output</em> to something simple, so you can easily view what is generated at <em>http://localhost:8080/build.js</em>. In case we run this without the dev-server (which should typically not happen), we write to where other static files are written.</li></ul><p>If we’re not running the dev-server, we’re writing to disk:</p><pre>else {<br>  // Static configuration, outputs to public/client.<br>  // For use with Heroku/CircleCI.</pre><pre>  if (process.env.WEBPACK_MINIFY) {<br>    // Gzip.<br>    config.plugins.push(new CompressionPlugin());<br>    <br>    // Generate stats.html.<br>    config.plugins.push(new StatsPlugin(&#39;stats.json&#39;));<br>    config.plugins.push(new Visualizer());<br>  }</pre><pre>  config.output = {<br>    path: &#39;public/client&#39;,<br>    publicPath: &#39;/client/&#39;,</pre><pre>    // Unique filenames (for caching).<br>    filename: &#39;[id].[name].[chunkhash].js&#39;,<br>  };<br>}</pre><ul><li>When minifying, we gzip all files (which Rails static asset hosting automatically uses), and we generate a <a href="https://github.com/chrisbateman/webpack-visualizer">file usage visualisation</a>, which we serve on our internal development pages.</li><li>We also generate unique filenames for each build, so we can serve them with infinite caching headers.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*Gl4XpOAQtV1L-2Xjjvbyaw.png" /><figcaption>The file usage visualisation helps us debug increases in the bundle size</figcaption></figure><p>Finally we speed up deploys a bit by leaving out tests when deploying on Heroku:</p><pre>// Don&#39;t build tests when deploying on Heroku.<br>if (process.env.HEROKU_APP_ID) {<br>  delete config.entry.tests;<br>  delete config.entry.happo;<br>}</pre><h4>Serving from Rails</h4><p>Let’s now look at the plugins part of our Webpack config. It looks like this:</p><pre>plugins: [<br>  new CircularDependencyPlugin(),<br>  new ManifestPlugin(),<br>],</pre><p>The first one is to <a href="https://github.com/aackerman/circular-dependency-plugin">prevent circular dependencies</a>, which can be a pain to debug in Webpack. The second one <a href="https://github.com/danethurber/webpack-manifest-plugin">generates a <em>manifest.json</em> file</a>, which looks something like this:</p><pre>{<br>  &quot;build.js&quot;: &quot;0.build.fc79868b1fdedc95cd1f.js&quot;,<br>  &quot;happo.js&quot;: &quot;1.happo.d44f048f66291e0e73ca.js&quot;,<br>  &quot;tests.js&quot;: &quot;2.tests.305167cc0309faddc140.js&quot;<br>}</pre><p>We use this in our Rails application to serve the right assets. For this we have created a helper file, <em>assets_helper.rb</em>:</p><pre># Adds `webpack_include_tag`.<br>module AssetsHelper<br>  def webpack_include_tag(filename)<br>    if Rails.application.config.use_webpack_dev_server<br>      # Assumes that Webpack is configured with<br>      # config.output.filename = &#39;[name].js&#39;.<br>      return javascript_include_tag(root_url(port: 8080) + filename)<br>    end</pre><pre>    webpack_filename = webpack_manifest[filename]<br>    if webpack_filename<br>      javascript_include_tag(&quot;/client/#{webpack_filename}&quot;)<br>    else<br>      raise ArgumentError, &quot;Webpack file not found: #{filename}&quot;<br>    end<br>  end</pre><pre>  private def webpack_manifest<br>    @webpack_manifest ||= JSON.load(Rails.root.join(<br>      &#39;public&#39;, &#39;client&#39;, &#39;manifest.json&#39;))<br>  end<br>end</pre><p>This allows us to call <em>webpack_include_tag(‘build.js’)</em> in templates, and have it use the filename including the hash. Now we can tell the browser to cache these files forever, as they will have a different filename if they ever change.</p><p>Note that when <em>use_webpack_dev_server</em> is enabled, we point to the dev-server. We set this variable to <em>true </em>in development, to <em>false</em> in staging and production, and in <em>test.rb</em> we set:</p><pre>config.use_webpack_dev_server = !ENV[&#39;CI&#39;]</pre><h4>Preprocessing using Loaders</h4><p>Finally, we have a bunch of Webpack loaders. This is what that looks like in the Webpack config:</p><pre>module: {<br>  loaders: [<br>    {<br>      test: /\.js$/,<br>      include: path.resolve(&#39;./client&#39;),<br>      loader: &#39;babel&#39;,<br>      query: {<br>        cacheDirectory: &#39;.babel-cache&#39;,</pre><pre>        // For code coverage.<br>        plugins: (!process.env.WEBPACK_DEV_SERVER &amp;&amp;<br>          !process.env.WEBPACK_MINIFY) ? [&#39;istanbul&#39;] : [],<br>      },<br>    },<br>    {<br>      test: /\.less$/,<br>      include: path.resolve(&#39;./client&#39;),<br>      loaders: [<br>         // Inject into HTML (bundles it in JS).<br>        &#39;style&#39;, </pre><pre>        // Resolves url() and :local().<br>        &#39;css?localIdentName=[path][name]--[local]--[hash:base64:10]&#39;,</pre><pre>        // Autoprefixer (see below at `postcss()`).<br>        &#39;postcss-loader&#39;,</pre><pre>        // LESS preprocessor.<br>        &#39;less&#39;, <br>      ],<br>    },<br>    {<br>      test: /\.(jpe?g|png|gif)$/i,<br>      include: path.resolve(&#39;./client&#39;),<br>      loaders: [<br>        // Inline small images, otherwise create file.<br>        &#39;url?limit=10000&#39;,</pre><pre>        // Minify images.<br>        &#39;img?progressive=true&#39;,<br>      ],<br>    },<br>    {<br>      test: /\.(geo)?json$/,<br>      include: [<br>        path.resolve(&#39;./client&#39;),<br>        path.resolve(&#39;./spec&#39;), // Shared fixtures.<br>      ],<br>      loader: &#39;json&#39;,<br>    },<br>    {<br>      test: /\.svg$/,<br>      loader: &#39;raw&#39;,<br>    },<br>  ],<br>},<br>postcss() {<br>  return [autoprefixer];<br>},</pre><ul><li>First, the Babel loader. This allows us to use the latest Javascript features without having to worry about browser support (in conjunction with babel-polyfill). We use Istanbul to track code coverage for tests, and we set an explicit cache path so the CI can keep this cache between builds. This is what that looks like for CircleCI, in <em>circle.yml</em>:</li></ul><pre>dependencies:<br>  cache_directories:<br>    - &quot;.babel-cache&quot;</pre><ul><li>Next is CSS. We use LESS for preprocessing, although we’re thinking of switching to PostCSS, which uses future CSS standards. We already use PostCSS for auto-prefixing. We also use CSS Modules by setting <em>css?localIdentName, </em>which lets you scope CSS classes to only the file that uses them.</li><li>Images are being inlined if they are a small file, otherwise they get loaded separately. They are also minified.</li><li>JSON and SVG are straightforward. We import SVG as text, which we use with an <em>&lt;Svg&gt;</em> component that looks like this:</li></ul><pre>// Use a tool like <a href="https://jakearchibald.github.io/svgomg/">https://jakearchibald.github.io/svgomg/</a><br>// to slim down the SVG, and then manually<br>// remove width/height/fill/stroke.<br>const Svg = React.createClass({<br>  propTypes: {<br>    height: React.PropTypes.number,<br>    offset: React.PropTypes.number,<br>    svg: React.PropTypes.string.isRequired,<br>    width: React.PropTypes.number.isRequired,<br>  },</pre><pre>  render() {<br>    return (<br>      &lt;div<br>        className={styles.root}<br>        dangerouslySetInnerHTML={{ __html: this.props.svg }}<br>        style={{<br>          height: this.props.height || this.props.width,<br>          width: this.props.width,<br>          top: this.props.offset,<br>        }}<br>      /&gt;<br>    );<br>  },<br>});</pre><pre>export default Svg;</pre><p>Which then gets used like this:</p><pre>&lt;Svg svg={require(&#39;./pencil.svg&#39;)} width={14} offset={2} /&gt;</pre><h4>Conclusion</h4><p>This is just a small part of our stack, but it took a while to get right. After all, it’s the small things that make a difference, such as being able to run a minified version with all React optimisations in development, or persisting Babel’s cache between CI runs, or not building tests when deploying.</p><p>Hopefully this is useful to get started with Webpack, or to tune your existing setup. Keep an eye out for next editions in this series, in which we’ll talk about our components library, unit testing, screenshot testing, deploying, keeping the CI fast, and more!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=34990de9d803" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Maintaining scroll positions in all browsers]]></title>
            <link>https://medium.com/@JanPaul123/maintaining-scroll-positions-in-all-browsers-a280d49bffca?source=rss-51e73dbd24ba------2</link>
            <guid isPermaLink="false">https://medium.com/p/a280d49bffca</guid>
            <category><![CDATA[web-development]]></category>
            <category><![CDATA[scroll-restoration]]></category>
            <category><![CDATA[javascript]]></category>
            <dc:creator><![CDATA[Jan Paul Posma]]></dc:creator>
            <pubDate>Mon, 14 Dec 2015 21:37:06 GMT</pubDate>
            <atom:updated>2015-12-14T22:55:31.370Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/682/1*GRNlhtvPxaWI2lwfz6DLzw.gif" /><figcaption>Delayed scroll restoration in Firefox using our polyfill.</figcaption></figure><p>A few months ago I was riding the subway taking positions on the <a href="https://brigade.com">Brigade web app</a>. I noticed something strange. Whenever I didn’t have a strong opinion I checked out the reasons people had left to inform myself. Then I would use the back button to take positions again, only to have to scroll down all the way to where I was before. That was a bad experience—I had to do a lot of scrolling—especially since I like to take a lot of positions!</p><p>Now, I had done the same thing in Chrome on my MacBook before, and I never noticed this problem. When I got home, I verified this, and indeed, it worked fine on my laptop—it scrolled back to my last taken position. Then I tried out other browsers on my laptop, such as Firefox and Safari, and <em>aha</em>! Those browsers had the same problem as my iPhone. I found it so annoying that I started investigating.</p><p>It turns out that all browsers restore the scroll position when clicking the back button, right after the page has loaded. However, with single page applications like ours, a page load typically doesn’t mean all content on the page is available; we first need to make some AJAX requests before we can render things. So for traditional websites most browsers work fine, but for newer web apps navigating around can suck—except in Chrome.</p><h4>Existing solutions</h4><p>After digging through the Chrome source code, I found the <a href="https://chromium.googlesource.com/chromium/blink/+/5da5b59/Source/core/loader/FrameLoader.cpp#1049">piece of code</a> responsible for restoring the scroll position. It turns out that Chrome uses some sophisticated logic to determine when to restore the scroll position, which looks at if network requests have completed, if the size of the page has changed since last looking at it, if the user has already scrolled, and so on. A personal highlight is the variable <em>canRestoreWithoutAnnoyingUser</em>.</p><blockquote>It turns out that this is such a debated topic in the react-router community, that they even split out a separate repo for different scroll behaviours.</blockquote><p>Looking at how other people solve this problem, I found that our navigation library at the time, <a href="https://github.com/defunkt/jquery-pjax">pjax</a>, had functionality for <a href="https://github.com/defunkt/jquery-pjax/blob/d76e840c0f1c0a98c9dd5065b32e436e810d8d13/jquery.pjax.js#L783">caching page content</a> when navigating away, so that pages can be immediately restored when navigating back. However, it assumed having static content, and didn’t seem to play well with React, which we use for our rendering, as React components would lose their state.</p><p>We were considering switching to <a href="https://github.com/rackt/react-router">react-router</a> (which we have now done), so I looked if they had a better solution. It turns out that <a href="https://github.com/rackt/react-router/issues/186">this</a> <a href="https://github.com/rackt/react-router/issues/707">is</a> <a href="https://github.com/rackt/react-router/issues/810">such</a> <a href="https://twitter.com/dan_abramov/status/601097500586549249">a</a> <a href="https://github.com/rackt/react-router/issues/2019">debated</a> <a href="https://github.com/rackt/react-router/issues/2144">topic</a> in the react-router community, that they even split out a separate repo for <a href="https://github.com/rackt/scroll-behavior">different scroll behaviours</a>. Unfortunately, none of them supported waiting for the content to be rendered, like Chrome did.</p><h4>Writing our own polyfill</h4><p>So I decided to write <a href="https://github.com/brigade/delayed-scroll-restoration-polyfill">my own solution</a>. I really liked Chrome’s behaviour, so I wanted to write a polyfill that would emulate it as closely as possible. A key part of Chrome’s algorithm was to wait until the page becomes large enough to actually be able to scroll to previous position again, and that seemed easy enough to implement. Instead of waiting for network requests to finish, I simply <a href="https://github.com/brigade/delayed-scroll-restoration-polyfill/blob/1aa90ef6ff9c3b295da4574532e073e057fc6c0a/index.es6.js#L29-L55">checked the page width and height every few milliseconds</a>, and that seemed to work well enough. Then, when it would be possible to scroll, do it. With manual testing of scroll values, that seemed to work pretty well.</p><p>The next question is, where to scroll to? Our application uses the <a href="https://developer.mozilla.org/en-US/docs/Web/API/History">History API</a> for all page navigation, so I decided not to worry about full page loads. It turns out that you can store information whenever calling <em>pushState</em> or <em>replaceState</em>, so I modified both functions to <a href="https://github.com/brigade/delayed-scroll-restoration-polyfill/blob/1aa90ef6ff9c3b295da4574532e073e057fc6c0a/index.es6.js#L5-L27">store the scroll position</a> whenever calling them. Combining that with <a href="https://github.com/brigade/delayed-scroll-restoration-polyfill/blob/1aa90ef6ff9c3b295da4574532e073e057fc6c0a/index.es6.js#L57-L72">restoring the scroll position when <em>popState</em> is called</a>, and it already comes pretty close to Chrome’s behaviour!</p><blockquote>Interestingly, people have argued that this is a bug in the spec, and in fact Chrome has deliberately implemented this differently.</blockquote><p>Those modifications worked well for navigating to new pages, but not so much for pressing “back” and then “forward” again, because we didn’t save the scroll position from before clicking the “back” button. So I wanted to also store the scroll position when <em>popState</em> was fired, because that means that the browser navigates to another place. However, it turns out that’s not so easy, because <a href="https://html.spec.whatwg.org/#history-traversal">the spec</a> states that the scroll position should be restored before firing <em>popState</em>, so we would not be able to determine the actual scroll position. Interestingly, <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=666792#c2">people have argued</a> that this is a <a href="https://github.com/whatwg/html/issues/39">bug in the spec</a>, and in fact Chrome has <a href="https://code.google.com/p/chromium/issues/detail?id=474579">deliberately implemented this differently</a>. So I had to do without scroll restoration when pressing the “forward” button.</p><p>Another deviation from Chrome’s behaviour, is that it doesn’t attempt to restore the scroll position if the user has already scrolled. Unfortunately, in Javascript-land there is no way for us to tell if a scroll was initiated by the user, or by the browser’s scroll restoration algorithm (which, as we just learned, is even inconsistent across browsers, so it’s hard to make assumptions about it). Luckily, both this problem and the <em>popState</em> problem will likely be fixed by the <a href="http://majido.github.io/scroll-restoration-proposal/">Custom Scroll Restoration Proposal</a>, a new API that allows Javascript developers to disable the browser’s scroll behaviour altogether. It has already been shipped in—you guessed it—<a href="https://code.google.com/p/chromium/issues/detail?id=477353">Google Chrome</a>. Hopefully other browser vendors will follow suit soon.</p><p>Anyway, we’ve had this polyfill enabled on Brigade’s production web app for a few months now without any problems, so we decided to make it open source. If you have similar scrolling issues with your web app, just install the <a href="https://github.com/brigade/delayed-scroll-restoration-polyfill">delayed-scroll-restoration-polyfill</a>. And, as always, we welcome all feedback!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=a280d49bffca" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Don’t pass CSS classes between components]]></title>
            <link>https://medium.com/@JanPaul123/don-t-pass-css-classes-between-components-e9f7ab192785?source=rss-51e73dbd24ba------2</link>
            <guid isPermaLink="false">https://medium.com/p/e9f7ab192785</guid>
            <dc:creator><![CDATA[Jan Paul Posma]]></dc:creator>
            <pubDate>Tue, 12 May 2015 02:30:18 GMT</pubDate>
            <atom:updated>2015-05-12T04:00:48.394Z</atom:updated>
            <cc:license>http://creativecommons.org/licenses/by/4.0/</cc:license>
            <content:encoded><![CDATA[<h4>The hidden complexity of CSS in modular applications</h4><p>The hardest thing when building a large application is <strong>managing complexity</strong>. You get complexity when lots of parts of your application interact with each other, resulting in a large number of states your program can be in. This makes it harder to reason about your program.</p><p>Frameworks like <a href="http://reactjs.com">React</a> help us to reduce this complexity by decomposing an application into smaller components which can be reasoned about individually. But unless we are careful, we can still end up with a lot of complexity within our components. Think of that one component that accepts more than 10 properties — isn’t it a pain to work with? Each additional property increases the <a href="http://2014.jsconf.eu/speakers/sebastian-markbage-minimal-api-surface-area-learning-patterns-instead-of-frameworks.html">API surface</a>, causing a combinatorial explosion, which makes it hard to predict how a change to one prop will affect all the possible combinations.</p><p>For example, in our codebase at Brigade we have a <em>&lt;Button&gt;</em> component that has grown significantly over time — as these things happen. At one point it took a <em>color</em> string, <em>flat</em> boolean, <em>zDepth</em> integer (a Material Design term), <em>unstyled</em> boolean, <em>light</em> boolean, <em>dark</em> boolean, <em>darkRipple</em> boolean, <em>round</em> boolean, <em>type</em> string, and many more. Besides weird inconsistencies (what does it mean to have <em>&lt;Button dark light&gt;</em>?), it was mostly just hard to change anything. What if we change some shadow, will that still look good for <em>&lt;Button color=”primary-inverted” flat zDepth=”3&quot; round&gt;</em>? Do we even have a button with those properties? The only way to work with such a component is to try to understand how all the different properties interact, and come up with all the possible results in your head, which is impractical.</p><p>While a dozen properties is bad, imagine that you suddenly add hundreds of properties to a component. Can you imagine how much complexity that adds? You have no idea how all those properties are being used throughout the application, and what interactions they might have with the changes you are making.</p><p><strong><em>That’s exactly what happens when you pass in a CSS class as a property.</em></strong></p><p>I’ve seen the pattern of passing a CSS class into components a couple of times now. Superficially it makes sense, because it is consistent with the built-in components, and you want to be able to style your components, right? For example, we could have <em>&lt;Button className=”sign-up-submit”&gt;</em>, with corresponding CSS that overrides the global styles for <em>&lt;Button&gt;</em>.</p><p>However, that <em>className</em> is complexity in disguise. Once you can give a component any arbitrary CSS class, you can change any of its <a href="http://meiert.com/en/indices/css-properties/">315</a> CSS properties, which has exactly the same problem as adding 315 properties explicitly. With any change you have no idea how it might interact with all the different CSS properties that might be applied to the component throughout the application, making the component very brittle. And if you do this throughout the application, expect styles to break all over the place.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/860/1*JXKNw2AeagxFUeXtYtFO8Q.png" /><figcaption>Represent styles as properties.</figcaption></figure><p>So what to do instead? First of all, you can <strong>make all different styles explicit properties</strong>. Unfortunately you can end up with lots of properties, like with our <em>&lt;Button&gt; </em>component, but at least then these properties are explicit — the complexity is not hidden.</p><p>For example, we had a <em>&lt;Checkbox&gt;</em> component which took a <em>className</em>, which we used in one case to vertically align a (rather complex) label, and to add an ellipsis if it would overflow. In other cases, however, the label would wrap to the next line. Instead of solving this with <em>className</em> (which actually broke when we changed the component’s styles!) we could expose a <em>wrap</em> property that allows choosing between the wrapping and overflow ellipsis behaviours.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/707/1*GfBkqxEafASqMJs8iw-Jhg.png" /><figcaption>Split components by decomposing them if possible.</figcaption></figure><p>The second trick is <strong>splitting one component into two or more components</strong>, which have sufficiently different styles or behavior. In some cases you can use composition, such as extracting a component that just renders a shadow — which you can then reuse! The only potential downside is that you can get more elements, which in certain rare cases might hurt performance.</p><p>To see if a component has a truly small API surface, just look at your test suite. Does it reasonably cover all possible combinations of properties, or does it miss some major use cases? If you have a <em>className</em> property, your tests will most certainly not cover all the things you could do with the component. But CSS classes are only one example of properties in disguise. The same applies to a <em>style</em> property; a function that can alter a component’s rendered output significantly; many references to stateful objects (such as stores); multiple mixins that add properties, and so on.</p><p>So, to keep your application maintainable:</p><ul><li>Keep the number of properties of your components to a minimum.</li><li>Don’t sneak in more properties implicitly through <em>className.</em></li><li>Represent actual different ways a component can look or behave using properties.</li><li>Split out your component into several smaller components that you can compose.</li></ul><p>Your application will become easier to reason about, and thus easier to change.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=e9f7ab192785" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>