<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[blog4code]]></title><description><![CDATA[blog4code]]></description><link>https://alexey.detr.us</link><generator>metalsmith-feed</generator><lastBuildDate>Sat, 27 Apr 2019 19:53:01 GMT</lastBuildDate><atom:link href="https://alexey.detr.us/feed_en.xml" rel="self" type="application/rss+xml"/><item><title><![CDATA[Promise and async/await errors handling]]></title><description><![CDATA[<p>It’s been a long time since my previous post. So many things have been changed in my life. I moved to Sweden and was quite busy last months because of this. But it’s calming down now and I found some time for my blog.</p>
<p>As <a href="/en/posts/2019/2019-01-05-move-from-promises-to-async-await/">I promised previously</a> I’m writing this blog post about errors handling with async/awaits. This one will be just a short note to show an idea of how Promises and async/awaits can work together. Actually, errors handling is a huge topic in software development, but let’s remember only the most popular ways to handle errors in JavaScript:</p>
<ul>
<li>Passing error object in callbacks</li>
<li><code class="codespan-short">try...catch</code> statement in general cases and for async/awaits</li>
<li><code class="codespan-short">.catch()</code> when using Promises</li>
</ul>
<p>As we’re working with async/awaits and Promises, let’s took only the last two.</p>
<p>Sometimes I hear an opinion that if you decided to move from Promises to async/awaits to simplify your code and there was a <code class="codespan-short">Promise.catch</code> you have to use <code class="codespan-short">try...catch</code> statement to convert this. But that’s not actually true, you can mix these approaches to leave your code free from ugly <code class="codespan-short">try...catch</code> statements.</p>
<p>I think I have a good example to demonstrate this. Let’s look onto a new Node.js Promises file system API. <a href="https://nodejs.org/api/fs.html#fs_fspromises_access_path_mode">There is a function <code class="codespan-short">access</code></a> to check if a file is accessible by the current process. It returns a Promise which resolves if it is possible to access a target file and rejects otherwise. If we will try to use that with async/await it’ll look like this:</p>
<pre><code class="lang-js"><span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">isAccessible</span>(<span class="hljs-params">path</span>) </span>{
    <span class="hljs-keyword">let</span> result;

    <span class="hljs-keyword">try</span> {
        <span class="hljs-keyword">await</span> fs.access(path);
        result = <span class="hljs-literal">true</span>;
    } <span class="hljs-keyword">catch</span> (err) {
        result = <span class="hljs-literal">false</span>;
    }

    <span class="hljs-keyword">return</span> result;
}
</code></pre>
<p>That one doesn’t look nice. But what if we’ll try to add a Promise error handling approach here?</p>
<pre><code class="lang-js"><span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">isAccessible</span>(<span class="hljs-params">path</span>) </span>{
    <span class="hljs-keyword">const</span> result = <span class="hljs-keyword">await</span> fs.access(path)
        .then(<span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> <span class="hljs-literal">true</span>)
        .catch(<span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> <span class="hljs-literal">false</span>);

    <span class="hljs-keyword">return</span> result;
}
</code></pre>
<p>So how that could be possible? We know that returned Promise from <code class="codespan-short">access</code> resolves and rejects depending from the check result, so I think it’s a nice idea to convert this behavior to the values we need: <code class="codespan-short">true</code> or <code class="codespan-short">false</code>.</p>
<p>Moreover, there’s no need to make this function async and add await to get a result. Actually, it’s possible to simplify it further.</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">isAccessible</span>(<span class="hljs-params">path</span>) </span>{
    <span class="hljs-keyword">return</span> fs.access(path)
        .then(<span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> <span class="hljs-literal">true</span>)
        .catch(<span class="hljs-function"><span class="hljs-params">()</span> =&gt;</span> <span class="hljs-literal">false</span>);
}

<span class="hljs-comment">// Usage</span>

