<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Vasily Malykhin</title>
    <description>The latest articles on Forem by Vasily Malykhin (@malykhinvi).</description>
    <link>https://forem.com/malykhinvi</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F397735%2Fe37e3dd5-e2b9-47ef-a152-11133b9f0dd2.jpeg</url>
      <title>Forem: Vasily Malykhin</title>
      <link>https://forem.com/malykhinvi</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/malykhinvi"/>
    <language>en</language>
    <item>
      <title>SemVer - Magic version 0</title>
      <dc:creator>Vasily Malykhin</dc:creator>
      <pubDate>Tue, 06 Apr 2021 19:16:44 +0000</pubDate>
      <link>https://forem.com/malykhinvi/semver-0-x-x-46e7</link>
      <guid>https://forem.com/malykhinvi/semver-0-x-x-46e7</guid>
      <description>&lt;h3&gt;
  
  
  SemVer
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://semver.org/"&gt;Semantic Versioning&lt;/a&gt; defines a package version format and a set of rules that should be used when the package updates. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Under this scheme, version numbers and the way they change convey meaning about the underlying code and what has been modified from one version to the next.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A brief intro to SemVer: you can specify a version of a package using three groups of numbers: &lt;code&gt;major.minor.patch&lt;/code&gt;. When you create a new version of your package, you should:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Increment &lt;code&gt;major&lt;/code&gt; if you introduced a breaking change.&lt;/li&gt;
&lt;li&gt;Increment &lt;code&gt;minor&lt;/code&gt; if you added functionality in a backward-compatible manner.&lt;/li&gt;
&lt;li&gt;Increment &lt;code&gt;patch&lt;/code&gt; if you made a backward-compatible bugfix.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This is pretty much it, although in documents you can find more details.&lt;/p&gt;

&lt;h3&gt;
  
  
  Version ranges
&lt;/h3&gt;

&lt;p&gt;When you work with package managers which rely on semver (e.g. NPM), you can declare specific versions of dependencies or &lt;em&gt;version ranges&lt;/em&gt;, which would allow you to update dependencies easier.&lt;/p&gt;

&lt;p&gt;For example, you can use the &lt;em&gt;caret&lt;/em&gt;(&lt;code&gt;^&lt;/code&gt;) symbol to tell the package manager that all compatible versions are allowed:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// package.json
"dependencies": {
  "react": "^16.0.0"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The above means that all versions of &lt;code&gt;react&lt;/code&gt; up to (but not including) &lt;code&gt;17.0.0&lt;/code&gt; are allowed. So when a new version of &lt;code&gt;react&lt;/code&gt; is out, you can run &lt;code&gt;npm update&lt;/code&gt; and it will download an updated version of it, update your &lt;code&gt;package.json&lt;/code&gt; and a lock file.&lt;/p&gt;

&lt;h3&gt;
  
  
  Magic zero
&lt;/h3&gt;

&lt;p&gt;But there is &lt;a href="https://semver.org/#spec-item-4"&gt;an exception&lt;/a&gt; for packages with &lt;code&gt;major&lt;/code&gt; version equal to &lt;em&gt;zero&lt;/em&gt;, e.g. &lt;code&gt;0.1.2&lt;/code&gt;.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Major version zero (0.y.z) is for initial development. Anything MAY change at any time. The public API SHOULD NOT be considered stable.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Technically, it is legitimate to introduce breaking changes, updating the &lt;code&gt;minor&lt;/code&gt; digit of the package version. So, versions &lt;code&gt;0.1.2&lt;/code&gt; and &lt;code&gt;0.2.0&lt;/code&gt; won't be compatible.&lt;/p&gt;

&lt;p&gt;To prevent potential breaking changes, when you do a minor update of a dependency, NPM treats versions a bit &lt;a href="https://github.com/npm/node-semver#caret-ranges-123-025-004"&gt;different&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Allows changes that do not modify the left-most non-zero element in the [major, minor, patch] tuple. In other words, this allows patch and minor updates for versions 1.0.0 and above, patch updates for versions 0.X &amp;gt;=0.1.0, and no updates for versions 0.0.X.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So, if you have a dependency &lt;code&gt;^0.1.2&lt;/code&gt;, &lt;code&gt;npm update&lt;/code&gt; won't update it to &lt;code&gt;0.2.0&lt;/code&gt;, because only &lt;code&gt;patch&lt;/code&gt; updates are allowed. &lt;br&gt;
I didn't know this subtlety before and when an automatic update didn't work, I thought that it was due to some bug in NPM CLI :) Even worse, I updated the dependencies manually... Even though we had a lot of tests, how on Earth didn't I break anything?!&lt;/p&gt;

