<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/">
  <channel>
    <title>webcodr</title>
    <link>https://webcodr.io/topics/javascript/</link>
    <description>Recent content on webcodr</description>
    <generator>Hugo</generator>
    <language>en-us</language>
    <lastBuildDate>Wed, 25 Sep 2019 22:20:12 +0200</lastBuildDate>
    <atom:link href="https://webcodr.io/topics/javascript/index.xml" rel="self" type="application/rss+xml" />
    
    <item>
      <title>Hello, Dark Mode</title>
      <link>https://webcodr.io/2019/09/hello-dark-mode/</link>
      <pubDate>Wed, 25 Sep 2019 22:20:12 +0200</pubDate>
      <guid>https://webcodr.io/2019/09/hello-dark-mode/</guid>
      <description>Dark mode for Android and iOS? Hold my beer …
It’s quite simple to implement. Every modern browser can evaluate media queries in JavaScript with window.matchMedia() and supports CSS variables.
I added the following to my application JavaScript file:
const preferColorSchemeResult = window.matchMedia(&#39;(prefers-color-scheme: dark)&#39;) if (preferColorSchemeResult &amp;&amp; preferColorSchemeResult.matches === true) { document.documentElement.setAttribute(&#39;data-theme&#39;, &#39;dark&#39;) } else { document.documentElement.setAttribute(&#39;data-theme&#39;, &#39;light&#39;) } The script will set the data attribute theme on the document element (html) with the possible values dark or light depending on the result of the media query.
</description>
      <content:encoded><![CDATA[<p>Dark mode for Android and iOS? Hold my beer &hellip;</p>
<p>It&rsquo;s quite simple to implement. Every modern browser can evaluate media queries in JavaScript with
<code>window.matchMedia()</code> and supports CSS variables.</p>
<p>I added the following to my application JavaScript file:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">preferColorSchemeResult</span>
</span></span><span class="line"><span class="cl">  <span class="o">=</span> <span class="nb">window</span><span class="p">.</span><span class="nx">matchMedia</span><span class="p">(</span><span class="s1">&#39;(prefers-color-scheme: dark)&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">if</span> <span class="p">(</span><span class="nx">preferColorSchemeResult</span> <span class="o">&amp;&amp;</span> <span class="nx">preferColorSchemeResult</span><span class="p">.</span><span class="nx">matches</span> <span class="o">===</span> <span class="kc">true</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nb">document</span><span class="p">.</span><span class="nx">documentElement</span><span class="p">.</span><span class="nx">setAttribute</span><span class="p">(</span><span class="s1">&#39;data-theme&#39;</span><span class="p">,</span> <span class="s1">&#39;dark&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nb">document</span><span class="p">.</span><span class="nx">documentElement</span><span class="p">.</span><span class="nx">setAttribute</span><span class="p">(</span><span class="s1">&#39;data-theme&#39;</span><span class="p">,</span> <span class="s1">&#39;light&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>The script will set the data attribute <code>theme</code> on the document element (html) with the possible values
<code>dark</code> or <code>light</code> depending on the result of the media query.</p>
<p>There&rsquo;s no need for a polyfill, even IE 10 supports <code>window.matchMedia()</code>.</p>
<p>The stylesheet changes are even simpler, since I already had introduced SCSS color variables a while ago. I just
had to replace them with CSS variables.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-scss" data-lang="scss"><span class="line"><span class="cl"><span class="c1">// colors
</span></span></span><span class="line"><span class="cl"><span class="nv">$c_white</span><span class="o">:</span> <span class="mh">#fff</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="nv">$c_dark-grey</span><span class="o">:</span> <span class="mh">#4A4A4A</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nd">:root</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="na">--container-background-color</span><span class="o">:</span> <span class="si">#{</span><span class="nv">$c_white</span><span class="si">}</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="nc">...</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="o">[</span><span class="nt">data-theme</span><span class="o">=</span><span class="s2">&#34;dark&#34;</span><span class="o">]</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="na">--container-background-color</span><span class="o">:</span> <span class="si">#{</span><span class="nf">darken</span><span class="p">(</span><span class="nv">$c_dark-grey</span><span class="o">,</span> <span class="mi">20</span><span class="kt">%</span><span class="p">)</span><span class="si">}</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">  <span class="nc">...</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>That&rsquo;s basically it. If you use SCSS, please take notice to use interpolations to map the SCSS
variables to CSS variables. This change in SassScript expressions was necessary to provide full
compatibility with plain CSS.</p>
<p>Since the theme selection is fully automated, I will provide a toggle possibility in a future
release for those of you who prefer the light mode. This can be easily achieved with a flag in local
storage and some minor changes in the JavaScript part.</p>
]]></content:encoded>
    </item>
    
    <item>
      <title>Snapshot Tests With Jest</title>
      <link>https://webcodr.io/2018/06/snapshot-tests-with-jest/</link>
      <pubDate>Wed, 13 Jun 2018 16:31:12 +0200</pubDate>
      <guid>https://webcodr.io/2018/06/snapshot-tests-with-jest/</guid>
      <description>Writing tests can sometimes be a tedious task. Mocks and assertions can be a pain in the ass. The latter is especially nasty when HTML is involved. Give me the second p element from the 30th div within an article in aside etc. – no thanks.
The creators of Jest (Facebook) have found a better way: Snapshot tests!
How does it work? Take a look at the following assertion:
it(&#39;should create a foo bar object&#39;, () =&gt; { const result = foo.bar() expect(result).toMatchSnapshot() }) toMatchSnapshot() takes whatever you give to expect(), serializes it and saves it into a file. The next test run will compare the expected value to the stored snapshot and will fail if they don’t match. Jest shows a nicely formatted error message and diff view on failed tests.
</description>
      <content:encoded><![CDATA[<p>Writing tests can sometimes be a tedious task. Mocks and assertions can be a pain in the ass. The latter is especially nasty when HTML is involved. Give me the second p element from the 30th div within an article in aside etc. &ndash; no thanks.</p>
<p>The creators of Jest (Facebook) have found a better way: Snapshot tests!</p>
<h2 id="how-does-it-work"><a href="#how-does-it-work" class="heading-anchor">How does it work?</a></h2>
<p>Take a look at the following assertion:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="nx">it</span><span class="p">(</span><span class="s1">&#39;should create a foo bar object&#39;</span><span class="p">,</span> <span class="p">()</span> <span class="p">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="kr">const</span> <span class="nx">result</span> <span class="o">=</span> <span class="nx">foo</span><span class="p">.</span><span class="nx">bar</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">  <span class="nx">expect</span><span class="p">(</span><span class="nx">result</span><span class="p">).</span><span class="nx">toMatchSnapshot</span><span class="p">()</span>
</span></span><span class="line"><span class="cl"><span class="p">})</span>
</span></span></code></pre></div><p><code>toMatchSnapshot()</code> takes whatever you give to <code>expect()</code>, serializes it and saves it into a file. The next test run will compare the expected value to the stored snapshot and will fail if they don&rsquo;t match. Jest shows a nicely formatted error message and diff view on failed tests.</p>
<p>This is really useful with generated HTML and/or testing UI behaviour. Just call the method and let it compare to the snapshot.</p>
<h2 id="updating-snapshots"><a href="#updating-snapshots" class="heading-anchor">Updating snapshots</a></h2>
<p>You added something to your code and the snapshot has to be updated? No problem:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">jest --updateSnapshot
</span></span></code></pre></div><p>If you&rsquo;re using the Jest watcher it&rsquo;s even simpler. Just press <code>u</code> to update all snapshots or press <code>i</code> to update the snapshots interactively.</p>
<h2 id="what-about-objects-with-generated-values"><a href="#what-about-objects-with-generated-values" class="heading-anchor">What about objects with generated values?</a></h2>
<p>Here&rsquo;s an example with a randomized id:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="nx">it</span><span class="p">(</span><span class="s1">&#39;should fail every time&#39;</span><span class="p">,</span> <span class="p">()</span> <span class="p">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="kr">const</span> <span class="nx">ship</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">id</span><span class="o">:</span> <span class="nb">Math</span><span class="p">.</span><span class="nx">floor</span><span class="p">(</span><span class="nb">Math</span><span class="p">.</span><span class="nx">random</span><span class="p">()</span> <span class="o">*</span> <span class="mi">20</span><span class="p">),</span>
</span></span><span class="line"><span class="cl">    <span class="nx">name</span><span class="o">:</span> <span class="s1">&#39;USS Defiant&#39;</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="nx">expect</span><span class="p">(</span><span class="nx">ship</span><span class="p">).</span><span class="nx">toMatchSnapshot</span><span class="p">()</span>
</span></span><span class="line"><span class="cl"><span class="p">})</span>
</span></span></code></pre></div><p>The id will change on every test run, so this test will fail every time. Well, shit? Nope. Jest got you covered:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="nx">it</span><span class="p">(</span><span class="s1">&#39;should create a ship&#39;</span><span class="p">,</span> <span class="p">()</span> <span class="p">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="kr">const</span> <span class="nx">ship</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">id</span><span class="o">:</span> <span class="nb">Math</span><span class="p">.</span><span class="nx">floor</span><span class="p">(</span><span class="nb">Math</span><span class="p">.</span><span class="nx">random</span><span class="p">()</span> <span class="o">*</span> <span class="mi">20</span><span class="p">),</span>
</span></span><span class="line"><span class="cl">    <span class="nx">name</span><span class="o">:</span> <span class="s1">&#39;USS Defiant&#39;</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="nx">expect</span><span class="p">(</span><span class="nx">ship</span><span class="p">).</span><span class="nx">toMatchSnapshot</span><span class="p">({</span>
</span></span><span class="line"><span class="cl">    <span class="nx">id</span><span class="o">:</span> <span class="nx">expect</span><span class="p">.</span><span class="nx">any</span><span class="p">(</span><span class="nb">Number</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">  <span class="p">})</span>
</span></span><span class="line"><span class="cl"><span class="p">})</span>
</span></span></code></pre></div><p>Jest will now only compare the type of the id and the test will pass.</p>
<p>For certain objects like a date, there is another possibility:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="nb">Date</span><span class="p">.</span><span class="nx">now</span> <span class="o">=</span> <span class="nx">jest</span><span class="p">.</span><span class="nx">fn</span><span class="p">(()</span> <span class="p">=&gt;</span> <span class="mi">1528902424828</span><span class="p">)</span>
</span></span></code></pre></div><p>A call of <code>Date.now()</code> will call the mock method and always return the same value.</p>
<h2 id="some-advice"><a href="#some-advice" class="heading-anchor">Some advice</a></h2>
<ol>
<li>
<p>Always commit your snapshots! If they are missing, CI systems will always create new snapshots and the tests will become useless.</p>
</li>
<li>
<p>Snapshot tests are an awesome tool, but don&rsquo;t be too lazy. They are no replacement for other assertion types, especially if you&rsquo;re working test-driven. Rather use them alongside your other tests.</p>
</li>
<li>
<p>Write meaningful test names. Well, you heard that one before, didn&rsquo;t you? Really, it helps a lot when tests fail or you have to look inside a snapshot file. Jest takes a test name as an id inside a snapshot file. That&rsquo;s why you have to update a snapshot after changing the name.</p>
</li>
</ol>
]]></content:encoded>
    </item>
    
    <item>
      <title>Introducing DeliveryGuy</title>
      <link>https://webcodr.io/2018/04/introducing-deliveryguy/</link>
      <pubDate>Fri, 27 Apr 2018 23:10:16 +0200</pubDate>
      <guid>https://webcodr.io/2018/04/introducing-deliveryguy/</guid>
      <description>I like the Fetch API. It’s supported by all modern browsers, easy to use and has some really good polyfills for older devices. But Fetch has one major flaw: it will only throw errors if there is a network problem.
That’s a really odd decision from my point of view. Nearly any HTTP library out there throws errors or rejects the promise in case of a HTTP error.
A Fetch response object has the property ok to determine if the server responded with an error, but that’s not very comfortable to use.
</description>
      <content:encoded><![CDATA[<p>I like the Fetch API. It&rsquo;s supported by all modern browsers, easy to use and has some really good polyfills for older devices. But Fetch has one major flaw: it will only throw errors if there is a network problem.</p>
<p>That&rsquo;s a really odd decision from my point of view. Nearly any HTTP library out there throws errors or rejects the promise in case of a HTTP error.</p>
<p>A Fetch response object has the property <code>ok</code> to determine if the server responded with an error, but that&rsquo;s not very comfortable to use.</p>
<p>Since my team and I have decided to use Fetch in a Vue-based web app, I decided to create a little wrapper for much more convenience. Say hello to DeliveryGuy.</p>
<h2 id="usage"><a href="#usage" class="heading-anchor">Usage</a></h2>
<p>Well, surprise, it&rsquo;s a Node module, so just use any package manager you like. My personal choice is yarn.</p>
<p><code>yarn install delivery-guy</code></p>
<h3 id="example"><a href="#example" class="heading-anchor">Example</a></h3>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="kr">import</span> <span class="p">{</span> <span class="nx">deliverJson</span> <span class="p">}</span> <span class="nx">from</span> <span class="s1">&#39;delivery-guy&#39;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">getItems</span> <span class="o">=</span> <span class="kr">async</span> <span class="p">()</span> <span class="p">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">try</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kr">const</span> <span class="nx">items</span> <span class="o">=</span> <span class="kr">await</span> <span class="nx">deliverJson</span><span class="p">(</span><span class="s1">&#39;/api/items&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">items</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span> <span class="k">catch</span> <span class="p">(</span><span class="nx">e</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">console</span><span class="p">.</span><span class="nx">error</span><span class="p">(</span><span class="nx">e</span><span class="p">.</span><span class="nx">message</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s1">&#39;HTTP Status&#39;</span><span class="p">,</span> <span class="nx">e</span><span class="p">.</span><span class="nx">response</span><span class="p">.</span><span class="nx">status</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s1">&#39;Response Body&#39;</span><span class="p">,</span> <span class="nx">e</span><span class="p">.</span><span class="nx">responseBody</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><h3 id="whats-going-on-here"><a href="#whats-going-on-here" class="heading-anchor">What&rsquo;s going on here?</a></h3>
<p>DeliveryGuy exports two main functions:</p>
<ul>
<li><code>deliver()</code> will return a <a href="https://developer.mozilla.org/en-US/docs/Web/API/Response">response promise</a> like <code>fetch()</code> does.</li>
<li><code>deliverJson()</code> presumes your response body contains JSON. It&rsquo;s basically a shortcut and returns the promise of <code>Response.json()</code>.</li>
</ul>
<p>Both will accept the same two parameters as <code>fetch()</code> does and pass them along.</p>
<p>If the server responds with a HTTP error, DeliveryGuy will throw an error.</p>
<p>Due to the inheritance limitations of built-in classes with ES5 I mentioned in my <a href="/2018/04/why-custom-errors-in-javascript-with-babel-are-broken/">last post</a>, it&rsquo;s only possible to set custom properties of a custom error class.</p>
<p>DeliveryGuy provides two additional properties on an error object:</p>
<ul>
<li><code>response</code> has the original response object of a Fetch call.</li>
<li><code>responseBody</code> contains the response body and will try to parse it as JSON. If <code>JSON.parse</code> fails, it will return the response body in its original state.</li>
</ul>
<h2 id="tldr"><a href="#tldr" class="heading-anchor">TL;DR</a></h2>
<p>DeliveryGuy allows you to comfortably call the Fetch API without a hassle on HTTP errors. Just use <code>try/catch</code> and you&rsquo;re done.</p>
<p>Please let me know on <a href="https://github.com/WebCodr/delivery-guy">GitHub</a> if you have feedback, a feature request or found a bug. Thank you!</p>
]]></content:encoded>
    </item>
    
    <item>
      <title>Why custom errors in JavaScript with Babel are broken</title>
      <link>https://webcodr.io/2018/04/why-custom-errors-in-javascript-with-babel-are-broken/</link>
      <pubDate>Fri, 27 Apr 2018 10:50:35 +0200</pubDate>
      <guid>https://webcodr.io/2018/04/why-custom-errors-in-javascript-with-babel-are-broken/</guid>
      <description>Have you ever tried to write a custom error class in JavaScript? Well, it does work to a certain extent. But if you want to add custom methods or call instanceof to determine the error type it will not work properly.
Here is a little example of a custom error class:
class MyError extends Error { constructor(foo = &#39;bar&#39;, ...params) { super(...params) if (Error.captureStackTrace) { Error.captureStackTrace(this, MyError) } this.foo = foo } getFoo() { return this.foo } } try { throw new MyError(&#39;myBar&#39;) } catch(e) { console.log(e instanceof MyError) // -&gt; false console.log(e.getFoo()) // -&gt; Uncaught TypeError: e.getFoo is not a function } Works fine in any browser with ES6/ES2015 support, but if you transpile the example with Babel to ES5 and execute the code, you will get the results shown in the comments.
</description>
      <content:encoded><![CDATA[<p>Have you ever tried to write a custom error class in JavaScript? Well, it does work to a certain extent. But if you want to add custom methods or call <code>instanceof</code> to determine the error type it will not work properly.</p>
<p>Here is a little example of a custom error class:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-js" data-lang="js"><span class="line"><span class="cl"><span class="kr">class</span> <span class="nx">MyError</span> <span class="kr">extends</span> <span class="nb">Error</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nx">constructor</span><span class="p">(</span><span class="nx">foo</span> <span class="o">=</span> <span class="s1">&#39;bar&#39;</span><span class="p">,</span> <span class="p">...</span><span class="nx">params</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kr">super</span><span class="p">(...</span><span class="nx">params</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    
</span></span><span class="line"><span class="cl">    <span class="k">if</span> <span class="p">(</span><span class="nb">Error</span><span class="p">.</span><span class="nx">captureStackTrace</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nb">Error</span><span class="p">.</span><span class="nx">captureStackTrace</span><span class="p">(</span><span class="k">this</span><span class="p">,</span> <span class="nx">MyError</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">    
</span></span><span class="line"><span class="cl">    <span class="k">this</span><span class="p">.</span><span class="nx">foo</span> <span class="o">=</span> <span class="nx">foo</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl">  
</span></span><span class="line"><span class="cl">  <span class="nx">getFoo</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">foo</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">try</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="k">throw</span> <span class="k">new</span> <span class="nx">MyError</span><span class="p">(</span><span class="s1">&#39;myBar&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span> <span class="k">catch</span><span class="p">(</span><span class="nx">e</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">e</span> <span class="k">instanceof</span> <span class="nx">MyError</span><span class="p">)</span> <span class="c1">// -&gt; false
</span></span></span><span class="line"><span class="cl">  <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="nx">e</span><span class="p">.</span><span class="nx">getFoo</span><span class="p">())</span> <span class="c1">// -&gt; Uncaught TypeError: e.getFoo is not a function
</span></span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>Works fine in any browser with ES6/ES2015 support, but if you transpile the example with Babel to ES5 and execute the code, you will get the results shown in the comments.</p>
<h2 id="why"><a href="#why" class="heading-anchor">Why</a></h2>
<p>Due to limitations of ES5 it&rsquo;s not possible to inherit from built-in classes like <code>Error</code>, see the <a href="https://babeljs.io/docs/usage/caveats/#classes">Babel docs</a>.</p>
<h3 id="possible-solution"><a href="#possible-solution" class="heading-anchor">Possible solution</a></h3>
<p>The docs mention a plug-in called <code>babel-plugin-transform-builtin-extend</code> to resolve this issue, but if you have to support older browsers it may not help. In order to work the plug-in needs support for <code>__proto__</code>. Take a guess which browser does not support <code>__proto__</code> &hellip; and of course, it&rsquo;s the web developer&rsquo;s best friend aka Internet Explorer. Thankfully it affects only version 10 and below.</p>
<h3 id="workaround"><a href="#workaround" class="heading-anchor">Workaround</a></h3>
<p>If it&rsquo;s not feasible to use the plug-in, you can at least access properties set in the constructor. A call to <code>e.foo</code> in the example is possible, but <code>e instanceof MyError</code> will return <code>false</code>, since you will always get an instance of <code>Error</code>.</p>
<h2 id="conclusion"><a href="#conclusion" class="heading-anchor">Conclusion</a></h2>
<p>Nothing of this is ideal. We have to wait until it&rsquo;s possible to use ES6/ES2015 directly. Yes, we all could set our transpile targets to ES6/ES2015 today, but our clients usually won&rsquo;t allow it. Some customer is always browsing the web with an ancient device/browser.</p>
]]></content:encoded>
    </item>
    
    <item>
      <title>Awesome tests with Vue and Jest</title>
      <link>https://webcodr.io/2018/04/awesome-tests-with-vue-and-jest/</link>
      <pubDate>Wed, 25 Apr 2018 17:27:26 +0200</pubDate>
      <guid>https://webcodr.io/2018/04/awesome-tests-with-vue-and-jest/</guid>
      <description>Jest is a very neat JavaScript testing library from Facebook. It’s mostly syntax-compatible with Jasmine and needs zero or very little configuration. Code coverage reports are there out-of-the-box and with sandboxed tests and snapshot testing it has some unique features.
Set-up Jest Vue CLI You are using Vue CLI? Consider yourself lucky, the set-up of Jest could not be simpler:
yarn add --dev jest @vue/cli-plugin-unit-jest vue invoke unit-jest Vue CLI will do the rest and also create an example spec for the HelloWorld component.
</description>
      <content:encoded><![CDATA[<p>Jest is a very neat JavaScript testing library from Facebook. It&rsquo;s mostly syntax-compatible with Jasmine and needs zero
or very little configuration. Code coverage reports are there out-of-the-box and with sandboxed tests and snapshot testing
it has some unique features.</p>
<h2 id="set-up-jest"><a href="#set-up-jest" class="heading-anchor">Set-up Jest</a></h2>
<h3 id="vue-cli"><a href="#vue-cli" class="heading-anchor">Vue CLI</a></h3>
<p>You are using Vue CLI? Consider yourself lucky, the set-up of Jest could not be simpler:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">yarn add --dev jest @vue/cli-plugin-unit-jest
</span></span><span class="line"><span class="cl">vue invoke unit-jest
</span></span></code></pre></div><p>Vue CLI will do the rest and also create an example spec for the HelloWorld component.</p>
<h3 id="diy"><a href="#diy" class="heading-anchor">DIY</a></h3>
<p>Install all necessary dependencies:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">yarn add --dev @vue/test-utils babel-jest jest jest-serializer-vue vue-jest
</span></span></code></pre></div><p>Create <code>jest.config.js</code> in your project root directory:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="nx">module</span><span class="p">.</span><span class="nx">exports</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nx">moduleFileExtensions</span><span class="o">:</span> <span class="p">[</span><span class="s1">&#39;js&#39;</span><span class="p">,</span> <span class="s1">&#39;json&#39;</span><span class="p">,</span> <span class="s1">&#39;vue&#39;</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">  <span class="nx">transform</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="s1">&#39;^.+\\.vue$&#39;</span><span class="o">:</span> <span class="s1">&#39;vue-jest&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="s1">&#39;^.+\\.js?$&#39;</span><span class="o">:</span> <span class="s1">&#39;babel-jest&#39;</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="nx">moduleNameMapper</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="s1">&#39;^@/(.*)$&#39;</span><span class="o">:</span> <span class="s1">&#39;&lt;rootDir&gt;/src/$1&#39;</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="nx">snapshotSerializers</span><span class="o">:</span> <span class="p">[</span><span class="s1">&#39;jest-serializer-vue&#39;</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">  <span class="nx">testMatch</span><span class="o">:</span> <span class="p">[</span><span class="s1">&#39;&lt;rootDir&gt;/src/tests/**/*.spec.js&#39;</span><span class="p">]</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>Please adjust the paths in <code>moduleNameMapper</code> and <code>testMatch</code> to your project.</p>
<p>You should also add a modern JavaScript preset to your <code>.babelrc</code> file:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="s2">&#34;presets&#34;</span><span class="o">:</span> <span class="p">[</span><span class="s2">&#34;es2015&#34;</span><span class="p">]</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><h4 id="optional-step"><a href="#optional-step" class="heading-anchor">Optional step</a></h4>
<p>Add the following line to your <code>.gitignore</code> file:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">/coverage
</span></span></code></pre></div><p>The set-up is now complete. Let&rsquo;s write a test file!</p>
<h2 id="writing-tests"><a href="#writing-tests" class="heading-anchor">Writing tests</a></h2>
<p>Here is a little example Vue component:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-html" data-lang="html"><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">template</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;</span><span class="nt">ul</span> <span class="na">class</span><span class="o">=</span><span class="s">&#34;demo&#34;</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">    <span class="p">&lt;</span><span class="nt">li</span> <span class="na">class</span><span class="o">=</span><span class="s">&#34;demo__item&#34;</span> <span class="na">v-for</span><span class="o">=</span><span class="s">&#34;value in values&#34;</span> <span class="na">:key</span><span class="o">=</span><span class="s">&#34;value&#34;</span><span class="p">&gt;</span>{{ value }}<span class="p">&lt;/</span><span class="nt">li</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">  <span class="p">&lt;/</span><span class="nt">ul</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">template</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">script</span><span class="p">&gt;</span>
</span></span><span class="line"><span class="cl"><span class="kr">export</span> <span class="k">default</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nx">name</span><span class="o">:</span> <span class="s1">&#39;demo&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nx">data</span> <span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nx">values</span><span class="o">:</span> <span class="p">[]</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="nx">created</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="k">this</span><span class="p">.</span><span class="nx">fetchValues</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="nx">methods</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kr">async</span> <span class="nx">fetchValues</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="kr">const</span> <span class="nx">response</span> <span class="o">=</span> <span class="kr">await</span> <span class="nx">fetch</span><span class="p">(</span><span class="s1">&#39;/api/demo/values&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">      <span class="k">this</span><span class="p">.</span><span class="nx">values</span> <span class="o">=</span> <span class="kr">await</span> <span class="nx">response</span><span class="p">.</span><span class="nx">json</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">&lt;/</span><span class="nt">script</span><span class="p">&gt;</span>
</span></span></code></pre></div><p>The component <code>Demo</code> will fetch some values after its creation and display them in an unordered list. This example is quite
simple, but testing is a little more complex due to the usage of <code>fetch</code>, <code>async</code> and <code>await</code>.</p>
<p>Of course, there are some tools to help us:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-shell" data-lang="shell"><span class="line"><span class="cl">yarn add --dev fetch-mock flush-promises
</span></span></code></pre></div><p>Now, let&rsquo;s write a test:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="kr">import</span> <span class="p">{</span> <span class="nx">shallow</span> <span class="p">}</span> <span class="nx">from</span> <span class="s1">&#39;@vue/test-utils&#39;</span>
</span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="nx">fetchMock</span> <span class="nx">from</span> <span class="s1">&#39;fetch-mock&#39;</span>
</span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="nx">flushPromises</span> <span class="nx">from</span> <span class="s1">&#39;flush-promises&#39;</span>
</span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="nx">Demo</span> <span class="nx">from</span> <span class="s1">&#39;@/components/Demo.vue&#39;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">values</span> <span class="o">=</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">  <span class="s1">&#39;foo&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="s1">&#39;bar&#39;</span>
</span></span><span class="line"><span class="cl"><span class="p">]</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nx">describe</span><span class="p">(</span><span class="s1">&#39;Demo.vue&#39;</span><span class="p">,</span> <span class="p">()</span> <span class="p">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nx">beforeEach</span><span class="p">(()</span> <span class="p">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">fetchMock</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s1">&#39;/api/demo/values&#39;</span><span class="p">,</span> <span class="nx">values</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">  <span class="p">})</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="nx">it</span><span class="p">(</span><span class="s1">&#39;renders component&#39;</span><span class="p">,</span> <span class="kr">async</span> <span class="p">()</span> <span class="p">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kr">const</span> <span class="nx">wrapper</span> <span class="o">=</span> <span class="nx">shallow</span><span class="p">(</span><span class="nx">Demo</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="kr">await</span> <span class="nx">flushPromises</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="nx">expect</span><span class="p">(</span><span class="nx">wrapper</span><span class="p">.</span><span class="nx">vm</span><span class="p">.</span><span class="nx">values</span><span class="p">).</span><span class="nx">toEqual</span><span class="p">(</span><span class="nx">values</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">  <span class="p">})</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">  <span class="nx">afterEach</span><span class="p">(()</span> <span class="p">=&gt;</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">fetchMock</span><span class="p">.</span><span class="nx">restore</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">  <span class="p">})</span>
</span></span><span class="line"><span class="cl"><span class="p">})</span>
</span></span></code></pre></div><h3 id="whats-going-on"><a href="#whats-going-on" class="heading-anchor">What&rsquo;s going on?</a></h3>
<ol>
<li>
<p><code>shallow</code> from Vue Test Utils creates a wrapper of the rendered and mounted component, any child components will be stubs.
If you need child components in your test, please use <code>mount</code> instead of <code>shallow</code>.</p>
</li>
<li>
<p><code>fetchMock</code> will create a mocked version of the Fetch API. In this case it will return the defined values for a GET request to
<code>/api/demo/values</code>. If you send a request that&rsquo;s not defined in fetchMock, it will throw an exception and break your tests.</p>
</li>
<li>
<p>The test itself is defined as async to use <code>await</code> for <code>flushPromises()</code>. It will wait until the mocked request is finished and the values are stored in the component&rsquo;s data.</p>
</li>
<li>
<p>You can now access the data property <code>values</code> and compare the content to the response of the mocked HTTP request.</p>
</li>
</ol>
<h2 id="conclusion"><a href="#conclusion" class="heading-anchor">Conclusion</a></h2>
<p>Setting up Jest for Vue is easy, even if you have to do it manually.</p>
<p><strong>A little warning</strong>: setting up Jest for an existing app can be tedious.
The current AngularJS app of our customer can&rsquo;t be tested with Jest, at least for now. The AngularJS HTTP mock does not work and I haven&rsquo;t figured out the problem yet.</p>
<p>But enough of Angular: the real deal comes with the testing itself. Async/await is a nice and simple way for testing asynchronous behaviour.
I don&rsquo;t think this could be easier and it&rsquo;s a reliable method with the power of modern JavaScript. Try to imagine what the demo test would look like in ES5 &hellip;</p>
]]></content:encoded>
    </item>
    
    <item>
      <title>Vue Loader Setup in Webpack</title>
      <link>https://webcodr.io/2018/04/vue-loader-setup-in-webpack/</link>
      <pubDate>Tue, 24 Apr 2018 16:21:49 +0200</pubDate>
      <guid>https://webcodr.io/2018/04/vue-loader-setup-in-webpack/</guid>
      <description>Since it’s no option to use Vue CLI in my current project, I had to manually add vue-loader to the Webpack config. Well, I was positively surprised how simple it was. Especially compared to a manual set-up of Angular 2 shortly after its launch in late 2016, while Angular CLI was an alpha version and buggy as hell.
Shall we begin? Modules Let’s add the necessary modules to the package:
</description>
      <content:encoded><![CDATA[<p>Since it&rsquo;s no option to use Vue CLI in my current project, I had to manually add <code>vue-loader</code> to the Webpack
config. Well, I was positively surprised how simple it was. Especially compared to a manual set-up of Angular 2 shortly
after its launch in late 2016, while Angular CLI was an alpha version and buggy as hell.</p>
<h2 id="shall-we-begin"><a href="#shall-we-begin" class="heading-anchor">Shall we begin?</a></h2>
<h3 id="modules"><a href="#modules" class="heading-anchor">Modules</a></h3>
<p>Let&rsquo;s add the necessary modules to the package:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-sh" data-lang="sh"><span class="line"><span class="cl">yarn add --dev vue-loader vue-template-compiler
</span></span><span class="line"><span class="cl">yarn add vue
</span></span></code></pre></div><p>If you want to use a template engine like Pug or prefer TypeScript over JavaScript, you can add the respective
Webpack loader package, <code>pug-loader</code> for example. Webpack will also tell you in detail, if modules are missing.</p>
<h3 id="webpack"><a href="#webpack" class="heading-anchor">Webpack</a></h3>
<p>Just add the following rule to your Webpack config:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nx">test</span><span class="o">:</span> <span class="sr">/\.vue$/</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nx">use</span><span class="o">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">    <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nx">loader</span><span class="o">:</span> <span class="s1">&#39;vue-loader&#39;</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">  <span class="p">]</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>Webpack will now be able to use import statements with Vue single file components.</p>
<p>If you want to have a separate JavaScript file with your Vue application, you can add a new entry point:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nx">entry</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="s1">&#39;current-application&#39;</span><span class="o">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">      <span class="nx">path</span><span class="p">.</span><span class="nx">resolve</span><span class="p">(</span><span class="nx">__dirname</span><span class="p">,</span> <span class="s1">&#39;js/current-application.js&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">],</span>
</span></span><span class="line"><span class="cl">    <span class="s1">&#39;vue-application&#39;</span><span class="o">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">      <span class="nx">path</span><span class="p">.</span><span class="nx">resolve</span><span class="p">(</span><span class="nx">__dirname</span><span class="p">,</span> <span class="s1">&#39;js/vue-application.js&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">]</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>Not fancy enough? How about vendor chunks?</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nx">optimization</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">splitChunks</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">      <span class="nx">chunks</span><span class="o">:</span> <span class="s1">&#39;all&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nx">cacheGroups</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nx">vendor</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">          <span class="nx">chunks</span><span class="o">:</span> <span class="s1">&#39;initial&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">          <span class="nx">test</span><span class="o">:</span> <span class="sr">/node_modules\/(?!(vue|vue-resource)\/).*/</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">          <span class="nx">name</span><span class="o">:</span> <span class="s1">&#39;vendor&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">          <span class="nx">enforce</span><span class="o">:</span> <span class="kc">true</span>
</span></span><span class="line"><span class="cl">        <span class="p">},</span>
</span></span><span class="line"><span class="cl">        <span class="s1">&#39;vue-vendor&#39;</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">          <span class="nx">chunks</span><span class="o">:</span> <span class="s1">&#39;initial&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">          <span class="nx">test</span><span class="o">:</span> <span class="sr">/node_modules\/(vue|vue-resource)\/.*/</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">          <span class="nx">name</span><span class="o">:</span> <span class="s1">&#39;vue-vendor&#39;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">          <span class="nx">enforce</span><span class="o">:</span> <span class="kc">true</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">      <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>This will separate your vendor files from <code>node_modules</code> into <code>vendor.js</code> and <code>vue-vendor.js</code>. The property <code>test</code> contains
a regex to determine which modules should go into the vendor chunks.</p>
<p>Of course, this comes not even close to what Vue CLI can do. I highly recommend to use Vue CLI when it&rsquo;s feasible. It&rsquo;s
quite easy to configure while not being dumbed down, has an excellent documentation and is very well maintained. At least
for our customer&rsquo;s set-up it would be difficult to use Vue CLI at the moment, but we are eager to migrate to Vue CLI asap.</p>
]]></content:encoded>
    </item>
    
    <item>
      <title>Real-world Node.js Performance Improvements</title>
      <link>https://webcodr.io/2017/08/real-world-node.js-performance-improvements/</link>
      <pubDate>Mon, 28 Aug 2017 22:00:00 +0200</pubDate>
      <guid>https://webcodr.io/2017/08/real-world-node.js-performance-improvements/</guid>
      <description>I just updated from Node.js 8.2.1 to 8.4.0 within my current project. The update to V8 6.0 really shines as I noticed some major real-world performance improvements.
So I decided to do some tests with the above mentioned versions and the latest LTS version, 6.11.2.
Testing methodology The Webpack build contains the following tasks:
Building of two stylesheets with SASS and Autoprefixer Transpiling with Babel of a large AngularJS app written in ES2015 Copying images and some other static files Chunking into vendor.js and application.js Each test ran nine times for each Node.js version.
</description>
      <content:encoded><![CDATA[<p>I just updated from Node.js 8.2.1 to 8.4.0 within my current project. The update
to V8 6.0 really shines as I noticed some major real-world performance improvements.</p>
<p>So I decided to do some tests with the above mentioned versions and the latest
LTS version, 6.11.2.</p>
<h2 id="testing-methodology"><a href="#testing-methodology" class="heading-anchor">Testing methodology</a></h2>
<p>The Webpack build contains the following tasks:</p>
<ul>
<li>Building of two stylesheets with SASS and Autoprefixer</li>
<li>Transpiling with Babel of a large AngularJS app written in ES2015</li>
<li>Copying images and some other static files</li>
<li>Chunking into <code>vendor.js</code> and <code>application.js</code></li>
</ul>
<p>Each test ran nine times for each Node.js version.</p>
<p>The tests were conducted in dev mode (no minification, no uglification) with
a Debian-based Docker container on Windows 10 Pro with HyperV.</p>
<h2 id="hardware"><a href="#hardware" class="heading-anchor">Hardware</a></h2>
<ul>
<li>Core i7-7700K (the Docker container had access to all cores)</li>
<li>16 GB RAM (8 GB for the Docker container)</li>
<li>PCIe SSD</li>
</ul>
<p>As you can see, the system has more than enough power and is significantly faster
than my MacBook. Docker on HyperV is incredibly fast and a joy to work with.</p>
<h2 id="results"><a href="#results" class="heading-anchor">Results</a></h2>
<p><img src="/images/node-js-webpack-benchmark.png" alt="Node.js performance benckmark" width="748" height="527" loading="lazy" decoding="async" /></p>
<p>The improvement between version 8.2.1 and 8.4.0 is a big deal. V8 6.0
does a great job. Node.js 6 used Crankshaft as JIT, Node 8.0 to 8.2 used a combination
of Crankshaft and Turbofan (V8 5.9). As of version 8.3.0 Node.js utilizes only Turbofan with
V8 6.0.</p>
<p>About 10% improvement with a minor version is a really big step and I&rsquo;m really
looking forward to the next V8 versions and even more power.</p>
]]></content:encoded>
    </item>
    
    <item>
      <title>Webpack 2 with Pug and SASS</title>
      <link>https://webcodr.io/2017/01/webpack-2-with-pug-and-sass/</link>
      <pubDate>Sun, 08 Jan 2017 20:00:00 +0100</pubDate>
      <guid>https://webcodr.io/2017/01/webpack-2-with-pug-and-sass/</guid>
      <description>Until now I used some Gulp tasks with Jade and SASS to create the HTML and CSS files as a base for the webcodr blog theme. A crude little setup, but it worked.
I decided to write a replacement with Webpack 2 and to share it with you: WebCodr/design GitHub repo
First steps The original setup used the indented SASS syntax and Jade templates. Since the indented syntax is more trouble than it’s worth, I had to convert to the SCSS syntax, a superset of the CSS syntax.
</description>
      <content:encoded><![CDATA[<p>Until now I used some Gulp tasks with Jade and SASS to create the HTML and CSS files as a base for the webcodr blog theme. A crude little setup, but it worked.</p>
<p>I decided to write a replacement with Webpack 2 and to share it with you: <a href="https://github.com/WebCodr/design">WebCodr/design GitHub repo</a></p>
<h2 id="first-steps"><a href="#first-steps" class="heading-anchor">First steps</a></h2>
<p>The original setup used the indented SASS syntax and Jade templates. Since the indented syntax is more trouble than it&rsquo;s worth, I had to convert to the SCSS syntax, a superset of the CSS syntax.</p>
<p>Unfortunately there was a copyright claim for &ldquo;Jade&rdquo; and they had to rename the project to Pug. The Jade Node module is still available but unmaintained. It&rsquo;s time to use Pug.</p>
<h3 id="sass-to-scss"><a href="#sass-to-scss" class="heading-anchor">SASS to SCSS</a></h3>
<p>Don&rsquo;t worry, that&rsquo;s quite simple. The SASS people provide a tool called <code>sass-convert</code> and it&rsquo;s really easy to use:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">sass-convert --from<span class="o">=</span>sass --to<span class="o">=</span>scss -R assets/styles/
</span></span></code></pre></div><p>Just pass the tool the format you want to convert, the new format, <code>-R</code> for recursive conversion and add the directory name. After <code>sass-convert</code> finished, you find the new SCSS files along with their SASS predecessors. You can now delete the old SASS files, adjust your build tool and you&rsquo;re done.</p>
<h3 id="jade-to-pug"><a href="#jade-to-pug" class="heading-anchor">Jade to Pug</a></h3>
<p>It depends on your templates how easy or complicated this step is. My template files are rather simple, so just renaming the file extensions from <code>.jade</code> to <code>.pug</code> and using Pug instead of Jade did the job. If you are having trouble, there is a <a href="https://pugjs.org/api/migration-v2.html">migration guide from Jade to Pug</a>.</p>
<h2 id="using-webpack-2"><a href="#using-webpack-2" class="heading-anchor">Using Webpack 2</a></h2>
<p>Webpack 2 isn&rsquo;t finished yet. The current version is 2.2.0 RC3, but even the Beta versions were stable enough to use it for production purposes.</p>
<p>Here&rsquo;s my <code>package.json</code> file with all necessary modules:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-json" data-lang="json"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;name&#34;</span><span class="p">:</span> <span class="s2">&#34;WebCodr_Design&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;version&#34;</span><span class="p">:</span> <span class="s2">&#34;2.0.0&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;scripts&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;server&#34;</span><span class="p">:</span> <span class="s2">&#34;webpack-dev-server&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;dist&#34;</span><span class="p">:</span> <span class="s2">&#34;webpack --config webpack.config.prod.babel.js&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;dependencies&#34;</span><span class="p">:</span> <span class="p">{},</span>
</span></span><span class="line"><span class="cl">  <span class="nt">&#34;devDependencies&#34;</span><span class="p">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;autoprefixer&#34;</span><span class="p">:</span> <span class="s2">&#34;^6.6.1&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;babel-core&#34;</span><span class="p">:</span> <span class="s2">&#34;^6.21.0&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;babel-preset-es2015&#34;</span><span class="p">:</span> <span class="s2">&#34;^6.18.0&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;css-loader&#34;</span><span class="p">:</span> <span class="s2">&#34;^0.26.1&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;csso-loader&#34;</span><span class="p">:</span> <span class="s2">&#34;^0.2.1&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;extract-text-webpack-plugin&#34;</span><span class="p">:</span> <span class="s2">&#34;^2.0.0-beta.4&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;html-loader&#34;</span><span class="p">:</span> <span class="s2">&#34;^0.4.4&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;node-sass&#34;</span><span class="p">:</span> <span class="s2">&#34;^4.1.1&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;postcss-loader&#34;</span><span class="p">:</span> <span class="s2">&#34;^1.2.1&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;pug&#34;</span><span class="p">:</span> <span class="s2">&#34;^2.0.0-beta6&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;pug-html-loader&#34;</span><span class="p">:</span> <span class="s2">&#34;^1.0.10&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;sanitize.css&#34;</span><span class="p">:</span> <span class="s2">&#34;^4.1.0&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;sass-loader&#34;</span><span class="p">:</span> <span class="s2">&#34;^4.1.1&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;webpack&#34;</span><span class="p">:</span> <span class="s2">&#34;2.2.0-rc.3&#34;</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nt">&#34;webpack-dev-server&#34;</span><span class="p">:</span> <span class="s2">&#34;2.2.0-rc.0&#34;</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>I wrote two little helper scripts to run a dev server on port <code>8080</code> and to build a production version of the assets, mainly the CSS file. Currently there is no JavaScript file for webcodr. But it would be really easy to add JavaScript to the Webpack config.</p>
<h3 id="the-webpack-config-or-where-the-magic-happens"><a href="#the-webpack-config-or-where-the-magic-happens" class="heading-anchor">The Webpack config or where the magic happens</a></h3>
<p>I can&rsquo;t stand the old JavaScript syntax anymore, so I write all my stuff in ES2015 and that&rsquo;s why Babel is present in the dev dependencies.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="kr">import</span> <span class="nx">webpack</span> <span class="nx">from</span> <span class="s1">&#39;webpack&#39;</span>
</span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="nx">path</span> <span class="nx">from</span> <span class="s1">&#39;path&#39;</span>
</span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="nx">autoprefixer</span> <span class="nx">from</span> <span class="s1">&#39;autoprefixer&#39;</span>
</span></span><span class="line"><span class="cl"><span class="kr">import</span> <span class="nx">ExtractTextPlugin</span> <span class="nx">from</span> <span class="s1">&#39;extract-text-webpack-plugin&#39;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kd">let</span> <span class="nx">extractStyles</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">ExtractTextPlugin</span><span class="p">(</span><span class="s1">&#39;[name].css&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="kd">let</span> <span class="nx">extractHtml</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">ExtractTextPlugin</span><span class="p">(</span><span class="s1">&#39;[name].html&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kd">let</span> <span class="nx">config</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nx">stats</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">assets</span><span class="o">:</span> <span class="kc">false</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nx">colors</span><span class="o">:</span> <span class="kc">true</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nx">version</span><span class="o">:</span> <span class="kc">false</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nx">hash</span><span class="o">:</span> <span class="kc">true</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nx">timings</span><span class="o">:</span> <span class="kc">true</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nx">chunks</span><span class="o">:</span> <span class="kc">false</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nx">chunkModules</span><span class="o">:</span> <span class="kc">false</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="nx">entry</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">index</span><span class="o">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">      <span class="nx">path</span><span class="p">.</span><span class="nx">resolve</span><span class="p">(</span><span class="nx">__dirname</span><span class="p">,</span> <span class="s1">&#39;templates/index.pug&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">],</span>
</span></span><span class="line"><span class="cl">    <span class="nx">post</span><span class="o">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">      <span class="nx">path</span><span class="p">.</span><span class="nx">resolve</span><span class="p">(</span><span class="nx">__dirname</span><span class="p">,</span> <span class="s1">&#39;templates/post.pug&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">],</span>    
</span></span><span class="line"><span class="cl">    <span class="s1">&#39;css/application&#39;</span><span class="o">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">      <span class="nx">path</span><span class="p">.</span><span class="nx">resolve</span><span class="p">(</span><span class="nx">__dirname</span><span class="p">,</span> <span class="s1">&#39;assets/styles/application.scss&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">    <span class="p">]</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="nx">output</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">path</span><span class="o">:</span> <span class="nx">path</span><span class="p">.</span><span class="nx">resolve</span><span class="p">(</span><span class="nx">__dirname</span><span class="p">,</span> <span class="s1">&#39;build&#39;</span><span class="p">),</span>
</span></span><span class="line"><span class="cl">    <span class="nx">filename</span><span class="o">:</span> <span class="s1">&#39;[name].js&#39;</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="nx">module</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">rules</span><span class="o">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">      <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nx">test</span><span class="o">:</span> <span class="sr">/\.pug$/</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nx">loader</span><span class="o">:</span> <span class="nx">extractHtml</span><span class="p">.</span><span class="nx">extract</span><span class="p">({</span>
</span></span><span class="line"><span class="cl">          <span class="nx">loader</span><span class="o">:</span> <span class="p">[</span><span class="s1">&#39;html-loader&#39;</span><span class="p">,</span> <span class="s1">&#39;pug-html-loader?pretty&amp;exports=false&#39;</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">        <span class="p">})</span>
</span></span><span class="line"><span class="cl">      <span class="p">},</span>
</span></span><span class="line"><span class="cl">      <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nx">test</span><span class="o">:</span> <span class="sr">/\.scss$/</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">        <span class="nx">loader</span><span class="o">:</span> <span class="nx">extractStyles</span><span class="p">.</span><span class="nx">extract</span><span class="p">({</span>
</span></span><span class="line"><span class="cl">          <span class="nx">loader</span><span class="o">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">            <span class="p">{</span>
</span></span><span class="line"><span class="cl">              <span class="nx">loader</span><span class="o">:</span> <span class="s1">&#39;css-loader&#39;</span>
</span></span><span class="line"><span class="cl">            <span class="p">},</span>
</span></span><span class="line"><span class="cl">            <span class="p">{</span>
</span></span><span class="line"><span class="cl">              <span class="nx">loader</span><span class="o">:</span> <span class="s1">&#39;postcss-loader&#39;</span>
</span></span><span class="line"><span class="cl">            <span class="p">},</span>
</span></span><span class="line"><span class="cl">            <span class="p">{</span>
</span></span><span class="line"><span class="cl">              <span class="nx">loader</span><span class="o">:</span> <span class="s1">&#39;sass-loader&#39;</span>
</span></span><span class="line"><span class="cl">            <span class="p">}</span>
</span></span><span class="line"><span class="cl">          <span class="p">]</span>
</span></span><span class="line"><span class="cl">        <span class="p">})</span>
</span></span><span class="line"><span class="cl">      <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">]</span>
</span></span><span class="line"><span class="cl">  <span class="p">},</span>
</span></span><span class="line"><span class="cl">  <span class="nx">plugins</span><span class="o">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">    <span class="k">new</span> <span class="nx">webpack</span><span class="p">.</span><span class="nx">LoaderOptionsPlugin</span><span class="p">({</span>
</span></span><span class="line"><span class="cl">      <span class="nx">minimize</span><span class="o">:</span> <span class="kc">false</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nx">debug</span><span class="o">:</span> <span class="kc">true</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">      <span class="nx">options</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nx">postcss</span><span class="o">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">          <span class="nx">autoprefixer</span><span class="p">({</span>
</span></span><span class="line"><span class="cl">            <span class="nx">browsers</span><span class="o">:</span> <span class="p">[</span><span class="s1">&#39;last 2 version&#39;</span><span class="p">,</span> <span class="s1">&#39;Explorer &gt;= 10&#39;</span><span class="p">,</span> <span class="s1">&#39;Android &gt;= 4&#39;</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">          <span class="p">})</span>
</span></span><span class="line"><span class="cl">        <span class="p">],</span>
</span></span><span class="line"><span class="cl">        <span class="nx">sassLoader</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">          <span class="nx">includePaths</span><span class="o">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">            <span class="nx">path</span><span class="p">.</span><span class="nx">resolve</span><span class="p">(</span><span class="nx">__dirname</span><span class="p">,</span> <span class="s1">&#39;node_modules/sanitize.css/&#39;</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">          <span class="p">]</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">      <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">}),</span>
</span></span><span class="line"><span class="cl">    <span class="nx">extractStyles</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">    <span class="nx">extractHtml</span>
</span></span><span class="line"><span class="cl">  <span class="p">]</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">export</span> <span class="k">default</span> <span class="nx">config</span>
</span></span></code></pre></div><p>Explanations:</p>
<ul>
<li>
<p><code>stats</code>: Webpack 2 is really verbose, this options will help to make it shut up. ;)</p>
</li>
<li>
<p><code>entry</code>: I defined three entry points for Webpack. Two for Pug files and one for my SCSS file. The property name is the filename for saving the finished file and the array item points to the source file.</p>
</li>
<li>
<p><code>output</code>: Defines where to put the files and how to name them.</p>
</li>
<li>
<p><code>module</code>: The module rules tell Webpack what to do with different file extensions. Since Webpack 2 is a JavaScript module bundler it creates JavaScript files and we have to use a plug-in to get HTML and CSS files. The extract text plug-in looks for the content of the defined loaders and extracts it into the file you want.</p>
<p>To convert Pug into HTML I had to use the Pug HTML loader and the HTML loader. The extract text plug-in now knows what to extract of the generated JavaScript files.</p>
<p>The same goes for SASS. The SASS loader converts SASS into CSS, after that the PostCSS loader applies the Autoprefixer and finally the CSS loader tells the extract text plug-in what to do.</p>
</li>
<li>
<p><code>plugins</code>: <code>webpack.LoaderOptionsPlugin</code> contains the loader config for Webpack 1 loaders. Webpack 2 compatible loaders can be configured directly with the loader definition. As you can see, PostCSS loader and SASS loader are not compatible with Webpack 2 yet.</p>
<p>After the configuration of the legacy loaders, I just had to add the extraction plug-in instances and that&rsquo;s it.</p>
</li>
</ul>
<p>When Webpack is started, it will iterate through the entry points and apply the appropriate rules based on the regular expressions in the property <code>test</code>. Each rule applies the loaders in reverse order, so the last loader will be applied first. The loaders themselves obtain their configs from the query as the Pug HTML loader does or from the loader options plug-in, only the extract text plug-in is an exception as it needs two configurations: the loaders and where to put the extracted content.</p>
<p>After Webpack is finished, the files are located in the output directory. There are two files for each entry point: a HTML or CSS file and a JavaScript file. As mentioned above, Webpack 2 is a JavaScript module bundler and can only create JavaScript files without help from plug-ins. Without extraction, these JavaScript files would contain the HTML or CSS code as a Webpack runtime module and could be used within JavaScript.</p>
<p>You could now open one of the HTML files in your browser, but there&rsquo;s a better way. You would have to manually start Webpack for each change to make &hellip; meh.</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-bash" data-lang="bash"><span class="line"><span class="cl">yarn run server
</span></span></code></pre></div><p>This will start the Webpack Dev Server on Port <code>8080</code>. It watches for changes and re-builds all affected files. You just have to reload the browser tab. Not comfy enough? There is a possibility of auto-reloading and even hot JavaScript module replacement which will be explored in a future blog post.</p>
<h3 id="adding-javascript-support"><a href="#adding-javascript-support" class="heading-anchor">Adding JavaScript support</a></h3>
<p>What do you think? Is it complicated to create JavaScript files with a JavaScript module bundler? Of course not!</p>
<p>Add the following rule to your config:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="p">{</span>
</span></span><span class="line"><span class="cl">  <span class="nx">test</span><span class="o">:</span> <span class="sr">/\.js$/</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nx">exclude</span><span class="o">:</span> <span class="sr">/node_modules\/*/</span><span class="p">,</span>
</span></span><span class="line"><span class="cl">  <span class="nx">use</span><span class="o">:</span> <span class="p">[</span><span class="s1">&#39;babel-loader&#39;</span><span class="p">],</span>
</span></span><span class="line"><span class="cl">  <span class="nx">options</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">presets</span><span class="o">:</span> <span class="p">[</span>
</span></span><span class="line"><span class="cl">      <span class="p">[</span><span class="s1">&#39;es2015&#39;</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">    <span class="p">]</span>
</span></span><span class="line"><span class="cl">  <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div><p>Any entry point with JavaScript files will be processed with Babel for ES2015 support. Pretty neat, huh?</p>
<p>Need ES2016 or ES2017? No problem, just add a suitable Babel preset with npm or yarn to your project and adjust the config.</p>
<p>You&rsquo;re using TypeScript or CoffeeScript? No problem, just look for a compatible loader.</p>
<h2 id="conclusion"><a href="#conclusion" class="heading-anchor">Conclusion</a></h2>
<p>Some say Webpack is too complicated. Well, it can be quite confusing if you&rsquo;re just using it without knowledge what it really does, but it&rsquo;s no rocket science.</p>
<p>I used Webpack to replace a rather large and complex collection of Gulp tasks to build the assets for the website of a customer. For certain things like SVG sprite maps I still use Gulp, but all other tasks are done by Webpack faster and way more easy, especially things like hashes in filenames for production purposes or automatically splitting the main JavaScript file into an application file and a vendor file with certain libraries/frameworks like AngularJS.</p>
<p>The same goes for Karma to run the Jasmine tests. Just add the Webpack plug-in for Karma, make some small adjustments to the Webpack config, let Webpack handle the rest and you&rsquo;re done.</p>
<p>Compared to the old Gulp tasks, the Webpack setup is easier to understand, faster and much more fun to use. New team members do not have to dig into a bunch of Gulp tasks and related helper methods. A quick introduction to the Webpack config is mostly enough to understand how it works.</p>
<p>If you have about 1,000 lines of code with Gulp tasks and helper functions or some really small tasks and about 150 lines of Webpack config, what do you prefer?</p>
<h2 id="tldr"><a href="#tldr" class="heading-anchor">TL;DR</a></h2>
<p>Use Webpack 2, it&rsquo;s awesome. :P</p>
]]></content:encoded>
    </item>
    
    <item>
      <title>Schnellere Websites mit RequireJS</title>
      <link>https://webcodr.io/2012/04/schnellere-websites-mit-requirejs/</link>
      <pubDate>Fri, 06 Apr 2012 22:16:42 +0100</pubDate>
      <guid>https://webcodr.io/2012/04/schnellere-websites-mit-requirejs/</guid>
      <description>Script-Elemente sind Blocker im Rendering-Prozess. Browser arbeiten den Quelltext einer Seite von oben nach unten durch. Wenn ein script-Element auftaucht, muss es erst ausgeführt werden, bevor der Browser sich um den nachfolgenden Quelltext kümmern kann. Externe JavaScripts können aus diesem Grund massiven Einfluss auf die Ladegeschwindigkeit einer Seite haben, auch wenn die eigentliche Website schon längst vom Web-Server an den Browser ausgeliefert wurde.
Falls ein externes Script auf einem langsamen Server liegt, muss der Browser warten, bis er es komplett abgerufen und ausgeführt hat. Sollte das aufgerufene Script gar nicht mehr vorhanden sein, wartet der Browser seine Timeout-Einstellung ab, bis er weitermacht. Sicherlich hat jeder schon mal gesehen, dass eine Website nur bis zu einem gewissen Teil angezeigt wird und erst nach ein paar Sekunden der Rest dargestellt wird. Mit sehr hoher Wahrscheinlichkeit, war dies ein nicht mehr vorhandenes oder nur sehr langsam ladendes JavaScript.
</description>
      <content:encoded><![CDATA[<p>Script-Elemente sind Blocker im Rendering-Prozess. Browser arbeiten den Quelltext einer Seite von oben nach unten durch. Wenn ein script-Element auftaucht, muss es erst ausgeführt werden, bevor der Browser sich um den nachfolgenden Quelltext kümmern kann. Externe JavaScripts können aus diesem Grund massiven Einfluss auf die Ladegeschwindigkeit einer Seite haben, auch wenn die eigentliche Website schon längst vom Web-Server an den Browser ausgeliefert wurde.</p>
<p>Falls ein externes Script auf einem langsamen Server liegt, muss der Browser warten, bis er es komplett abgerufen und ausgeführt hat. Sollte das aufgerufene Script gar nicht mehr vorhanden sein, wartet der Browser seine Timeout-Einstellung ab, bis er weitermacht. Sicherlich hat jeder schon mal gesehen, dass eine Website nur bis zu einem gewissen Teil angezeigt wird und erst nach ein paar Sekunden der Rest dargestellt wird. Mit sehr hoher Wahrscheinlichkeit, war dies ein nicht mehr vorhandenes oder nur sehr langsam ladendes JavaScript.</p>
<p>Asynchrones Abholen findet erst nach dem Rendern der Seite statt und blockiert daher nichts. Dazu lässt sich bei konsequentem Nutzen von RequireJS der Einsatz von script-Elementen weitgehend vermeiden. Im Idealfall gibt es nur noch ein script-Element, das RequireJS lädt und ein weiteres Script startet, um die gesamte JavaScript-Funktionalität einer Seite zu initialisieren.</p>
<h3 id="konfiguration"><a href="#konfiguration" class="heading-anchor">Konfiguration</a></h3>
<p>Hier ein simples Beispiel einer Require-JS-Konfiguration mit jQuery:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="p">(</span><span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="nx">require</span><span class="p">.</span><span class="nx">config</span><span class="p">({</span>
</span></span><span class="line"><span class="cl">        <span class="nx">paths</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">            <span class="s1">&#39;jquery&#39;</span><span class="o">:</span> <span class="s1">&#39;libs/jquery/jquery-1.7.1&#39;</span>
</span></span><span class="line"><span class="cl">        <span class="p">}</span>
</span></span><span class="line"><span class="cl">    <span class="p">});</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="nx">require</span><span class="p">([</span><span class="s1">&#39;jquery&#39;</span><span class="p">],</span> <span class="kd">function</span><span class="p">(</span><span class="nx">jQuery</span><span class="p">){</span>
</span></span><span class="line"><span class="cl">      <span class="nx">jQuery</span><span class="p">.</span><span class="nx">noConflict</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">    <span class="p">});</span>
</span></span><span class="line"><span class="cl"><span class="p">})();</span>
</span></span></code></pre></div><p>Zuerst wird RequireJS so konfiguriert, dass <a href="http://jquery.com/">jQuery</a> mittels des Keywords &ldquo;jquery&rdquo; geladen werden kann. Im Konfigurations-Objekt &ldquo;paths&rdquo; wird dafür als Attributsname &ldquo;jquery&rdquo; und als Wert der Pfad (ausgehend vom Verzeichnis des Scripts) zu jQuery gesetzt. Anschließend wird require() aufgerufen und als erster Parameter wird ein Array mit den aufzulösenden Abhängigkeiten erwartet &ndash; hier jQuery. Man kann hier ein unter &ldquo;paths&rdquo; gesetztes Keyword, den Pfad oder auch externe JavaScripts über die URL angeben. Falls es sich um ein Modul handelt, wird auf die Dateiendung &ldquo;.js&rdquo; verzichtet.</p>
<p>Im zweiten Parameter wird eine Callback-Funktion definiert, deren Aufruf unmittelbar nach dem Laden der Abhängigkeiten stattfindet. Als Parameter folgen hier die Rückgaben der angeforderten JavaScript-Dateien. In diesem Fall ist es ein jQuery-Objekt, das sogleich in den No-Conflict-Modus versetzt wird, um nicht mit evtl. anderen geladenen Bibliotheken zu kollidieren. Dieses Verfahren ist besser bekannt als <a href="http://de.wikipedia.org/wiki/Dependency_Injection">Dependency Injection</a>.</p>
<h3 id="module"><a href="#module" class="heading-anchor">Module</a></h3>
<p>RequireJS bietet über die Modul-Definition eine elegante Lösung, Programmbestandteile zu kapseln und Abhängigkeiten (z.B. jQuery) aufzulösen. Aktuell setze ich hier drei Module ein, die Funktionen für einzelne Beiträge (Syntax Highlighting, Lightbox etc.) übernehmen sowie das Tracking über Piwik bzw. Google Analytics starten.</p>
<p>Alle Module sind so aufgebaut, dass sie Abhängigkeiten in Form von Bibliotheken oder anderen Modulen erst auflösen, wenn sie gebraucht werden. Gleichzeitig stellt RequireJS sicher, dass eine Abhängigkeit nur einmal geladen wird und für jedes andere Modul zur Verfügung steht.</p>
<p>Ein Beispiel-Modul:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-javascript" data-lang="javascript"><span class="line"><span class="cl"><span class="nx">define</span><span class="p">([</span><span class="s1">&#39;jquery&#39;</span><span class="p">],</span> <span class="kd">function</span><span class="p">(</span><span class="nx">$</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">    <span class="kd">var</span> <span class="nx">exports</span> <span class="o">=</span> <span class="p">{};</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="nx">exports</span><span class="p">.</span><span class="nx">init</span> <span class="o">=</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl">        <span class="nx">$</span><span class="p">(</span><span class="s1">&#39;body&#39;</span><span class="p">).</span><span class="nx">append</span><span class="p">(</span><span class="s1">&#39;&lt;h1&gt;Hello World!&lt;/h1&gt;&#39;</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">    <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">    <span class="k">return</span> <span class="nx">exports</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span></code></pre></div><p>Mit define() wird die Moduldefinition gestartet. Anschließend passiert das gleiche, wie in der Funktion require(). Zuerst werden die Abhängigkeiten als Array definiert, danach startet eine Dependency Injection in die Callback-Funktion. An dieser Stelle wird ein Dollarzeichen als Parameter für die Abhängigkeit verwendet, um jQuery wie gewohnt einsetzen zu können. Anschließend wird das Objekt &ldquo;exports&rdquo; mit der Methode init() erstellt und zurückgegeben. Wird das Modul an anderer Stelle über require() geladen und das exports-Objekt in die Callback-Funktion injiziert, kann man in ihr die init-Methode aufrufen und damit das Modul starten. Natürlich es ist aber auch möglich, darauf zu verzichten und innerhalb der Modul-Callback-Funktion direkt Code auszuführen.</p>
<p>Um ein Modul an anderer Stelle mit require() zu laden, gibt man den Pfad, ausgehend vom Verzeichnis der RequireJS-Konfiguration, zum Modul an. Wie vorhin schon beschrieben, muss man hierbei auf die Dateiendung &ldquo;.js&rdquo; verzichten.</p>
<p>Zu guter Letzt muss RequireJS selbst samt Konfiguration geladen werden:</p>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-html" data-lang="html"><span class="line"><span class="cl"><span class="p">&lt;</span><span class="nt">script</span> <span class="na">src</span><span class="o">=</span><span class="s">&#34;js/libs/require/require.js&#34;</span> <span class="na">data-main</span><span class="o">=</span><span class="s">&#34;js/config&#34;</span><span class="p">&gt;&lt;/</span><span class="nt">script</span><span class="p">&gt;</span>
</span></span></code></pre></div><p>Ein simples Script-Element hierzu genügt &ndash; am besten unmittelbar vor dem schließenden body-Element. Zusätzlich wird mit dem Daten-Attribut &ldquo;main&rdquo; noch der Pfad zur Konfiguration mitgegeben. RequireJS bindet das entsprechende JavaScript automatisch ein und startet es.</p>
<h3 id="fazit"><a href="#fazit" class="heading-anchor">Fazit</a></h3>
<p>RequireJS ist ein mächtiges Tool, das alleine schon durch die Kapselung in verschiedene Module dem Entwickler sehr viele Vorteile bringt. Durch die immer größer werdende Komplexität von Web-Sites bzw. Web-Applikationen sind andere Formen der Organisation notwendig geworden, die in anderen Programmiersprachen schon von Anfang an vorhanden waren.</p>
<p>Dank der Module mit ihren von RequireJS automatisch aufgelösten Abhängigkeiten durch Dependency Injection, lassen sich schnell und einfach, neue Funktionalitäten in eine Website implementieren, ohne weitere script-Elemente in den HTML-Quelltext einfügen zu müssen.</p>
<p>Bis auf RequireJS selbst werden alle definierten Abhängigkeiten bzw. Module asynchron geladen, ohne das Rendern der Seite zu blockieren. Da Browser asynchrone Anfragen parallel abarbeiten können, werden insgesamt alle Scripts schneller geladen und früher ausgeführt, als es bei einer traditionellen Verwendung von JavaScript möglich wäre.</p>
<p>Das Ergebnis ist ein großer Vorteil für alle Beteiligten. Für den Nutzer wird eine Website mit viel JavaScript deutlich schneller dargestellt, während die Funktionalitäten im Hintergrund nachgeladen werden, ohne dass man etwas davon bemerkt. Aus Sicht der Entwickler bietet RequireJS eine elegante Möglichkeit, schnelle neue Funktionen zu entwickeln, Abhängigkeiten einfach aufzulösen und durch die Module strukturierter zu arbeiten.</p>
<p>Abgesehen von TypeKit und Disqus laufen alle JavaScript-Bestandteile dieser Seite als Modul. Zwar lässt sich TypeKit problemlos als Modul umsetzen, nur werden die Schriften erst nach dem Rendern der Seite geladen. Für etwa eine halbe Sekunde sind die Fallback-Schriften zu sehen, erst dann werden die über TypeKit geladenen Schriften dargestellt. Da das nicht Sinn und Zweck von TypeKit ist und Euch Leser irritiert, wird TypeKit klassisch im head-Element vor den Stylesheets geladen.</p>
<p>Disqus ist dagegen als Wordpress-Plug-In eingebunden und darauf würde ich auch nur sehr ungern verzichten. Ich könnte das Plug-In zwar anpassen, aber damit wäre die Update-Fähigkeit dahin. Da Disqus seine Scripts selbst asynchron lädt, sehe ich auch keine Notwendigkeit, den ganzen Aufwand zu betreiben und Module zu schreiben. Allerdings habe ich andere Plug-Ins wie die Lightbox und das Syntax Highlighting rausgeworfen und durch RequireJS-Module ersetzt, die nun fester Bestandteil des Themes sind. Geladen werden sie aber nur, wenn auch Beiträge vorhanden sind, die eine der Funktionen brauchen.</p>
<p>Falls ich Euer Interesse an RequireJS geweckt habe, könnt Ihr meine Implementierung inkl. eines Ladesystems für Module aus dem HTML-Quelltext heraus im GitHub-Repository meines <a href="https://web.archive.org/web/20131210084100/https://github.com/MadCatme/mcw-blue">Wordpress-Themes</a> anschauen oder auch einen Fork erstellen, um damit selbst entwickeln zu können. Falls jemand Ideen oder Verbesserungen hat, ich freue mich über jede Anregung und jeden Pull-Request in GitHub.</p>
]]></content:encoded>
    </item>
    
  </channel>
</rss>