<span class="hljs-keyword">if</span> (<span class="hljs-keyword">await</span> isAccessible(<span class="hljs-string">'/etc/passwd'</span>)) {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'The passwd file can be read by current process.'</span>);
} <span class="hljs-keyword">else</span> {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'The passwd file can\'t be read by current process.'</span>);
}
</code></pre>
<p>Here is a really handy function <code class="codespan-short">isAccessible</code> which returns Promise and it always resolves <code class="codespan-short">true</code> or <code class="codespan-short">false</code> and never rejects.</p>
<p>So what we got here? We should always keep in mind that Promises and async/awaits are tightly connected in JavaScript and use this knowledge to keep the code as clean as possible.</p>
<p>That’s it, thanks for reading this. Hope this note was helpful.</p>
<h2 id="see-also">See also</h2>
<ol>
<li><a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/catch">Promise.catch MDN article with nice examples and comprehensive description</a></li>
<li><a href="https://nodejs.org/api/fs.html#fs_fs_promises_api">Node’s promises FS API documentation</a></li>
</ol>
]]></description><link>https://alexey.detr.us/en/posts/2019/2019-04-27-promise-and-async-await-mixing-errors-handling</link><guid isPermaLink="false">/lang/en/posts/2019/2019-04-27-promise-and-async-await-mixing-errors-handling/index.md</guid><pubDate>Sat, 27 Apr 2019 21:48:57 GMT</pubDate></item><item><title><![CDATA[Move from Promise to async/await]]></title><description><![CDATA[<p>For some of you, this topic can be very familiar, but I think it is still actual nowadays. I wanted to write this post because we started to use async/awaits in our big project and I have some experience to share.</p>
<p>I don’t want to dive deep into details about generators and other approaches which were predecessors of async/await but I want to show how to easily migrate from Promises to async/awaits in your project and when you should pay attention with async/awaits.</p>
<h2 id="promise">Promise</h2>
<p>First of all, let’s remember what is the Promise? As it is <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/promise">written in MDN</a></p>
<blockquote>
<p>Promise is an object which represents the eventual completion (or failure) of an asynchronous operation, and its resulting value.</p>
</blockquote>
<p>In other words, Promise is an unknown result of some operation which will be known in the future. Usually, we can meet Promises in JS when we’re working with remote HTTP requests.</p>
<h2 id="async-await">async/await</h2>
<p>I like a definition that async/await in JS is just a syntax sugar for Promises.</p>
<p>Proposal of this feature exists quite long and it is already on stage 3, so <a href="https://caniuse.com/#feat=async-functions">browsers widely support it</a>. If you don’t need to support ancient browsers (or if you’re already using Webpack) you can freely use async/await.</p>
<p>So why async/await is better than Promise? From a syntax side, async functions are really easier to read. But I think this is a slightly wrong question because async/awaits and Promises are different things and we shouldn’t compare them in this way. I believe that async/awaits and Promises should be used together to unleash the power of asynchronous operations and simplicity of code.</p>
<p>Well, let’s look at the Promise-based example of code:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> fetchGitHubReposCount = <span class="hljs-function"><span class="hljs-params">username</span> =&gt;</span>
    fetch(<span class="hljs-string">`https://api.github.com/users/<span class="hljs-subst">${username}</span>`</span>)
        .then(<span class="hljs-function"><span class="hljs-params">response</span> =&gt;</span> response.json())
        .then(<span class="hljs-function"><span class="hljs-params">result</span> =&gt;</span> result.public_repos);
</code></pre>
<p>The function returns Promise which will resolve repositories count of a specified user. How do we usually use such kind of functions?</p>
<pre><code class="lang-js">fetchGitHubReposCount(<span class="hljs-string">'tc39'</span>)
    .then(<span class="hljs-function"><span class="hljs-params">count</span> =&gt;</span> <span class="hljs-built_in">console</span>.log(count));