&lt;p&gt;Anyways, if you depend directly or transitively on various &lt;code&gt;0.x.y&lt;/code&gt; versions of the same package, you can't do much. But as a package author, if you introduce a backward-compatible update to &lt;code&gt;0.x.y&lt;/code&gt; version, you'd better update &lt;code&gt;patch&lt;/code&gt; instead of &lt;code&gt;minor&lt;/code&gt;. That way the update process would be more streamlined for the package consumers.&lt;/p&gt;

&lt;h3&gt;
  
  
  P.S.
&lt;/h3&gt;

&lt;p&gt;Online semver calculator - &lt;a href="https://semver.npmjs.com/"&gt;https://semver.npmjs.com/&lt;/a&gt;&lt;br&gt;
Discussion related to pre-releases and magic zero - &lt;a href="https://github.com/semver/semver/issues/221"&gt;https://github.com/semver/semver/issues/221&lt;/a&gt;&lt;/p&gt;

</description>
      <category>semver</category>
      <category>npm</category>
    </item>
    <item>
      <title>Eslint vs Performance</title>
      <dc:creator>Vasily Malykhin</dc:creator>
      <pubDate>Sat, 03 Apr 2021 15:33:30 +0000</pubDate>
      <link>https://forem.com/malykhinvi/eslint-vs-performance-5592</link>
      <guid>https://forem.com/malykhinvi/eslint-vs-performance-5592</guid>
      <description>&lt;p&gt;Nowadays, &lt;a href="https://eslint.org/"&gt;eslint&lt;/a&gt; is a very popular tool in the frontend world. It helps you to enforce different code style rules, prevent bugs, and encourage your team to use best practices as you write code. &lt;/p&gt;

&lt;p&gt;Eslint is completely pluggable and you can add as many rules as you wish, and of course, write your own rules. As you start seeing the benefits eslint gives you, it is become very tempting to use each and every rule that you can reach out to.&lt;/p&gt;

&lt;p&gt;But beware! Keep in mind, that with every rule you accumulate the amount of work that needs to get done whenever you lint your code, be it a local development or a part of a CI.&lt;/p&gt;

&lt;p&gt;To get some insights about time spent on every rule you can use a special environment variable &lt;code&gt;TIMING=1&lt;/code&gt;. It will trigger the display of the ten longest-running rules, along with their individual running time and relative performance impact (&lt;a href="https://eslint.org/docs/developer-guide/working-with-rules-deprecated#per-rule-performance"&gt;docs&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Take a look at the timing information on one of the projects I'm working on:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Rule                                    | Time (ms) | Relative
:---------------------------------------|----------:|--------:
import/no-restricted-paths              | 94633.358 |    72.2%
@typescript-eslint/no-floating-promises | 18576.419 |    14.2%
react/no-multi-comp                     |  4629.594 |     3.5%
@typescript-eslint/no-redeclare         |  2634.454 |     2.0%
lodash/callback-binding                 |  1272.849 |     1.0%
@typescript-eslint/naming-convention    |  1209.871 |     0.9%
lodash/collection-return                |   885.415 |     0.7%
lodash/no-unbound-this                  |   669.923 |     0.5%
lodash/collection-method-value          |   668.716 |     0.5%
lodash/no-extra-args                    |   569.119 |     0.4%
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;More than 90 seconds spent on checking a single rule... A little bit too much, isn't it? :)&lt;/p&gt;

&lt;p&gt;In this particular example, the &lt;code&gt;TIMING&lt;/code&gt; report revealed a performance bottleneck and pushed us to contribute to a third-party eslint plugin we used and &lt;a href="https://github.com/benmosher/eslint-plugin-import/pull/2022"&gt;fix it&lt;/a&gt; eventually.&lt;/p&gt;

&lt;p&gt;In addition to obvious performance issues, you might notice that a significant amount of time is wasted on rules that you can live without. For example, most of the code-style-related rules could be replaced with &lt;a href="https://prettier.io/"&gt;prettier&lt;/a&gt;. Some rules just don't give you that much to use them, e.g. &lt;code&gt;react/no-multi-comp&lt;/code&gt; in our case.&lt;br&gt;
As for me, I prefer to follow &lt;a href="https://twitter.com/dan_abramov/status/1086215771401920512?s=20"&gt;this advice&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Look at every linting rule and think: “Does this rule &lt;del&gt;bring  me joy&lt;/del&gt; help me find bugs?” If not, TURN IT OFF.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;But I would add: start with ten the longest-running rules if your goal is to speed up linting. &lt;/p&gt;

</description>
      <category>javascript</category>
      <category>eslint</category>
      <category>performance</category>
    </item>
    <item>
      <title>Fix a transitive npm dependency vulnerability</title>
      <dc:creator>Vasily Malykhin</dc:creator>
      <pubDate>Fri, 29 May 2020 08:50:09 +0000</pubDate>
      <link>https://forem.com/malykhinvi/fix-a-transitive-npm-dependency-vulnerability-4775</link>
      <guid>https://forem.com/malykhinvi/fix-a-transitive-npm-dependency-vulnerability-4775</guid>
      <description>&lt;p&gt;Thanks to community, from time to time, npm reports about vulnerabilities found amongst the installed dependencies. Our team works on a SPA based on react, webpack, storybook, babel, and so on, pretty basic setup nowadays. We strive to keep the number of vulnerabilities as small as possible. But sometimes it is not that easy to fix them.&lt;/p&gt;

&lt;p&gt;The transitive dependency or, in other words, the indirect one might be located very deep in the tree. For example, on March 6th, 2020 a &lt;del&gt;kind of vulnerability&lt;/del&gt; vulnerability in &lt;code&gt;kind-of&lt;/code&gt; package had been &lt;a href="https://www.npmjs.com/advisories/1490" rel="noopener noreferrer"&gt;found&lt;/a&gt;. All of a sudden, we ended up with more than &lt;strong&gt;38000&lt;/strong&gt; of low-level vulnerabilities, reported by &lt;code&gt;npm audit&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F78zim5zmnzubdqipjyk6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F78zim5zmnzubdqipjyk6.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We didn't have it in our &lt;code&gt;package.json&lt;/code&gt; file, but obviously it was used by a ton of packages deep in the tree. For example, take a look at this path to &lt;code&gt;kind-of&lt;/code&gt;:&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

jest&amp;gt;jest-cli&amp;gt;@jest/core&amp;gt;@jest/reporters&amp;gt;jest-runtime&amp;gt;jest-config&amp;gt;@jest/test-sequencer&amp;gt;jest-runner&amp;gt;jest-jasmine2&amp;gt;@jest/environment&amp;gt;@jest/transform&amp;gt;jest-haste-map&amp;gt;jest-util&amp;gt;@jest/fake-timers&amp;gt;jest-message-util&amp;gt;micromatch&amp;gt;nanomatch&amp;gt;kind-of


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The standard recommendation given by the &lt;code&gt;npm audit&lt;/code&gt; is to run &lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

npm update  package-name --depth=N


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;To be honest, I haven't seen it working yet. Sometimes this command does nothing, sometimes it does "so much" that it hangs forever.&lt;/p&gt;

&lt;p&gt;So, the only way to fix it for us was to do it manually. Exploring &lt;code&gt;package-lock.json&lt;/code&gt;, we noticed that a vulnerable version (6.0.2) was installed multiple times by different packages. In order to get rid of the vulnerabilities, we had to update all occurrences of &lt;code&gt;kind-of&lt;/code&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;npm install -D kind-of@6.0.2&lt;/code&gt; - install 6.0.2 to remove duplicates on the next step&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;npm dedupe&lt;/code&gt; - remove duplicates of 6.0.2&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;npm update kind-of&lt;/code&gt; - fix vulnerability upgrading to 6.0.3&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;npm uninstall kind-of&lt;/code&gt; - remove the direct dependency&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;After these manipulations, we saw a much better picture:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Foa9ttkvkqqlo8qulpryt.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Foa9ttkvkqqlo8qulpryt.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In that case, it was rather simple to identify duplicates and find out how to dedupe dependencies. But in more complex cases we find it very useful to use &lt;a href="https://github.com/discoveryjs/quick-start-tutorial" rel="noopener noreferrer"&gt;discovery.js&lt;/a&gt;. See it in action &lt;a href="https://discoveryjs.github.io/quick-start-tutorial/" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;P.S.&lt;br&gt;
Don't pay attention to the rest of the vulnerabilities. We are already working on them ;)&lt;/p&gt;

</description>
      <category>npm</category>
      <category>vulnerabilities</category>
      <category>javascript</category>
    </item>
  </channel>
</rss>