</code></pre>
<p>Looks pretty easy. But what if we need to process this result somehow and send it to another URL? Every time we would need another <code class="codespan-short">.then(...)</code> for that. Well, that looks not so nice and we can improve this with async/awaits.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> count = <span class="hljs-keyword">await</span> fetchGitHubReposCount(<span class="hljs-string">'tc39'</span>);
<span class="hljs-built_in">console</span>.log(count);
</code></pre>
<p>Better, isn’t it? The code now looks plain and it is still asynchronous. But what if we need to fetch info about two users simultaneously? Probably you’ve already heard about <code class="codespan-short">Promise.all()</code> and yes, for async/await you should also use <code class="codespan-short">Promise.all()</code> in such cases.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> [countTC39, countMe] = <span class="hljs-keyword">await</span> <span class="hljs-built_in">Promise</span>.all([
    fetchGitHubReposCount(<span class="hljs-string">'tc39'</span>),
    fetchGitHubReposCount(<span class="hljs-string">'alexey-detr'</span>),
]);
</code></pre>
<p>The example above is a nice example of how async/await can be used with Promise together. This is what I meant speaking that we shouldn’t compare them.</p>
<p><strong>Please note.</strong> It is a common mistake when developers forget about simultaneous tasks processing. You shouldn’t blindly write async/await code and expect that it will magically process simultaneous cases. If something can run in parallel you should use <code class="codespan-short">Promise.all</code> or other tricky constructions to achieve optimal performance.</p>
<h2 id="async-function">async function</h2>
<p>Above we used an <code class="codespan-short">await</code> keyword only, but every time there was an <code class="codespan-short">async</code> prefix which is also usually used in conjunction with <code class="codespan-short">function</code>. So what is the <code class="codespan-short">async function</code>? First of all, it is a function which handles <code class="codespan-short">await</code>s inside of it and always returns a Promise.</p>
<p>That’s a nice fact about returning a Promise because we can combine old style Promise-based code with a new one and migrate to async/await smoothly.</p>
<p>In a real world, you can’t just write <code class="codespan-short">await</code> outside of <code class="codespan-short">async function</code> as we did before (it works in browser consoles because they have a special wrapper for that). Let’s rewrite an example above so it would work in a real world.</p>
<pre><code class="lang-js">(<span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> (<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">const</span> [countTC39, countMe] = <span class="hljs-keyword">await</span> <span class="hljs-built_in">Promise</span>.all([
        fetchGitHubReposCount(<span class="hljs-string">'tc39'</span>),
        fetchGitHubReposCount(<span class="hljs-string">'alexey-detr'</span>),
    ]);
})();
</code></pre>
<p>The code is wrapped by an IIFE (Immediately Invoked Function Expression). It is necessary to do so when you’re going to use <code class="codespan-short">await</code> on the root level of a module. But it wouldn’t be an issue with nested functions, they can be async or not.</p>
<h2 id="so-how-async-functions-work">So how async functions work</h2>
<p>Just a few words to describe a program flow inside of async functions. When a program reaches an <code class="codespan-short">await</code> keyword, it interrupts processing of current function and continues it after <code class="codespan-short">await</code>ed Promise is resolved or rejected. There is no any special magic, the logic is exactly the same as if you would write it with Promises. Just imagine that all your <code class="codespan-short">then(...)</code> constructions turned into <code class="codespan-short">await</code>s.</p>
<h2 id="in-the-end">In the end</h2>
<p>So we found out how to change an approach from Promise-based to async/await-based without getting into deep details. But there is also a big domain called an error handling. I’m going to write about errors handling in async/awaits and Promises next time.</p>
<p>That’s it, see you next time.</p>
]]></description><link>https://alexey.detr.us/en/posts/2019/2019-01-05-move-from-promises-to-async-await</link><guid isPermaLink="false">/lang/en/posts/2019/2019-01-05-move-from-promises-to-async-await/index.md</guid><pubDate>Sat, 05 Jan 2019 14:48:40 GMT</pubDate></item><item><title><![CDATA[You don't need lodash…]]></title><description><![CDATA[<p><em>…if you’re using <a href="https://babeljs.io/">Babel</a>.</em></p>
<p>The previous time I wrote a <a href="/en/posts/2018/2018-08-20-webp-nginx-with-fallback/">post about WebP</a> image format, a modern image compression technology. I want to continue the topic about modern Web and today I’m going to tell something about new ECMAScript features and check if lodash is really necessary nowadays.</p>
<h2 id="lodash">lodash</h2>
<p>Why <a href="https://lodash.com/docs">lodash</a> became popular? The answer is really simple. Because it solved a lot of common tasks in JavaScript development. But let’s look closer at this library.</p>
<h3 id="advantages">Advantages</h3>
<p>Lodash has <strong>a lot of handy functions</strong> to work with JavaScript objects, arrays, and even functions. If you have to do something (array sorting, object mapping, function currying, etc), lodash will likely help you with that.</p>
<p>The next advantage is a <strong>null-safety</strong> (resistance to <code class="codespan-short">undefined</code>). What’s that? Have you ever seen a <code class="codespan-long">TypeError: Cannot read property &#39;prop&#39; of undefined</code>? I bet you have. To avoid them you need to wrap your code into conditions:</p>
<pre><code class="lang-js"><span class="hljs-keyword">let</span> obj;
<span class="hljs-keyword">let</span> result;
<span class="hljs-keyword">if</span> (obj) {
    result = obj.prop;
}
</code></pre>
<p>But you can stop doing so with lodash because you can just write <code class="codespan-long">let result = _.get(obj, &#39;prop&#39;)</code> and it will be an equivalent of a code above. This is one of the simplest cases when null-safety is handy.</p>
<h3 id="disadvantages">Disadvantages</h3>
<p>Today we’re living in a world where <a href="https://www.stonetemple.com/mobile-vs-desktop-usage-study/">smartphones are beating desktops by usage stats</a>. We should be prepared for users with very weak devices. Lodash has a performance impact. A code written in a pure JavaScript is much faster than its lodash equivalent. Moreover, lodash <a href="https://bundlephobia.com/result?p=lodash@4.17.10">adds some extra kilobytes</a> to your JavaScript bundles.</p>
<p>Another 3rd party library jQuery was like a plague. Do you remember the time when almost all websites were using jQuery? Developers used jQuery for everything, they learned how to program their websites with jQuery, not JavaScript. I’m afraid lodash is something like a next jQuery now.</p>
<p>The popularity of lodash became its weak side. Obviously, it is nice when every JavaScript developer knows the library. But if you’ll look on the <a href="https://www.npmjs.com/">NPM’s Most depended-upon packages</a> list you’ll find that lodash is in the top of that. That means that lodash is used by the incredible amount of other packages. <strong>But do they actually need lodash?</strong> I definitely want to check it.</p>
<h2 id="investigations">Investigations</h2>
<p>There is a <a href="https://www.npmjs.com/browse/depended/lodash">nice list of popular packages</a> (thanks to npmjs.com) which depend on lodash. I wrote a simple script to clone this list. Finally, I got the 30 most popular packages that are using lodash, this should be enough for the research. Here they are:</p>
<pre><code class="lang-text">Inquirer.js
ant-design
async
cheerio
elasticsearch-js
enzyme
eslint
eslint-plugin-flowtype
eslint-plugin-import
generator
grpc-node
grunt-contrib-watch
gulp-template
gulp-uglify
html-webpack-plugin
http-proxy-middleware
jshint
karma
knex
node-archiver
node-restify
react-dnd
react-native
react-redux
redux-form
sequelize
stylelint
webpack-bundle-analyzer
webpack-manifest-plugin
webpack-merge
</code></pre>
<p>I think you are already familiar with some of them. Actually, most of them will never be used on the client-side and should be installed as <a href="https://docs.npmjs.com/files/package.json#devdependencies">devDependencies</a>. But anyway, all of them are using lodash for some reasons.</p>
<p>So what lodash functions are most popular in these libraries? I tried to fetch them in the following way:</p>
<pre><code class="lang-bash">grep -E <span class="hljs-string">"\s(_|lodash)\.\w+\("</span> -oh -r . | \
    sed -E <span class="hljs-string">"s/.*(lodash|_)\.([a-zA-Z]+).+/_.\2/"</span> | \
    sort | uniq -c | sort -r | head -10
</code></pre>
<p>This shell command searches lodash functions and makes stats. That’s how I got a top 10 most used lodash functions in a top 30 most popular packages which are using lodash:</p>
<pre><code> <span class="hljs-number">123</span> <span class="hljs-module-access"><span class="hljs-module"><span class="hljs-identifier">_</span>.</span></span>map
 <span class="hljs-number">112</span> <span class="hljs-module-access"><span class="hljs-module"><span class="hljs-identifier">_</span>.</span></span>each
  <span class="hljs-number">98</span> <span class="hljs-module-access"><span class="hljs-module"><span class="hljs-identifier">_</span>.</span></span>get
  <span class="hljs-number">97</span> <span class="hljs-module-access"><span class="hljs-module"><span class="hljs-identifier">_</span>.</span></span>extend
  <span class="hljs-number">84</span> <span class="hljs-module-access"><span class="hljs-module"><span class="hljs-identifier">_</span>.</span></span>assign
  <span class="hljs-number">80</span> <span class="hljs-module-access"><span class="hljs-module"><span class="hljs-identifier">_</span>.</span></span>defaults
  <span class="hljs-number">80</span> <span class="hljs-module-access"><span class="hljs-module"><span class="hljs-identifier">_</span>.</span></span>clone
  <span class="hljs-number">74</span> <span class="hljs-module-access"><span class="hljs-module"><span class="hljs-identifier">_</span>.</span></span>template
  <span class="hljs-number">54</span> <span class="hljs-module-access"><span class="hljs-module"><span class="hljs-identifier">_</span>.</span></span>forEach
  <span class="hljs-number">49</span> <span class="hljs-module-access"><span class="hljs-module"><span class="hljs-identifier">_</span>.</span></span>bind
</code></pre><p>First column is an amount of corresponding lodash function usages. That’s look interesting, let’s check if all of them are so necessary.</p>
<h2 id="the-top-10-lodash-functions">The top 10 lodash functions</h2>
<h3 id="_-map">_.map</h3>
<p>Collections mapping is a very common action in the JavaScript world. This lodash function can work with objects and arrays. Usually, we’re using it for mapping array of objects into another array of values, processed somehow. ECMAScript <a href="http://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map">also has this</a> for arrays. So we have a nearly easy way to write identical code using native methods:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> data = [
    {<span class="hljs-attr">id</span>: <span class="hljs-number">1</span>, <span class="hljs-attr">name</span>: <span class="hljs-string">'Bob'</span>},
    {<span class="hljs-attr">id</span>: <span class="hljs-number">2</span>, <span class="hljs-attr">name</span>: <span class="hljs-string">'John'</span>},
    {<span class="hljs-attr">id</span>: <span class="hljs-number">3</span>, <span class="hljs-attr">name</span>: <span class="hljs-string">'Sarah'</span>},
];
data.map(<span class="hljs-function"><span class="hljs-params">item</span> =&gt;</span> item.name);
<span class="hljs-comment">// ['Bob', 'John', 'Sarah']</span>
</code></pre>
<p>But what if data is an object. We can work with that in a very similar way:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> data = {
    <span class="hljs-number">1</span>: {<span class="hljs-attr">name</span>: <span class="hljs-string">'Bob'</span>},
    <span class="hljs-number">2</span>: {<span class="hljs-attr">name</span>: <span class="hljs-string">'John'</span>},
    <span class="hljs-number">3</span>: {<span class="hljs-attr">name</span>: <span class="hljs-string">'Sarah'</span>},
};
<span class="hljs-built_in">Object</span>.values(data).map(<span class="hljs-function"><span class="hljs-params">item</span> =&gt;</span> item.name);
<span class="hljs-comment">// ['Bob', 'John', 'Sarah']</span>
</code></pre>
<p>Remember I told you about null-safety? We can add it either.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> data = <span class="hljs-built_in">Math</span>.random() &gt;= <span class="hljs-number">0.5</span> ? <span class="hljs-literal">undefined</span> : {
    <span class="hljs-number">1</span>: {<span class="hljs-attr">name</span>: <span class="hljs-string">'Bob'</span>},
    <span class="hljs-number">2</span>: {<span class="hljs-attr">name</span>: <span class="hljs-string">'John'</span>},
    <span class="hljs-number">3</span>: {<span class="hljs-attr">name</span>: <span class="hljs-string">'Sarah'</span>},
};
<span class="hljs-built_in">Object</span>.values(data || {}).map(<span class="hljs-function"><span class="hljs-params">item</span> =&gt;</span> item.name);
<span class="hljs-comment">// ['Bob', 'John', 'Sarah'] or []</span>
</code></pre>
<p>Of course you don’t need to think about data type you have with lodash, you can just always write <code class="codespan-short">_.map</code> and it will work. But a native way also looks not bad.</p>
<h3 id="_-each-_-foreach">_.each, _.forEach</h3>
<p><code class="codespan-short">_.each</code> is just an alias for <code class="codespan-short">_.forEach</code>.</p>
<p>This method iterates over arrays and objects. <a href="http://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach">ECMAScript’s <code class="codespan-short">forEach</code> function</a> works only for arrays. If we want to migrate our code from lodash to native JavaScript, approaches would be nearly the same as we used for <code class="codespan-short">_.map</code>.</p>
<p>But actually, there are some more differences between <code class="codespan-short">_.forEach</code> and native <code class="codespan-short">forEach</code>. Lodash version supports breaks, we can break the loop by returning <code class="codespan-short">false</code> from its callback function. If you need to make a break in a native JavaScript, use a <a href="http://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of"><code class="codespan-short">for...of</code> statement</a></p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> data = <span class="hljs-built_in">Math</span>.random() &gt;= <span class="hljs-number">0.5</span> ? <span class="hljs-literal">undefined</span> : {
    <span class="hljs-number">1</span>: {<span class="hljs-attr">name</span>: <span class="hljs-string">'Bob'</span>},
    <span class="hljs-number">2</span>: {<span class="hljs-attr">name</span>: <span class="hljs-string">'John'</span>},
    <span class="hljs-number">3</span>: {<span class="hljs-attr">name</span>: <span class="hljs-string">'Sarah'</span>},
};
<span class="hljs-keyword">const</span> dataArray = <span class="hljs-built_in">Object</span>.values(data || {});
<span class="hljs-keyword">for</span> (<span class="hljs-keyword">const</span> user <span class="hljs-keyword">of</span> dataArray) {
    <span class="hljs-keyword">if</span> (user.name === <span class="hljs-string">'John'</span>) {
        <span class="hljs-keyword">break</span>;
    }
    <span class="hljs-built_in">console</span>.log(user.name);
}
<span class="hljs-comment">// 'Bob'</span>
</code></pre>
<p><code class="codespan-short">for...of</code> usage is even better because you don’t need extra callback functions and your code would run in the same function block.</p>
<h3 id="_-get">_.get</h3>
<p>I believe this one should be on the first place by usage frequency, I don’t know why it isn’t so. This handiest lodash function allows accessing nested object properties safely. It is interesting fact, but ECMAScript already has an alternative for that, a TC39 <a href="https://github.com/tc39/proposal-optional-chaining">optional chaining proposal</a>. Let’s write some code using this new feature.</p>
<p>Optional chaining is on stage 1 and unfortunately it is not possible to run this code on any JavaScript engine, but we can use a <a href="https://babeljs.io/">Babel transpiler</a> for that. To use it I created a simple sandbox project.</p>
<pre><code class="lang-bash">mkdir optional-chaining &amp;&amp; <span class="hljs-built_in">cd</span> optional-chaining
npm init -y
npm i --save-dev @babel/core @babel/cli @babel/plugin-proposal-optional-chaining
<span class="hljs-built_in">echo</span> <span class="hljs-string">'{ "plugins": ["@babel/plugin-proposal-optional-chaining"] }'</span> &gt; .babelrc
</code></pre>
<p>And added some code into <code class="codespan-short">index.js</code></p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> data = [
    <span class="hljs-literal">undefined</span>,
    {<span class="hljs-attr">id</span>: <span class="hljs-number">1</span>, <span class="hljs-attr">name</span>: <span class="hljs-string">'Bob'</span>},
];
data.forEach(<span class="hljs-function"><span class="hljs-params">item</span> =&gt;</span> {
    <span class="hljs-built_in">console</span>.log(item?.name);
});
</code></pre>
<p>Let’s run it</p>
<pre><code class="lang-bash">npx babel index.js | node
// undefined
// Bob
</code></pre>
<p>There was no <code class="codespan-long">TypeError: Cannot read property &#39;name&#39; of undefined</code> while accessing a property <code class="codespan-short">name</code> of <code class="codespan-short">undefined</code>. That’s how null-safety helps us in cases when we aren’t sure about data type we have.</p>
<p>Setting up Babel is a little complicated, but it allows to achieve null-safety in ECMAScript nowadays. In addition, if you’re already using Babel in your project, you can just add this plugin and be happy with this neat feature.</p>
<h3 id="_-extend-_-assign-_-defaults">_.extend, _.assign, _.defaults</h3>
<p>I put these methods together because they are very similar. All of them are used for merging objects in various ways. The difference between <code class="codespan-short">_.extend</code> and <code class="codespan-short">_.assign</code> is that <code class="codespan-short">_.extend</code> enumerates own and prototype object properties. When we are talking about prototypes in JavaScript, we are usually talking about inheritance. You can read about JavaScript inheritance in <a href="http://2ality.com/2012/01/js-inheritance-by-example.html">this comprehensive article</a> by Axel Rauschmayer. I believe that <code class="codespan-short">_.extend</code> is an old-school inheritance-like method, and it would be better to use a modern <code class="codespan-short">class...extends</code> statements today. Using extension of classes in JavaScript is an explicit way to show intents of your code. In practice, there is no drop-in replacement of <code class="codespan-short">_.extend</code> method.</p>
<p>So what’s about <code class="codespan-short">_.assign</code> and <code class="codespan-short">_.defaults</code>. In the real world, their behavior is almost the same but they have a different arguments order. In fact, <code class="codespan-short">_.defaults</code> has more details in its implementation, but usually, it doesn’t matter.</p>
<p>As I said before these group of methods are used for different ways of objects merging. ECMAScript already has a native way for basic objects merging. It is possible with <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax">spread operator</a>, this operator is already a part of ECMAScript 2015 standard. Let’s imagine that we have some settings we want to use by default and some settings to override these defaults:</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">applyDefaultSettings</span>(<span class="hljs-params">settings</span>) </span>{
    <span class="hljs-keyword">const</span> defaultSettings = {<span class="hljs-attr">flag</span>: <span class="hljs-literal">false</span>, <span class="hljs-attr">option</span>: <span class="hljs-number">2</span>, <span class="hljs-attr">value</span>: <span class="hljs-string">'on'</span>};
    <span class="hljs-keyword">return</span> {
        ...defaultSettings,
        ...settings,
    };
}
<span class="hljs-keyword">const</span> settings = {<span class="hljs-attr">option</span>: <span class="hljs-number">5</span>};
<span class="hljs-keyword">const</span> preparedSettings = applyDefaultSettings(settings);
<span class="hljs-built_in">console</span>.log(preparedSettings);
<span class="hljs-comment">// {flag: false, option: 5, value: 'on'}</span>
</code></pre>
<p>Using spreads in this way is a native alternative for both of <code class="codespan-short">_.assign</code> and <code class="codespan-short">_.defaults</code> methods.</p>
<h3 id="_-clone">_.clone</h3>
<p>Lodash clone creates a shallow copy of various data types. But what does shallow mean? It means that nested non-scalar properties of a value would not be copied actually. So if you are trying to make a copy of a value which is an object/array and it has nested objects/arrays, those nested values would not be copied. Let’s check it.</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> bob = {<span class="hljs-attr">name</span>: <span class="hljs-string">'Bob'</span>, <span class="hljs-attr">has</span>: [<span class="hljs-string">'cat'</span>, <span class="hljs-string">'dog'</span>, <span class="hljs-string">'house'</span>]};
<span class="hljs-keyword">const</span> bobsClone = _.clone(bob);
<span class="hljs-built_in">console</span>.log(bob.has === bobsClone.has);
<span class="hljs-comment">// true</span>
<span class="hljs-built_in">console</span>.log(bob === bobsClone);
<span class="hljs-comment">// false</span>
</code></pre>
<p><code class="codespan-short">bob.has</code> and <code class="codespan-short">bobsClone.has</code> are just references to the same array but <code class="codespan-short">bob</code> and <code class="codespan-short">bobsClone</code> are different objects. So <code class="codespan-short">bobsClone</code> is a shallow copy of <code class="codespan-short">bob</code>.</p>
<p>What’s about ECMAScript? Does it have an alternative for the shallow copy? Yes, it has. We can do this with the same spread operator, which we used in previous section. The equivalent of example above in native JavaScript:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> bob = {<span class="hljs-attr">name</span>: <span class="hljs-string">'Bob'</span>, <span class="hljs-attr">has</span>: [<span class="hljs-string">'cat'</span>, <span class="hljs-string">'dog'</span>, <span class="hljs-string">'house'</span>]};
<span class="hljs-keyword">const</span> bobsClone = {...bob};
<span class="hljs-built_in">console</span>.log(bob.has === bobsClone.has);
<span class="hljs-comment">// true</span>
<span class="hljs-built_in">console</span>.log(bob === bobsClone);
<span class="hljs-comment">// false</span>
</code></pre>
<p>Pretty simple isn’t it? Spread operator works for arrays as well. I beleive we don’t need a lodash <code class="codespan-short">_.clone</code> for shallow copying.</p>
<h3 id="_-template">_.template</h3>
<p>Well this one doesn’t have alternatives in a native JavaScript because it’s a part of lodash / <a href="https://underscorejs.org/#template">underscore template engine</a>. Let’s just skip it.</p>
<h3 id="_-bind">_.bind</h3>
<p>Binding context to function is a common practice in JavaScript. It even can bind function arguments, but let’s look at basics. So what does binding mean? Let’s check this example:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> utils = {
    getName() {
        <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>.name;
    }
};
</code></pre>
<p>Here is the <code class="codespan-short">utils</code> object with the <code class="codespan-short">getName</code> method. This method works in some context (<code class="codespan-short">this</code>) and fetches a <code class="codespan-short">name</code> field from the context. By default, the context will be the <code class="codespan-short">utils</code> object itself.</p>
<p>If we will run this method we would get <code class="codespan-short">undefined</code> because the <code class="codespan-short">utils</code> context doesn’t have a <code class="codespan-short">name</code> property.</p>
<p>But there is a way how to substitute a context for function with <code class="codespan-short">bind</code>. This function creates a new function which always runs in a specified context.</p>
<p>Well, I just described what’s the function binding in JavaScript but didn’t tell anything about how to use lodash <code class="codespan-short">_.bind</code> and native <code class="codespan-short">bind</code>. Actually, usage of native and lodash binding functions are really similar:</p>
<pre><code class="lang-js"><span class="hljs-keyword">const</span> context = {<span class="hljs-attr">name</span>: <span class="hljs-string">'Sarah'</span>};

<span class="hljs-keyword">const</span> nativeBoundGetName = utils.getName.bind(context);
nativeBoundGetName();
<span class="hljs-comment">// Sarah</span>

<span class="hljs-keyword">const</span> lodashBoundGetName = _.bind(utils.getName, context);
lodashBoundGetName();
<span class="hljs-comment">// Sarah</span>
</code></pre>
<p>So we have a good alternative for lodash <code class="codespan-short">_.bind</code> method.</p>
<h2 id="conclusions">Conclusions</h2>
<p>Whew, this post turned out quite large. But I believe this little research was important because we found that (probably) lodash is not necessary nowadays. We still need Babel for this sometimes, but it is better to use Babel instead of 3rd party libraries because this is the future of JavaScript language. When new features become a part of ECMAScript standard, they are starting to work without Babel transpiler and JavaScript engines would probably get some native optimizations for them.</p>
<p>Also if you’re developing client-side applications for browsers <a href="https://bundlephobia.com/result?p=lodash@4.17.10">lodash adds extra 24 KB</a> to your JS bundles. Of course, you can add some changes into your code to enable tree-shaking, but if you are using another libraries which depend on lodash you will meet some issues.</p>
<p>That’s all guys, I think it’s time to end this post.</p>
<h2 id="lodash-fp">lodash/fp</h2>
<p>In the end, I just wanted to say a few words about <a href="https://github.com/lodash/lodash/wiki/FP-Guide">lodash/fp</a>. You don’t need it either. If you’ve ever used lodash/fp you probably noticed how bad lodash/fp documentation is. But if you want to use functional programming approaches you would definitely need a library for that. I can recommend using <a href="https://ramdajs.com/">Ramda</a>, it has good documentation and it is <a href="https://bundlephobia.com/result?p=ramda@0.25.0">smaller than lodash</a>. Yet.</p>
<h2 id="see-also">See also</h2>
<ol>
<li><a href="https://gist.github.com/alexey-detr/3e316f95793a1c80843480be15535608">The script</a> I used to download popular NPM packages.</li>
<li>Nice recent article <a href="https://medium.com/@addyosmani/the-cost-of-javascript-in-2018-7d8950fbb5d4">The Cost of JavaScript</a> by Addy Osmani. If you didn’t read it you should do it soon. It contains very important stats about the performance of modern devices and how JS and CSS bundle sizes affect the average user.</li>
<li>A really nice project I found while writing this blog post. Its name <a href="https://github.com/you-dont-need/You-Dont-Need-Lodash-Underscore">You don’t (may not) need Lodash/Underscore</a>. There are many code snippets with native alternatives of some lodash functions.</li>
</ol>
]]></description><link>https://alexey.detr.us/en/posts/2018/2018-08-29-you-dont-need-lodash</link><guid isPermaLink="false">/lang/en/posts/2018/2018-08-29-you-dont-need-lodash/index.md</guid><pubDate>Sun, 02 Sep 2018 19:29:21 GMT</pubDate></item><item><title><![CDATA[WebP and nginx with graceful legacy fallback]]></title><description><![CDATA[<p><em>This is my very first time when I’m writing a blog post in English.</em></p>
<h2 id="webp">WebP</h2>
<p>The main reason I’m writing this post is my recent experience with WebP format on my Node.js project.</p>
<p>Probably you’ve heard something about this format before and know what it is, but I have to tell a few words anyway. <a href="https://developers.google.com/speed/webp/">WebP</a> is a modern image format developed by Google and its main feature is a size efficiency in various conditions. Why it is important? Let’s remember all the cases when we should use different image formats.</p>
<p><strong>PNG</strong>. A transparent image with alpha channel. It is lossless and PNG files are usually huge. However this format supports 32-bit color (24-bit for RGB and 8-bit for alpha channel), so images can be of high quality.</p>
<p><strong>JPEG</strong>. A good old format for photos. But it isn’t so efficient as modern WebP and <a href="https://en.wikipedia.org/wiki/High_Efficiency_Image_File_Format">HEIF</a>. Moreover, it doesn’t support transparent images.</p>
<p><strong>GIF</strong>. A 31 years old format for animated images compression. It’s widely supported by browsers. GIF supports only 256 colors. It also supports transparency, but usually, the quality is awful because of 256 colors.</p>
<p>Sounds depressing, isn’t it? Don’t upset, there is a hope when WebP will be supported by all major browsers, we will forget this as a terrible nightmare. Currently, Blink is the only browser engine, which <a href="https://caniuse.com/#feat=webp">supports WebP image format</a>. However if we will look at relative usage we will see that 73% of global Internet users can see WebP in their browsers. WebP surely worth it.</p>
<h2 id="convert-to-webp">Convert to WebP</h2>
<p>There are thousand ways to convert your existing images to WebP. To do it manually on MacOS you can run following commands:</p>
<pre><code class="lang-bash">brew install webp
cwebp -q 90 image.png -o image.webp
</code></pre>
<p>But it really depends on your platform and image library. I can’t name all possible options. For my web service, I’m using Node.js and ImageMagick for this.</p>
<h2 id="nginx">nginx</h2>
<p>On this step, I’ll help you configure a nginx web-server in the easiest way to support WebP.</p>
<p>First of all, you should put your new WebP images near to your old JPEG/PNG/GIF images, they should have the same name but with <code class="codespan-short">.webp</code> extension. Then let’s change a nginx configuration. We need to change <code class="codespan-short">http</code> section, usually, you can find it in the <code class="codespan-short">/etc/nginx/nginx.conf</code> file, add the following config there:</p>
<pre><code class="lang-nginx">http {
    # ...

    map $http_accept $webp_ext {
        default &quot;&quot;;
        &quot;~image\/webp&quot; &quot;.webp&quot;;
    }

    map $uri $file_ext {
        default &quot;&quot;;
        &quot;~(\.\w+)$&quot; $1;
    }

    # ...
}
</code></pre>
<p>Also, we should make a <code class="codespan-short">location</code> for our images in a <code class="codespan-short">server</code> section. Usually you can find a <code class="codespan-short">server</code> section in the <code class="codespan-long">/etc/nginx/conf.d/default.conf</code> file, but it can depend from your basic nginx configuration.</p>
<pre><code class="lang-nginx"><span class="hljs-section">server</span> {
    <span class="hljs-comment"># ...</span>

    <span class="hljs-attribute">location</span> <span class="hljs-regexp">~* "^(?&lt;path&gt;.+)\.(png|jpeg|jpg|gif)$"</span> {
        <span class="hljs-attribute">try_files</span> <span class="hljs-variable">$path</span><span class="hljs-variable">$webp_ext</span> <span class="hljs-variable">$path</span><span class="hljs-variable">$file_ext</span> =<span class="hljs-number">404</span>;
    }

    <span class="hljs-comment"># ...</span>
}
</code></pre>
<p>And finally please ensure that your <code class="codespan-short">/etc/nginx/mime.types</code> file contains the following line:</p>
<pre><code>image/webp webp<span class="hljs-comment">;</span>
</code></pre><p>If not, you should put it there manually. So nginx will know which <code class="codespan-short">Content-Type</code> header it should send for files with <code class="codespan-short">.webp</code> extension.</p>
<p>And that’s all. Now you can point any of your images normally. If it has corresponding WebP version and a current browser supports WebP nginx will return the WebP version. In any other cases, the legacy format version will be used.</p>
<h2 id="how-it-works">How it works</h2>
<p>It works really nice, but what’s under the hood? For every request nginx creates two variables <code class="codespan-short">$webp_ext</code> and <code class="codespan-short">$file_ext</code></p>
<ol>
<li><code class="codespan-short">$webp_ext</code> equals <code class="codespan-short">.webp</code> if current browser sends <code class="codespan-short">image/webp</code> in the <code class="codespan-short">Accept</code> header. Or it equals empty string otherwise.</li>
<li><code class="codespan-short">$file_ext</code> equals file extension (e.g. <code class="codespan-short">.png</code>) of current URI if current URI has it. Or it equals empty string otherwise.</li>
<li>In the <code class="codespan-short">location</code> for images, the <code class="codespan-short">$path</code> without extension is captured from incoming URI. And after that nginx tries to find a WebP version by concatenating <code class="codespan-short">$path</code> and <code class="codespan-short">$webp_ext</code> variables. If the file doesn’t exist nginx will try the next <code class="codespan-short">$path</code> and <code class="codespan-short">$file_ext</code>.</li>
</ol>
<p>You will see a legacy file extension in the URI whether it’s WebP or not, but browsers are okay with that because nginx sends correct <code class="codespan-short">Content-Type</code> for WebP files.</p>
<p>That’s the secret.</p>
<p>I would be glad if this post helped you with the basic concept of how to make your website WebP ready and keep it compatible with all browsers. In my case, the main page of my website decreased from 1,6 MB to 900 KB. That’s a significant difference. People with bad Internet connection will be happy.</p>
<h2 id="useful-links">Useful links</h2>
<ol>
<li><a href="https://developers.google.com/speed/webp/">The official WebP website</a></li>
<li><a href="https://optimus.keycdn.com/support/jpg-to-webp/">JPEG vs WebP</a> and <a href="https://optimus.keycdn.com/support/png-to-webp/">PNG vs WebP</a> comparison.</li>
<li><a href="https://caniuse.com/#feat=webp">Browser support</a></li>
</ol>
]]></description><link>https://alexey.detr.us/en/posts/2018/2018-08-20-webp-nginx-with-fallback</link><guid isPermaLink="false">/lang/en/posts/2018/2018-08-20-webp-nginx-with-fallback/index.md</guid><pubDate>Mon, 20 Aug 2018 00:48:20 GMT</pubDate></item></channel></rss>