<?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>DEV Community: Amoniac OÜ</title>
    <description>The latest articles on DEV Community by Amoniac OÜ (@amoniacou).</description>
    <link>https://dev.to/amoniacou</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%2Forganization%2Fprofile_image%2F1785%2Fce392302-95cc-405b-a238-d4983a171f11.png</url>
      <title>DEV Community: Amoniac OÜ</title>
      <link>https://dev.to/amoniacou</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/amoniacou"/>
    <language>en</language>
    <item>
      <title>Micro Kubernetes cluster</title>
      <dc:creator>Oleksandr Simonov</dc:creator>
      <pubDate>Thu, 25 Jun 2020 19:17:38 +0000</pubDate>
      <link>https://dev.to/amoniacou/micro-kubernetes-cluster-3570</link>
      <guid>https://dev.to/amoniacou/micro-kubernetes-cluster-3570</guid>
      <description>&lt;p&gt;We continue playing with Kubernetes and now migrating local development on k3s. I will make a few posts about it in the next two weeks. Also, we decided to test how it working with ARM64. Now Apple is moved to ARM and we want to know how to develop locally on one platform and deploy to another... &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--1cviKgX4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/92un4thxiumner78nars.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--1cviKgX4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/92un4thxiumner78nars.png" alt="Lets party begin!"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>kubernetes</category>
      <category>microservices</category>
      <category>rails</category>
    </item>
    <item>
      <title>Kubernetes in local development</title>
      <dc:creator>Oleksandr Simonov</dc:creator>
      <pubDate>Mon, 23 Mar 2020 20:04:42 +0000</pubDate>
      <link>https://dev.to/amoniacou/kubernetes-in-local-development-3d58</link>
      <guid>https://dev.to/amoniacou/kubernetes-in-local-development-3d58</guid>
      <description>&lt;p&gt;Hey fellows! I think you really tired with COVID-19 right now and thinking about what to learn new.&lt;/p&gt;

&lt;p&gt;Last two weeks I work really productive and tested different tools for local development with Kubernetes. &lt;/p&gt;

&lt;p&gt;The list is next:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Tilt&lt;/li&gt;
&lt;li&gt;Devspace&lt;/li&gt;
&lt;li&gt;Skaffold&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I also tested different local Kubernetes implementations like &lt;code&gt;Kubernetes in Docker Desktop&lt;/code&gt;, &lt;code&gt;minikube&lt;/code&gt; and &lt;code&gt;microk8s&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;So if you are interested in such content, please make love for such post!&lt;/p&gt;

</description>
      <category>docker</category>
      <category>kubernetes</category>
      <category>rails</category>
    </item>
    <item>
      <title>What is Docker? Why is it important and necessary for developers? Part II</title>
      <dc:creator>Oleksandr Simonov</dc:creator>
      <pubDate>Thu, 12 Mar 2020 12:33:03 +0000</pubDate>
      <link>https://dev.to/amoniacou/what-is-docker-why-is-it-important-and-necessary-for-developers-part-ii-pgh</link>
      <guid>https://dev.to/amoniacou/what-is-docker-why-is-it-important-and-necessary-for-developers-part-ii-pgh</guid>
      <description>&lt;p&gt;In the first part of the article, we examined the concept of containerization, looked at the difference between LXC and Docker, and also what else has replaced such a powerful tool in the development world. You can see everything in detail here&lt;/p&gt;

&lt;p&gt;And we continue our review of Docker and talk about the development environment and the main delicacies of Docker.&lt;/p&gt;

&lt;h2&gt;
  
  
  Docker Development Environment
&lt;/h2&gt;

&lt;p&gt;When you develop an application, you need to provide the code along with all its components, such as libraries, servers, databases, etc. You may find yourself in a situation where the application is running on your computer but refuses to turn on on another user's device. And this problem is solved by creating software independence from the system.&lt;/p&gt;

&lt;p&gt;But what is the difference between virtualization?&lt;/p&gt;

&lt;p&gt;Initially, virtualization was designed to eliminate such problems, but it has significant drawbacks:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;slow loading;&lt;/li&gt;
&lt;li&gt;possible payment for the provision of additional space;&lt;/li&gt;
&lt;li&gt;not all virtual machines support compatible use;&lt;/li&gt;
&lt;li&gt;supporting VMs often require complex configuration;&lt;/li&gt;
&lt;li&gt;the image may be too large since the "additional OS" adds a gigabyte of space to the project on top of the operating system, and in most cases, several VMs are put on the server, which takes up even more space.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;But Docker simply shares resources of the OS among all containers (Docker container) that work as separate processes. This is not the only such platform, but, undoubtedly, one of the most popular and in demand.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ocSwi4yX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://lh6.googleusercontent.com/Y3tBD_AuaJCC-44hCcI4F5hp13uM41iOZt_Y0gXu3sjCrS6oYRhS5mQRLzoEKWsgi8OqurU1cDBzs2UMnVX_546tZJYFqmzVT_doal8Q4U4ytJhrQjxBMBiatHeX12QTjt8fuXdX" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ocSwi4yX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://lh6.googleusercontent.com/Y3tBD_AuaJCC-44hCcI4F5hp13uM41iOZt_Y0gXu3sjCrS6oYRhS5mQRLzoEKWsgi8OqurU1cDBzs2UMnVX_546tZJYFqmzVT_doal8Q4U4ytJhrQjxBMBiatHeX12QTjt8fuXdX" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you have not started using Docker, then read on. Docker has changed the approach to building applications and has become an extremely important tool for Developers and DevOps professionals. Using this tool to automate tasks related to development, testing and configuration, let's take a look at how, in a few simple steps, you can make the team more efficient and focus directly on product development.&lt;/p&gt;

&lt;h3&gt;
  
  
  Quick start with docker-compose
&lt;/h3&gt;

&lt;p&gt;Docker-compose is a simple tool that allows you to run multiple docker containers with one command. Before diving into the details, let's talk about the structure of the project. We use monorepo, and the code base of each service (web application, API, background handlers) is stored in its root directory. Each service has a Docker file describing its dependencies. An example of such a structure can be seen in the demo project.&lt;/p&gt;

&lt;p&gt;As an example, consider one of the projects that were developed by our team. The project used technologies such as Ruby (back-end), Vue.js (front-end), and Golang (background jobs). PostgreSQL database and Faktory message broker. Docker-compose works best for linking all of these parts. The configuration for docker-compose is in the docker-compose.yml file, which is located inside the project.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;3'&lt;/span&gt;
&lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
 &lt;span class="na"&gt;postgres-data&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
   &lt;span class="na"&gt;driver&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;local&lt;/span&gt;
 &lt;span class="na"&gt;app-gems&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
   &lt;span class="na"&gt;driver&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;local&lt;/span&gt;
 &lt;span class="na"&gt;node-modules&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
   &lt;span class="na"&gt;driver&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;local&lt;/span&gt;
 &lt;span class="na"&gt;faktory-data&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
   &lt;span class="na"&gt;driver&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;local&lt;/span&gt;
&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;workers&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
     &lt;span class="na"&gt;context&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;../directory_with_go_part&lt;/span&gt;
     &lt;span class="na"&gt;dockerfile&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;dev.Dockerfile&lt;/span&gt;
   &lt;span class="na"&gt;links&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;postgres:db.local&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;faktory:faktory.local&lt;/span&gt;
   &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;../directory_with_go_part:/go/src/directory_with_go_part&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;app-uploads:/uploads:rw&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;../directory_with_go_part/logs:/logs&lt;/span&gt;
   &lt;span class="na"&gt;env_file&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;../upsta-go-workers/.env.docker&lt;/span&gt;
   &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;DATABASE_URL&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;postgres://postgres:password@db.local:5432/development_database&lt;/span&gt;
    &lt;span class="na"&gt;FAKTORY_URL&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;tcp://:password@faktory.local:7419&lt;/span&gt;
    &lt;span class="na"&gt;LOG_PATH&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/logs&lt;/span&gt;
   &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;make run&lt;/span&gt;
  &lt;span class="na"&gt;rails&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
     &lt;span class="na"&gt;context&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;../directory_with_rails_part&lt;/span&gt;
     &lt;span class="na"&gt;dockerfile&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;dev.Dockerfile&lt;/span&gt;
    &lt;span class="na"&gt;links&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
     &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;postgres:db.local&lt;/span&gt;
     &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;faktory:faktory.local&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;../directory_with_rails_part:/app&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;app-gems:/usr/local/bundle&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;node-modules:/app/node_modules&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;app-uploads:/app/public/uploads:rw&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
     &lt;span class="na"&gt;DATABASE_URL&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;postgres://postgres:password@db.local:5432/development_database&lt;/span&gt;
     &lt;span class="na"&gt;FAKTORY_URL&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;tcp://:password@faktory.local:7419&lt;/span&gt;
    &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;foreman start -f Procfile.dev&lt;/span&gt;

  &lt;span class="na"&gt;postgres&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;posrges:11.2-alpine"&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;POSTGRES_PASSWORD&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;password&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="s"&gt;-postgres-data:/var/lib/postgresql/data&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
     &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;5432:5432&lt;/span&gt;
  &lt;span class="s"&gt;faktory:&lt;/span&gt;
    &lt;span class="s"&gt;image:&lt;/span&gt;&lt;span class="nv"&gt; &lt;/span&gt;&lt;span class="s"&gt;"contribsys/faktory:1.0.1"&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;FAKTORY_PASSWORD&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;password&lt;/span&gt;
    &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;/faktory -b 0.0.0.0:7419 -w 0.0.0.0:7420&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
     &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;7420:7420"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;During the first launch, all necessary containers will be created or loaded. At first glance, it’s nothing complicated, especially if you used to work with Docker, but still let's discuss some details:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;context: &lt;code class="code-inline"&gt; ../directory&lt;/code&gt; or context: &lt;code class="code-inline"&gt; .&lt;/code&gt; - this specifies the path to the source code of the service within monorepo.&lt;/li&gt;
&lt;li&gt;dockerfile: dev.Dockerfile - for development environments, we use a separate dockerfiles. In production, the source code is copied directly to the container, and for development is connected as a volume. Therefore, there is no need to recreate the container each time the code is changed.&lt;/li&gt;
&lt;li&gt;volumes: &lt;code class="code-inline"&gt; - "../directory_with_app_code:/app"&lt;/code&gt; - this way the directory with the code is added to the docker as a volume.&lt;/li&gt;
&lt;li&gt;links: docker-compose can links containers with each other through virtual network, so for example: a web service can access postgres database by the hostname: &lt;code class="code-inline"&gt; postgres://postgres:&lt;a href="mailto:password@db.local"&gt;password@db.local&lt;/a&gt;:5432&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Always use the --build argument
&lt;/h3&gt;

&lt;p&gt;By default, if containers are already on the host, docker-compose up does not recreate them. To force this operation, use the &lt;code class="code-inline"&gt; --build&lt;/code&gt; argument. This is necessary when third-party dependencies or the Docker file itself change. We made it a rule to always run docker-compose up &lt;code class="code-inline"&gt; --build&lt;/code&gt;. Docker perfectly caches container layers and will not recreate them if nothing has changed. Continuous use of &lt;code class="code-inline"&gt; --build&lt;/code&gt; can slow down loading for a few seconds, but prevents unexpected problems associated with the application running outdated third-party dependencies.&lt;/p&gt;

&lt;p&gt;You can abstract the start of the project with a simple script&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;#!/bin/sh&lt;/span&gt;
&lt;span class="s"&gt;docker-compose up --build "$@"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;This technique allows you to change the options used when starting the tool, if necessary. Or you can just do &lt;code class="code-inline"&gt; ./bin/start.sh&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Partial launch
&lt;/h3&gt;

&lt;p&gt;In the docker-compose.yml example, some services depend on others:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;base&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nl"&gt;&amp;amp;app_base&lt;/span&gt;
    &lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;context&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;.&lt;/span&gt;
      &lt;span class="na"&gt;dockerfile&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;dev.Dockerfile&lt;/span&gt;
    &lt;span class="na"&gt;links&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;postgres&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;redis&lt;/span&gt;
    &lt;span class="na"&gt;env_file&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;.env.docker&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;.:/app&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;app-gems:/usr/local/bundle&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;node-modules:/app/node_modules&lt;/span&gt;
    &lt;span class="na"&gt;stdin_open&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="no"&gt;true&lt;/span&gt;
    &lt;span class="na"&gt;tty&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="no"&gt;true&lt;/span&gt;
  &lt;span class="na"&gt;app&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="s"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;*app_base&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;RACK_ENV=development&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;DATABASE_URL=postgres://login:pass@postgres:5432/develop_name&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;REDIS_URL=redis://redis:6379&lt;/span&gt;
  &lt;span class="na"&gt;tests&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="s"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;*app_base&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;RACK_ENV=test&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;NODE_ENV=production&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;DATABASE_URL=postgres://login:password@postgres:5432/test_name&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;REDIS_URL=redis://redis:6379&lt;/span&gt;
    &lt;span class="na"&gt;env_file&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;.env.docker&lt;/span&gt;
  &lt;span class="na"&gt;postgres&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;postgres:11.2-alpine"&lt;/span&gt;
    &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;POSTGRES_PASSWORD&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;strong-password&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;postgres-data:/var/lib/postgresql/data&lt;/span&gt;
  &lt;span class="na"&gt;redis&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;redis:4-alpine&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;In this fragment, the app and tests services require a database service (postgres in our case) and a data store service (redis in our case). When using docker-compose, you can specify the name of the service to run only it: &lt;code class="code-inline"&gt; docker-compose run app&lt;/code&gt;. This command will launch postgres container (with PostgreSQL service in it) and redis container (with Redis service), and after it the app service. In large projects, such features may come in handy. This functionality is useful when different developers need different parts of the system. For example, the frontend specialist who works on the landing page does not need the entire project, just the landing page itself is enough.&lt;/p&gt;

&lt;h3&gt;
  
  
  Unnecessary logs in&amp;gt;/dev/null
&lt;/h3&gt;

&lt;p&gt;Some programs generate too many logs. This information is in most cases useless and only distracting. In our demo repository, we turned off MongoDB logs by setting the log driver to none:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;mongo&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mongod&lt;/span&gt;
    &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mongo:3.2.0&lt;/span&gt;
    &lt;span class="na"&gt;ports&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;27100:27017"&lt;/span&gt;
    &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;/var/run/docker.sock:/var/run/docker.sock&lt;/span&gt;
    &lt;span class="na"&gt;logging&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="na"&gt;driver&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;none&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h3&gt;
  
  
  Multiple docker-compose files
&lt;/h3&gt;

&lt;p&gt;After running the docker-compose up command, it by default searches for the docker-compose.yml file in the current directory. In some cases, you may need multiple docker-compose.yml files. To include another configuration file, the &lt;code class="code-inline"&gt; --file&lt;/code&gt; argument can be used:&lt;/p&gt;

&lt;p&gt;&lt;code class="code-inline"&gt; docker-compose --file docker-compose-tests.yml up &lt;/code&gt;&lt;/p&gt;

&lt;p&gt;So why do we need multiple configuration files? First of all, to split a composite project into several subprojects. I am glad that services from different compose files can still be connected. For example, you can put infrastructure-related containers (databases, queues, etc.) in one docker-compose file, and application-related containers in another.&lt;/p&gt;

&lt;h3&gt;
  
  
  Testing
&lt;/h3&gt;

&lt;p&gt;We use docker-compose to run all our tests inside self-hosted drone.io. And we use various types of testing like unit, integrational, ui, linting. A separate set of tests has been developed for each service. For example, integration and UI tests golang workers. Initially, it was thought that it was better to run tests every time the main compose file was run, but it soon became clear that it was time consuming. In some cases, you need to be able to run specific tests. A separate compose files was created for this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;3"&lt;/span&gt;
&lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
 &lt;span class="na"&gt;postgres-data&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
   &lt;span class="na"&gt;driver&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;local&lt;/span&gt;
&lt;span class="na"&gt;services&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
 &lt;span class="na"&gt;workers_test&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
   &lt;span class="na"&gt;build&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
     &lt;span class="na"&gt;context&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;.&lt;/span&gt;
     &lt;span class="na"&gt;dockerfile&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;test.Dockerfile&lt;/span&gt;
   &lt;span class="na"&gt;links&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
     &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;postgres&lt;/span&gt;
   &lt;span class="na"&gt;depends_on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
     &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;postgres&lt;/span&gt;
   &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
     &lt;span class="na"&gt;DATABASE_URL&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;postgres://postgres:password@postgres:5432/test?sslmode=disable&lt;/span&gt;
     &lt;span class="na"&gt;MODE&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;test&lt;/span&gt;
   &lt;span class="na"&gt;command&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;./scripts/tests.sh&lt;/span&gt;
 &lt;span class="na"&gt;postgres&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
   &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="s"&gt;timescale/timescaledb-postgis:latest"&lt;/span&gt;
   &lt;span class="na"&gt;restart&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;always&lt;/span&gt;
   &lt;span class="na"&gt;environment&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
     &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;POSTGRES_PASSWORD=password&lt;/span&gt;
   &lt;span class="na"&gt;volumes&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
     &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;postgres-data:/var/lib/postgresql/data&lt;/span&gt;
     &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="s"&gt;./postgres/databases.sh:/docker-entrypoint-initdb.d/01-databases.sh&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Our docker-compose file does not depend on the entire project, in this case, when this file is launched, a test database is created, migration is carried out, test data is written to the database, and after that, the tests of our worker are launched.&lt;/p&gt;

&lt;p&gt;The entire list of commands is recorded in the script file tests.sh.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;#!/bin/bash&lt;/span&gt;
&lt;span class="s"&gt;docker-compose -f docker-compose-tests.yml up -d postgres&lt;/span&gt;
&lt;span class="s"&gt;docker-compose -f docker-compose-tests.yml run workers dbmate wait&lt;/span&gt;
&lt;span class="s"&gt;docker-compose -f docker-compose-tests.yml run workers dbmate drop&lt;/span&gt;
&lt;span class="s"&gt;docker-compose -f docker-compose-tests.yml run workers dbmate up&lt;/span&gt;
&lt;span class="s"&gt;docker-compose -f docker-compose-tests.yml run workers make build&lt;/span&gt;
&lt;span class="s"&gt;docker-compose -f docker-compose-tests.yml run workers ./bin/workers seed&lt;/span&gt;
&lt;span class="s"&gt;docker-compose -f docker-compose-tests.yml run workers go test ./... -v&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;h2&gt;
  
  
  The Main Docker's Delicacies
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Dockerfile
&lt;/h3&gt;

&lt;p&gt;It might seem that Dockerfile is a good old Chef-config, but in a new way. And here it is, from the server configuration in it there is only one line left this is the name of the base image of the operating system. The rest is part of the application architecture. And this should be taken as a declaration of the API and the dependencies of a service, not a server. This part is written by the programmer designing the application along the way in a natural way right in the development process. This approach provides not only amazing configuration flexibility, but also avoids the damaged phone between the developer and the administrator.&lt;/p&gt;

&lt;h3&gt;
  
  
  Puffed images
&lt;/h3&gt;

&lt;p&gt;The images in docker are not monolithic, but consist of copy-on-write layers. This allows you to reuse the base read only image files in all containers for free, launch the container without copying the image file system, make readonly containers, and also cache different stages of the image assembly. Very similar to git commits if you are familiar with its architecture.&lt;/p&gt;

&lt;h3&gt;
  
  
  Docker in Docker
&lt;/h3&gt;

&lt;p&gt;Ability to allow one container to manage other containers. Thus, it turns out that nothing will be installed on the host machine except Docker. There are two ways to reach this state. First way is to use Docker official image “docker” ( previously “Docker-in-Docker” or dind) with &lt;code class="code-inline"&gt; -privileged &lt;/code&gt; flag. Second one is more lightweight and deft - link docker binaries folder into container. It is done like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="s"&gt;docker run -v /var/run/docker.sock:/var/run/docker.sock \&lt;/span&gt;
       &lt;span class="s"&gt;-v $(which docker):/bin/docker \&lt;/span&gt;
       &lt;span class="s"&gt;-ti ubuntu&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;But this is not a real hierarchical docker-in-docker, but a flat but stable option.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;Docker is an open platform for developing, shipping, and running applications. Docker enables you to separate your applications from your infrastructure so you can deliver software quickly. With Docker, you can manage your infrastructure in the same ways you manage your applications. By taking advantage of Docker’s methodologies for shipping, testing, and deploying code quickly, you can significantly reduce the delay between writing code and running it in production.&lt;/p&gt;

&lt;p&gt;You just don’t have to waste time setting up everything locally on the developer's machine. We no longer have versions of nightmare and the like, and launching a new project takes not days, but only 15 minutes. The developer no longer needs an administrator, we have the same image everywhere, the same environment everywhere, and this is incredibly cool!&lt;/p&gt;

&lt;p&gt;In our next articles, we will encounter Docked more than once, so follow us on this blog and social networks.&lt;/p&gt;

</description>
      <category>docker</category>
      <category>devops</category>
      <category>webdev</category>
      <category>ruby</category>
    </item>
    <item>
      <title>GitHub VS GitLab VS BitBucket - Which is Better? </title>
      <dc:creator>Oleksandr Simonov</dc:creator>
      <pubDate>Tue, 18 Feb 2020 22:43:51 +0000</pubDate>
      <link>https://dev.to/amoniacou/github-vs-gitlab-vs-bitbucket-which-is-better-3b0o</link>
      <guid>https://dev.to/amoniacou/github-vs-gitlab-vs-bitbucket-which-is-better-3b0o</guid>
      <description>&lt;p&gt;Hello fellows!&lt;/p&gt;

&lt;p&gt;Yes, I know such a topic is really total war on the internet! But I want to drop a coin.&lt;/p&gt;

&lt;h2&gt;
  
  
  Preamble
&lt;/h2&gt;

&lt;p&gt;I want to provide a little bit more info on how I take such war. For the past few years, we use self-hosted Gitlab with our own Runners. Everything was great till the time when Gitlab starts to eat 16GB of RAM and still running really slow. Yeah, I know that they created a Memory team. But guys, In 2019 you still using Unicorn?! &lt;/p&gt;

&lt;p&gt;So we have moved to gitea and drone.io. They use my loved language Go and working really fast. We run them on the same host with only 1 GB of memory. After I decided to make our tests scaled and installed drone-autoscale... It was really mistaken... What I can say - User Experience was really degraded... The biggest issue was a drone - nice UI, but unusable back-end part. At least now! It was unusable only for our case. Keep in mind this thing.&lt;/p&gt;

&lt;p&gt;So, we have a hard decision - what to choose?! I decided to push there one of the hardest projects with a lot of tests and variables for them to test-drive BitBucket, Gitlab and GitHub. So let's start!&lt;/p&gt;

&lt;h2&gt;
  
  
  BitBucket
&lt;/h2&gt;

&lt;p&gt;I have decided to test it as the first alternative. We using JIRA a lot, so it was logical. The speed of git push was not so big - around 600Kbs, but LFS items were uploaded really fast. Grouping by Projects not really usable. All the time I tried to find the root of my "Company" account on the sidebar. But you can easily control the default page for your repo. Also, I think Atlassian needs to think about SubGroups - so I can make some groups of repos per project/client/etc. &lt;/p&gt;

&lt;p&gt;Another part which I want to test - Bitbucket Pipelines. Setup was really easiest, I just made only a few changes - all starts with our basic ruby test image(which I have created especially for this with Alpine in mind). &lt;br&gt;
I really like the idea that I can run x2 instances with grouping two steps into one. Another really cool feature is running services as separate docker containers with 1GB of memory. So we can use a lot of memory for tests in the result. Speed of VMs really fast. The tests which run around 30 minutes on my laptop was only 17 minutes. Really cool!&lt;/p&gt;

&lt;p&gt;But with team management all bad. If you need more control you need to pay more. Also, billing is separate from Atlassian, which looks strange.&lt;/p&gt;

&lt;p&gt;But in total such service is a good performer. Many addons on the marketplace. And 2500 minutes for pipelines.&lt;/p&gt;

&lt;h2&gt;
  
  
  GitLab
&lt;/h2&gt;

&lt;p&gt;After BitBucket I think that any case needs to gives a chance to GitLab. So I have pushed the same repo there again. Push speed was around 800Kbs but LFS upload was slower than on BitBucket. &lt;/p&gt;

&lt;p&gt;So UI is old GitLab. Nothing new as for me. Subgroups for clients, which really great feature. I just want to check the addon features and shared runners. As for me, their Integrations need to be extended a lot or have some interface for extending by the community. Or I have not found these things there... Anyway, let's go to the runners. They use Google Cloud, so you limited with 3.7Gb of RAM for tests. I think its really small for now. But again you can run your own runner. Shared runners are using Linux only. As I remember BB has some limitations. About tests run - 24 minutes. So 41% of the time more. If you have unlimited minutes - it could be not the issue, but by default, they give 2000 minutes. Not so big amount as for me.&lt;/p&gt;

&lt;h2&gt;
  
  
  GitHub
&lt;/h2&gt;

&lt;p&gt;So, this is a de facto(defunkt'o) standard. We using it a lot for opensource projects for years. I will not talk about UI - it's perfect! I will not talk about Integrations - they are a lot! So, let's talk about Github Actions. It's a new Github's product which provides a really powerful continuous integration/deployment/workflow for the project. &lt;/p&gt;

&lt;p&gt;But our main metric for today is a speed! Upload speed for LFS was not so big, and as I understand it uploading data to AWS S3 directly. @github you need to think about how to speedup AWS S3! For actions, we have a virtual instance on Azure(yeah baby! It's Micro$oft) with 7GB of RAM and two CPUs. Our tests are passes in 16 minutes, which is the same as BitBucket. But there are more features. You can run ARM and Mac OS X, which is really helpful. Before with Gitlab, we have used an old MacMini Server.&lt;/p&gt;

&lt;h2&gt;
  
  
  PRICE!
&lt;/h2&gt;

&lt;p&gt;About prices. Most expensive is a GitHub. After comes GitLab and the latest one is BitBucket. But there are one BIG thing - minutes!&lt;/p&gt;

&lt;p&gt;BitBucket provides 2500 and $10 each 1000. Gitlab provides 2000 and $8 each 1000. Github provides 10000(10 thousand!!!) minutes. I was focused on small team organization and as for me, it's really cool! &lt;/p&gt;

&lt;p&gt;If we have 10 team members and we need around 10000 minutes it will be next:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;BitBucket&lt;/em&gt; - 10 * 6 + 60 = &lt;em&gt;120 USD&lt;/em&gt;&lt;br&gt;
&lt;em&gt;Gitlab&lt;/em&gt;    - 10 * 4 + 64 = &lt;em&gt;104 USD&lt;/em&gt;&lt;br&gt;
&lt;em&gt;Github&lt;/em&gt;    - 10 * 9      = &lt;em&gt;90  USD&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;1&lt;/em&gt; Gitlab asking to pay annually, so as for me not so flexible.&lt;br&gt;
&lt;em&gt;2&lt;/em&gt; You can use cheaper variant for BitBucket and cost will be &lt;em&gt;90 USD&lt;/em&gt; too.&lt;/p&gt;

&lt;p&gt;So most cheaper &lt;strong&gt;*&lt;/strong&gt; variant for a small team is to use GitHub! And now with Actions its more valuable again!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;*&lt;/strong&gt; In my opinion for my small team.&lt;/p&gt;

</description>
      <category>github</category>
      <category>gitlab</category>
      <category>bitbucket</category>
      <category>git</category>
    </item>
    <item>
      <title>What is Docker? Why is it important and necessary for developers? Part I</title>
      <dc:creator>Oleksandr Simonov</dc:creator>
      <pubDate>Mon, 10 Feb 2020 11:31:40 +0000</pubDate>
      <link>https://dev.to/amoniacou/what-is-docker-why-is-it-important-and-necessary-for-developers-part-i-39e5</link>
      <guid>https://dev.to/amoniacou/what-is-docker-why-is-it-important-and-necessary-for-developers-part-i-39e5</guid>
      <description>&lt;h2&gt;
  
  
  What is Docker and What Containerization Means?
&lt;/h2&gt;

&lt;p&gt;As you know, ships are the leading way to distribute goods around the world. Previously, the cost of transportation was quite high, because each cargo had its own shape and type of material. Uploading a bag of fish or a car to a ship is a different task requiring different processes and tools. There were problems with loading methods that required a variety of cranes and tools. And to pack cargo expertly on the ship itself, given its fragility, this is not a trivial task.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--N5-TLi9Z--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://lh3.googleusercontent.com/q1T2hkaXMiXmPeaTMzZ5nOSqF4zHPHgs5VQqUIuqlg1gLbnk3Dk3Kw09Ij0oXLHdHAiDUaS4Nyga4mXt4GpmtWYBmXAy_o2aHWixVksRZ6wNLtL3pYTo-43xVOO4rtdaNu0Xh2Zf" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--N5-TLi9Z--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://lh3.googleusercontent.com/q1T2hkaXMiXmPeaTMzZ5nOSqF4zHPHgs5VQqUIuqlg1gLbnk3Dk3Kw09Ij0oXLHdHAiDUaS4Nyga4mXt4GpmtWYBmXAy_o2aHWixVksRZ6wNLtL3pYTo-43xVOO4rtdaNu0Xh2Zf" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;But at some point, everything changed. Containers leveled all types of cargo and standardized loading and unloading tools around the world, which in turn, led to a simplification of processes, acceleration, and, consequently, lower costs. This process of containerization or the creation of a container system, when intermodal freight transportation began to use intermodal containers, was launched from the 60s of the 20th century and entailed complete changes in the logistics system.&lt;/p&gt;

&lt;p&gt;The same thing happened in software development. Docker has become a universal software delivery tool, regardless of its structure, dependencies, or installation method. All that is needed for programs distributed through Docker is inside the image and does not intersect with the primary system and other containers. The importance of this fact cannot be overestimated. Now updating software versions does not involve either the system itself or other programs. Nothing can break anymore. All you need to do is download a new image of the program you want to update. In other words, Docker removed the dependency hell problem and made the infrastructure immutable.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--mEnCbTno--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://d26pm0riky5t4b.cloudfront.net/uploads/image/file/e2f645ad-7ff5-40c8-8bdc-e39d8c108f06.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--mEnCbTno--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://d26pm0riky5t4b.cloudfront.net/uploads/image/file/e2f645ad-7ff5-40c8-8bdc-e39d8c108f06.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Docker is a tool designed to make it easier to create, deploy, and run applications by using containers. Containers allow a developer to package up an application with all of the parts it needs, such as libraries and other dependencies, and ship it all out as one package. By doing so, thanks to the container, the developer can rest assured that the application will run on any other Linux machine regardless of any customized settings that machine might have that could differ from the machine used for writing and testing the code.&lt;/p&gt;

&lt;p&gt;In a way, Docker is a bit like a virtual machine. But unlike a virtual machine, rather than creating a whole virtual operating system, Docker allows applications to use the same Linux kernel as the system that they're running on and only requires applications be shipped with things not already running on the host computer. This gives a significant performance boost and reduces the size of the application.&lt;/p&gt;

&lt;p&gt;And importantly, Docker is open source. This means that anyone can contribute to Docker and extend it to meet their own needs if they need additional features that aren't available out of the box.&lt;/p&gt;

&lt;p&gt;Docker is a tool that is designed to benefit both developers and system administrators, making it a part of many DevOps (developers + operations) toolchains. For developers, it means that they can focus on writing code without worrying about the system that it will ultimately be running on. It also allows them to get a head start by using one of thousands of programs already designed to run in a Docker container as a part of their application. For operations staff, Docker gives flexibility and potentially reduces the number of systems needed because of its small footprint and lower overhead.&lt;/p&gt;

&lt;p&gt;Things you should know about Docker:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Docker is not LXC.&lt;/li&gt;
&lt;li&gt;Docker is not a Virtual Machine Solution.&lt;/li&gt;
&lt;li&gt;Docker is not a configuration management system and is not a replacement for chef, puppet, Ansible etc.&lt;/li&gt;
&lt;li&gt;Docker is not a platform as a service technology.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Docker Components:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Docker is composed of the following four components&lt;/li&gt;
&lt;li&gt;Docker Client and Daemon&lt;/li&gt;
&lt;li&gt;Images&lt;/li&gt;
&lt;li&gt;Docker registries&lt;/li&gt;
&lt;li&gt;Containers&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Docker architecture
&lt;/h3&gt;

&lt;p&gt;Images are the basic building blocks of Docker. Containers are built from images. Images can be configured with applications and used as a template for creating containers. It is organized in a layered fashion. Every change in an image is added as a layer on top of it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Docker registry
&lt;/h3&gt;

&lt;p&gt;Is a repository for Docker images. Using Docker registry, you can build and share images with your team. A registry can be public or private. Docker Inc provides a hosted registry service called Docker Hub. It allows you to upload and download images from a central location. If your repository is public, all your images can be accessed by other Docker hub users. You can also create a private registry in Docker Hub, Google Cloud Registry, Amazon Registry etc. Docker hub acts like git, where you can build your images locally on your laptop, commit it and then can be pushed to the Docker hub.&lt;/p&gt;

&lt;h3&gt;
  
  
  Container
&lt;/h3&gt;

&lt;p&gt;Is the execution environment for Docker. Containers are created from images. It is a writable layer of the image. You can package your applications in a container, commit it and make it a golden image to build more containers from it. Two or more containers can be linked together to form tiered application architecture. Containers can be started, stopped, committed and terminated. If you terminate a container without committing it, all the changes made to the container will be lost.&lt;/p&gt;

&lt;h2&gt;
  
  
  From LXC to Docker
&lt;/h2&gt;

&lt;p&gt;The original Linux container technology is called Linux Containers, or LXC. LXC is an OS-level virtualization method designed to run multiple isolated Linux systems on a single host.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Mp2uOH4c--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://d26pm0riky5t4b.cloudfront.net/uploads/image/file/dbd550e3-298c-412a-885f-e7ae5dbab097.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Mp2uOH4c--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://d26pm0riky5t4b.cloudfront.net/uploads/image/file/dbd550e3-298c-412a-885f-e7ae5dbab097.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Containers separate applications from operating systems. This means that users have a clean, minimal Linux OS, and you can run all processes in one or more isolated containers. Since the operating system is separate from the containers, you can move the container to any Linux server that supports the container's operating environment. Docker, which began as a project to build LXC containers for a single application, seriously changed LXC and made containers more portable and flexible.&lt;/p&gt;

&lt;p&gt;The main differences between Docker and LXC:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. A single process vs many processes
&lt;/h3&gt;

&lt;p&gt;Docker restricts containers to make them work as a single process. If your application environment consists of X concurrent processes, Docker will launch X containers, each with its own process. Unlike Docker, LXC containers can run many processes. To run a simple multi-level web application in Docker, you will need a PHP container, a Nginx container web server, a MySQL container for the database process, and several data containers to store database tables and other application information.&lt;/p&gt;

&lt;p&gt;Single-process containers have many benefits, including simpler and smaller updates. You do not need to kill the database process when you want to update only the webserver. Also, single-process containers have an efficient architecture for building microservice-based applications. Single-process containers also have limitations. For example, you cannot run agents, registration scripts, or automatically running SSH processes inside a container. It is also not easy to slightly upgrade a single-process container at the application level. You will have to launch a newly updated container.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Structurelessness vs structural
&lt;/h3&gt;

&lt;p&gt;Docker containers are designed to be more structureless than LXC.&lt;/p&gt;

&lt;p&gt;First, Docker does not support external storage. Docker circumvents this by allowing you to mount host storage as a Docker volume from your containers. Since quantities are attached, they are not considered part of the container environment.&lt;/p&gt;

&lt;p&gt;Secondly, Docker containers consist of layers in reading mode. This means that as soon as the image of the container is created, it does not change. During program execution, if the process in the container changes its internal state, a difference is created between the internal state and the image from which the container was created.&lt;/p&gt;

&lt;p&gt;If you run the docker commit command, the difference between the two versions becomes part of the new image, but not the original, but the new one from which you can create new containers. If you delete the container, the version difference will disappear.&lt;/p&gt;

&lt;p&gt;A structureless container is an unusual entity. You can update the container, but a series of updates will create a series of new container images, so it is so easy to roll back in the system.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Portability
&lt;/h3&gt;

&lt;p&gt;Perhaps this is the most critical advantage of Docker over the LXC. Docker separates network resources, storage, and OS details more than LXC. With Docker, the application is really independent of the settings of these low-level resources. When you move a Docker container from one Docker host to another Docker machine, Docker ensures that the environment for the application remains unchanged.&lt;/p&gt;

&lt;p&gt;A direct advantage of this approach is that Docker helps programmers create local development environments that look like a production server. When the programmer finishes writing and begins to test the code, he can wrap it in a container, publish it directly on the server or in a private cloud, and he will immediately work since this is the same environment.&lt;/p&gt;

&lt;p&gt;With LXC, a programmer can run something on his machine, but find that the code does not work correctly when deployed to a server. The server environment will be different, and the programmer will have to spend a lot of time to fix this difference and fix the problem. With Docker, there are no such problems.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Architecture created for developers
&lt;/h3&gt;

&lt;p&gt;Separating applications from the underlying hardware is the fundamental concept of virtualization. Containers go even further and separate applications from the OS. Thanks to this feature, programmers get flexibility and scalability during development.&lt;/p&gt;

&lt;h2&gt;
  
  
  What else Docker replaced?
&lt;/h2&gt;

&lt;p&gt;It is worth listing the technologies that have become redundant when working with infrastructure after the appearance of Docker. Of course, for other applications, these technologies are still indispensable, here's how, for example, to replace SSH or Git, used for other purposes?&lt;/p&gt;

&lt;h3&gt;
  
  
  Chef / Puppet / Ansible
&lt;/h3&gt;

&lt;p&gt;A concise and fast Dockerfile replaces the stateful server configuration management system. Since Docker can assemble the container image in seconds, and launch the container in milliseconds, you no longer need to pile up scripts that keep the heavy and expensive server up to date. It is enough to start a new container and pay off the old one. If you used Chef to deploy stateless servers before Docker arrived quickly, then you probably already love Docker.&lt;/p&gt;

&lt;h3&gt;
  
  
  Upstart / SystemD / Supervisor / launchd / God.rb / SysVinit
&lt;/h3&gt;

&lt;p&gt;Archaic service launch systems based on static configurations just go away. In their place comes docker daemon, which is an init-like process that can monitor running services, restart failed ones, store exit codes, logs, and most importantly, download any containers with any services on any machine, no matter what role the machine has.&lt;/p&gt;

&lt;h3&gt;
  
  
  Ubuntu_18.04.iso / AMI-W7FIS1T / apt-get update
&lt;/h3&gt;

&lt;p&gt;Like vagrant, docker finally allows us to forget about downloading the long-obsolete installation DVD-images, remember the control panels of different cloud platforms, and lament that they never have the latest ubuntu. And most importantly, you can launch your own custom image with everything you need in a couple of minutes, collecting it on your local machine and downloading it to the free Docker Hub cloud. And no more apt-get update after installation - your images will always be ready to work immediately after assembly.&lt;/p&gt;

&lt;h3&gt;
  
  
  RUBY_ENV, database.dev.yml, testing vs. staging vs. backup
&lt;/h3&gt;

&lt;p&gt;Since docker allows you to run containers with all the dependencies and a bit-by-bit environment that matches what you configured, you can pick up an exact copy of the production directly on your computer in a couple of seconds. All operating systems, all database and caching servers, the application itself, and the library versions it uses, all this will be accurately reproduced on the development machine or on the tester machine. If you are always dreamed of having a backup production server ready for battle in the event of a fall in the main one - docker-compose up, you have two battle servers that are copies of each other with accuracy to bits. Starting with docker version 1.10, container identifiers are their own SHA256 signature guaranteeing identity.&lt;/p&gt;

&lt;p&gt;And also note that such a powerful tool as Docker is fully consistent with the methodology of &lt;a href="https://12factor.net" rel="nofollow"&gt;12factor&lt;/a&gt;, which allows to create software as a service with a number of advantages.&lt;/p&gt;

&lt;h3&gt;
  
  
  SSH (sic!), VPN, Capistrano, Jenkins-slave
&lt;/h3&gt;

&lt;p&gt;To start the container, you do not need to get root on the server, fool around with the keys, and configure the deployment system. With Docker, deployment looks like building and configuring a physical server at home, further comprehensively testing it, and then magically moving it to an arbitrary number of data centers with one command. To do this, just run a Docker run on a laptop, and the Docker itself will connect to the server via TLS and start everything. It’s also easier to get inside the container: docker exec -it %containername% bash, and you have a debugging console in your hands. You can even drive rsync through the docker tunnel like this: rsync -e 'docker exec -i' --blocking-io -rv CONTAINER_NAME: / data., The main thing to remember is to add --blocking-io.&lt;/p&gt;

&lt;h3&gt;
  
  
  No Vendor lock
&lt;/h3&gt;

&lt;p&gt;That's all, he is no more. Do you want to move the entire application in a couple of minutes to another continent, and want to spread your application around the globe. Containers don't care where to spin, and they are connected by a virtual network, they see and hear each other from everywhere, including a development machine in case of live debugging.&lt;/p&gt;

&lt;p&gt;This is partial information about such a powerful tool as Docker, and in our next article, you can get acquainted with all the goodies of Docker, find out what Dokku is and how we use these tools in our practice.&lt;/p&gt;

</description>
      <category>docker</category>
      <category>opensource</category>
      <category>ruby</category>
      <category>rails</category>
    </item>
    <item>
      <title>Correct and  Efficient Vuex Using. Part II</title>
      <dc:creator>Oleksandr Simonov</dc:creator>
      <pubDate>Tue, 04 Feb 2020 11:36:18 +0000</pubDate>
      <link>https://dev.to/amoniacou/correct-and-efficient-vuex-using-part-ii-1877</link>
      <guid>https://dev.to/amoniacou/correct-and-efficient-vuex-using-part-ii-1877</guid>
      <description>&lt;p&gt;In the first part of the article, we looked at such components of Vuex as storage, state, getters, mutations, and actions. You can see all in details here &lt;a href="https://amoniac.dev.ua.amoniac.eu/blog/post/correct-and-efficient-vuex-using-part-i"&gt;https://amoniac.dev.ua.amoniac.eu/blog/post/correct-and-efficient-vuex-using-part-i&lt;/a&gt;&lt;br&gt;&lt;br&gt;
And we continue our review of the Vuex library and talk about modules, application structure, plugins, etc.&lt;/p&gt;

&lt;h3&gt;
  
  
  Modules
&lt;/h3&gt;

&lt;p&gt;Due to the use of a single state tree, all global application data is placed in one large object. As the application grows, the storage can swell significantly. To help with this, Vuex lets you split storage into modules. Each module can contain its own state, mutations, actions, getters, and even built-in submodules, this structure is fractal.&lt;/p&gt;

&lt;p&gt;The first argument that mutations and getters receive is the local state of the module. Similarly, &lt;code class="code-inline"&gt;context.state&lt;/code&gt; in actions also indicates the local state of the module, and the root is available in &lt;code class="code-inline"&gt;context.rootState&lt;/code&gt;. By default, actions, mutations, and getters inside modules are registered in the global namespace. This allows several modules to respond to the same type of mutations/actions.&lt;/p&gt;

&lt;p&gt;If you want to make the modules more self-sufficient and ready for reuse, you can create it with your namespace by specifying the &lt;code class="code-inline"&gt;namespaced: true&lt;/code&gt; option. When a module is registered, all its getters, actions, and mutations will be automatically associated with this namespace, based on the path along which the module is registered.&lt;/p&gt;

&lt;p&gt;Getters and actions with their namespace will receive their local &lt;code class="code-inline"&gt;getters&lt;/code&gt;, &lt;code class="code-inline"&gt;dispatch&lt;/code&gt;, and &lt;code class="code-inline"&gt;commit&lt;/code&gt;. In other words, you can use the contents of a module without writing prefixes in the same module. Switching between namespaces does not affect the code inside the module.&lt;/p&gt;

&lt;p&gt;If you want to use the global state and getters, &lt;code class="code-inline"&gt;rootState&lt;/code&gt; and &lt;code class="code-inline"&gt;rootGetters&lt;/code&gt; are passed in the 3rd, and 4th arguments to the getter function, as well as the properties in the &lt;code class="code-inline"&gt;context&lt;/code&gt; object, passed to the action function. To trigger actions or commit mutations in the global namespace, add &lt;code class="code-inline"&gt;{root: true}&lt;/code&gt; with the 3rd argument to &lt;code class="code-inline"&gt;dispatch&lt;/code&gt; and &lt;code class="code-inline"&gt;commit&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If you want to register global actions in namespaced modules, you can mark it with &lt;code class="code-inline"&gt;root: true&lt;/code&gt; and place the action definition to function &lt;code class="code-inline"&gt;handler&lt;/code&gt;. Furthermore, you can create namespaced helpers by using &lt;code class="code-inline"&gt;createNamespacedHelpers&lt;/code&gt;. It returns an object having new component binding helpers that are bound with the given namespace value.&lt;/p&gt;

&lt;p&gt;You may be concerned about the unpredictability of the namespace for your modules when you create a plug-in with its modules and the ability for users to add them to the Vuex repository. Your modules will also be placed in the namespace if plugin users add your modules to the module with their namespace. To adapt to this situation, you may need to get the namespace value through the plugin settings.&lt;/p&gt;

&lt;p&gt;You can register the module even after the storage has been created using the &lt;code class="code-inline"&gt;store.registerModule&lt;/code&gt; method. Module status will be available as &lt;code class="code-inline"&gt;store.state.myModule&lt;/code&gt; and &lt;code class="code-inline"&gt;store.state.nested.myModule&lt;/code&gt;. Dynamic module registration allows other Vue plugins also to use Vuex to manage their state by adding a module to the application data store. For example, the &lt;code class="code-inline"&gt;vuex-router-sync&lt;/code&gt; library integrates vue-router into vuex, reflecting a change in the current application path in a dynamically attached module.&lt;/p&gt;

&lt;p&gt;You can delete a dynamically registered module using the &lt;code class="code-inline"&gt;store.unregisterModule (moduleName)&lt;/code&gt;. Please note that the static, defined at the time the repository was created, modules cannot be removed using this method.&lt;/p&gt;

&lt;p&gt;Sometimes we may need to create several instances of the module, for example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;creation of several storages that are used by one module, for example, to avoid stateful singletones in the SSR when using the &lt;code class="code-inline"&gt;runInNewContext&lt;/code&gt; option if &lt;code class="code-inline"&gt;false&lt;/code&gt; or &lt;code class="code-inline"&gt;'once'&lt;/code&gt;;&lt;/li&gt;
&lt;li&gt;registering the module several times in one repository.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If we use an object to determine the state of a module, then this state object will be used by reference and cause pollution of the state of the storage/module during its mutations. This is actually the same problem with &lt;code class="code-inline"&gt;data&lt;/code&gt; inside Vue components. So the solution will be the same.&lt;/p&gt;

&lt;h3&gt;
  
  
  Application structure
&lt;/h3&gt;

&lt;p&gt;In reality, Vuex does not impose any significant restrictions on the code structure used. However, it requires compliance with several high-level principles:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The global state of the application must be contained in global storage;&lt;/li&gt;
&lt;li&gt;The only mechanism for changing this state are mutations that are synchronous transactions;&lt;/li&gt;
&lt;li&gt;Asynchronous operations are encapsulated in actions or their combinations.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As long as you follow these rules, you can use any project structure. If your storage file gets too large, just start putting actions, mutations, and getters into separate files. For any non-trivial application, you will most likely need to use modules. Here is an example of a possible project structure. For reference, you can use the shopping cart example.&lt;/p&gt;

&lt;h3&gt;
  
  
  Plugins
&lt;/h3&gt;

&lt;p&gt;Vuex repositories accept the &lt;code class="code-inline"&gt;plugins&lt;/code&gt; option, which provides hooks for each mutation. The Vuex plugin is just a function that receives storage as a single parameter. Plugins are not allowed to directly change the state of the application as well as components. They can only cause changes indirectly using mutations.&lt;/p&gt;

&lt;p&gt;By causing mutations, the plugin can synchronize the data source with the data store in the application. For example, to synchronize storage with a web socket, the example is intentionally simplified, in a real situation, &lt;code class="code-inline"&gt;createWebSocketPlugin&lt;/code&gt; would have additional options. Sometimes a plugin may need to “take a nugget” of the application state or compare the “before” and “after” mutations. To do this, use deep copying of the state object.&lt;/p&gt;

&lt;p&gt;Impression plugins should only be used during development. When using webpack or Browserify, we can give this moment at their mercy. The plugin will be used by default. In the production environment, you will need DefinePlugin for webpack, or envify for Browserify to change the value of &lt;code class="code-inline"&gt;process.env.NODE_ENV! == 'production'&lt;/code&gt; to &lt;code class="code-inline"&gt;false&lt;/code&gt; in the final assembly.&lt;/p&gt;

&lt;p&gt;Vuex comes with a logging plugin that can be used for debugging. You can also enable the logging plugin directly using a separate &lt;code class="code-inline"&gt;&amp;lt;script&amp;gt;&lt;/code&gt; tag, which places the &lt;code class="code-inline"&gt;createVuexLogger&lt;/code&gt; function in the global namespace. Please note that this plugin makes state casts, so you should use it only at the development stage.&lt;/p&gt;

&lt;h3&gt;
  
  
  Strict mode
&lt;/h3&gt;

&lt;p&gt;To enable strict mode, specify &lt;code class="code-inline"&gt;strict: true&lt;/code&gt; when creating the Vuex repository. In strict mode, any attempt to make changes to the Vuex state, except mutations, will throw an error. This ensures that all state mutations are explicitly tracked through debugging tools.&lt;/p&gt;

&lt;p&gt;Do not use strict mode in production! Strict mode triggers deep tracking of the application state tree in synchronous mode to detect inappropriate mutations, and this can be costly for performance when a large number of mutations occur. Be sure to turn this mode off in production to avoid performance degradation.&lt;/p&gt;

&lt;h3&gt;
  
  
  Work with forms
&lt;/h3&gt;

&lt;p&gt;When using strict mode, Vuex may not seem obvious how to use the &lt;code class="code-inline"&gt;v-model&lt;/code&gt; with the Vuex state part. Suppose &lt;code class="code-inline"&gt;obj&lt;/code&gt; is a computed property that returns an object reference from the repository. In this case, the &lt;code class="code-inline"&gt;v-model&lt;/code&gt; will try to change the &lt;code class="code-inline"&gt;obj.message&lt;/code&gt; value during user actions directly. In strict mode, such changes will trigger an error because they occur outside of Vuex mutation handlers. To work with Vuex in this situation, you should bind the value to &lt;code class="code-inline"&gt;&amp;lt;input&amp;gt;&lt;/code&gt; and track its changes by the &lt;code class="code-inline"&gt;input&lt;/code&gt; or &lt;code class="code-inline"&gt;change&lt;/code&gt; event.&lt;/p&gt;

&lt;h3&gt;
  
  
  Testing
&lt;/h3&gt;

&lt;p&gt;The main subject of unit testing in Vuex are mutations and actions. Mutations are fairly easy to test, as they are just simple functions whose behavior depends entirely on the parameters passed. One trick is that if you use ES2015 modules and put your mutations in the &lt;code class="code-inline"&gt;store.js&lt;/code&gt; file, then in addition to the default export, you must export the mutations using named exports.&lt;/p&gt;

&lt;p&gt;Testing activities are a bit more complicated, as they can access external APIs. When testing actions, you usually have to fake external objects - for example, calls to the API can be moved to a separate service, and as part of the tests, this service can be replaced with a fake one. To simplify the simulation of dependencies, you can use webpack and inject-loader to build test files.&lt;/p&gt;

&lt;p&gt;Getters doing complex calculations would also be helpful to test. As with mutations, everything is simple. If you correctly follow the rules for writing mutations and actions, the resulting tests should not depend on the browser API. Therefore, they can be assembled by webpack and run in Node. On the other hand, you can use &lt;code class="code-inline"&gt;mocha-loader&lt;/code&gt; or Karma + &lt;code class="code-inline"&gt;karma-webpack&lt;/code&gt;, and run tests in real browsers.&lt;/p&gt;

&lt;h3&gt;
  
  
  Hot reboot
&lt;/h3&gt;

&lt;p&gt;Vuex supports hot-swapping of mutations, modules, actions, and getters at development time using the webpack Hot Module Replacement API. Similar functionality in Browserify is achievable using the browserify-hmr plugin. For mutations and modules, you need to use the &lt;code class="code-inline"&gt;store.hotUpdate()&lt;/code&gt; API method.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Vuex Actions are the Ideal API Interface
&lt;/h2&gt;

&lt;p&gt;If you are working on a project in which the back end and front end are developing at the same time, or you are working in a UI/Frontend team that can even create a user interface before the back end exists, you are probably familiar with the problem when you need to drown out back end parts or data as the front end develops.&lt;/p&gt;

&lt;p&gt;The general way that this manifests is with purely static templates or content, with placeholders and text right in your interface templates. A step away from this is some form of fixtures, data that is statically loaded by the interface and injected into place. Both of them often face the same set of problems. When the back end is finally available, there is a bunch of refactoring to get the data in place.&lt;/p&gt;

&lt;p&gt;Even if the data structure from the back end matches your fixtures, you still have to cross to find each integration point. And if the structure is different, you should not only do this, but you must figure out how you can either change the external interface or create an abstraction layer that transforms the data.&lt;/p&gt;

&lt;h2&gt;
  
  
  Strengths and Benefits of Vuex Storage
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--FcJkHibc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://lh4.googleusercontent.com/sSMk7A7EJyVeSLFChgEPlAHTsPgc2SkwhblOp7gTOd2NWEgvs0r5oVZ5aYViLrX4X-zTz1a6WOqRzmykEG_qGoz3ofrUKdZONi7r_NQinbqmdDNcTzYo_jJwmbTSbzF9pEHMDuWS" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--FcJkHibc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://lh4.googleusercontent.com/sSMk7A7EJyVeSLFChgEPlAHTsPgc2SkwhblOp7gTOd2NWEgvs0r5oVZ5aYViLrX4X-zTz1a6WOqRzmykEG_qGoz3ofrUKdZONi7r_NQinbqmdDNcTzYo_jJwmbTSbzF9pEHMDuWS" alt="vue js front end web app development"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Compared to a simple global object, the Vuex repository has many significant advantages and benefits:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Vuex Storage - Reactive. As soon as components get the state from it, they will reactively update their views every time the state changes.&lt;/li&gt;
&lt;li&gt;Components cannot directly change the state of the repository. The only way to change the state of the repository is to commit the mutations explicitly. This ensures that every state change leaves a tracked record, which makes debugging and testing the application easier.&lt;/li&gt;
&lt;li&gt;Components cannot directly change the state of the repository. The only way to change the state of the repository is to commit the mutations explicitly. This ensures that every state change leaves a tracked record, which makes debugging and testing the application easier.&lt;/li&gt;
&lt;li&gt;You can easily debug your application by integrating Vuex with the Vue DevTools extension.&lt;/li&gt;
&lt;li&gt;Vuex repository gives you a general picture of the state of how everything is connected and affects the application.&lt;/li&gt;
&lt;li&gt;It is easier to maintain and synchronize the state between several components, even if the hierarchy of elements is changing.&lt;/li&gt;
&lt;li&gt;Vuex enables the direct interaction of components with each other.&lt;/li&gt;
&lt;li&gt;If the component is destroyed, the state in the Vuex repository will remain untouched.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;When working with Vuex, we need to remember some crucial points. Vuex creates a repository that consists of states, getters, mutations, and actions. To update or change state, must make a mutation. To perform an asynchronous task, you need an action. Actions, if successful, commit a mutation that changes state, thereby updating the presentation. The application state is stored as one large JSON object. Getters are used to access values in the store. Mutations update condition. It should be remembered that mutations are synchronous. All asynchronous operations must be performed within actions. Actions change state, initiating mutations. Make it a rule to initiate mutations solely through action. Modules can be used to organize storage in several small files.&lt;/p&gt;

&lt;p&gt;Vuex makes working with Vue much more comfortable and more fun. If you are new, there may be situations where it is difficult to decide whether to use Vuex in certain areas of application. Follow instincts and reach high speed pretty quickly.&lt;/p&gt;

</description>
      <category>vue</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Docker-based development</title>
      <dc:creator>Oleksandr Simonov</dc:creator>
      <pubDate>Thu, 30 Jan 2020 21:03:05 +0000</pubDate>
      <link>https://dev.to/amoniacou/docker-based-development-14i9</link>
      <guid>https://dev.to/amoniacou/docker-based-development-14i9</guid>
      <description>&lt;p&gt;Hello guys,&lt;/p&gt;

&lt;p&gt;I want to make an announcement that I plan to start a series of articles about how to use Docker in local development processes.&lt;/p&gt;

&lt;p&gt;First of all, I plan to explain why we are at Amoniac have chosen Docker as our main technology for local and production environments. I will show the cases when Docker helps a lot to start new development projects and optimize current processes.&lt;/p&gt;

&lt;p&gt;In the middle, I will show how to organize the process on your laptop with Docker Compose and spend 10 minutes on new projects' environment setup.&lt;/p&gt;

&lt;p&gt;At the latest posts, you will see how to migrate from Docker-Compose to the Kubernetes based deployments and how to optimize your Docker containers to have smaller sizes and better scalability.  &lt;/p&gt;

</description>
      <category>docker</category>
      <category>ruby</category>
      <category>rails</category>
      <category>kubernetes</category>
    </item>
    <item>
      <title>Correct and  Efficient Vuex Using. Part I</title>
      <dc:creator>Oleksandr Simonov</dc:creator>
      <pubDate>Thu, 30 Jan 2020 12:05:57 +0000</pubDate>
      <link>https://dev.to/amoniacou/correct-and-efficient-vuex-using-part-i-2p09</link>
      <guid>https://dev.to/amoniacou/correct-and-efficient-vuex-using-part-i-2p09</guid>
      <description>&lt;p&gt;With this article, we begin a series of publications about Vue.js technology and try to make out the application development and all its components from different practical sides. In this part, we will tell you what the Vuex library is and analyze in detail such components as a store, state, getters, mutations, and actions. &lt;/p&gt;

&lt;p&gt;Also, in the second part, we will consider modules, application structure, plugins, strict mode, work with forms, testing and strengths/benefits of Vuex Storage.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Vuex, and Where it Used?
&lt;/h2&gt;

&lt;p&gt;VueX is a state management library inspired by Flux, Redux, and Elm architecture, but specially designed and tuned to integrate well with Vue.js and take advantage of Vue’s Reactivity. &lt;/p&gt;

&lt;p&gt;What is a state management pattern? Let's start with a simple Vue application that implements a counter. This stand-alone application consists of the following parts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;State that controls the application;&lt;/li&gt;
&lt;li&gt;The view is a state display specified declaratively;&lt;/li&gt;
&lt;li&gt;Actions are possible ways to change the state of the app in response to users interaction with the view. &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Sometimes several components may appear that are based on the same state:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;multiple views may depend on the same part of the application state;&lt;/li&gt;
&lt;li&gt;actions from different views can affect the equal parts of the application state.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Solving the first problem, you will have to transfer the same data with input parameters to deeply embedded components. This is often complicated and tedious, but for neighboring elements this will not work at all. Solving the second problem, you can come to such solutions as referring to parent/child instances or try changing and synchronizing multiple state copies through actions. Both approaches are fragile and quickly lead to the emergence of code that cannot be supported.&lt;/p&gt;

&lt;p&gt;So why not take out the overall general state of the application from the components and manage it in a global singleton? At the same time, our component tree becomes one big "view" and any component can access the application state or trigger actions to change the state, regardless of where they are in the tree!&lt;/p&gt;

&lt;p&gt;By clearly defining and separating the concepts that arise in state management, and by requiring certain rules that maintain independence between views and states, we better structure the code and make it easier to maintain.&lt;/p&gt;

&lt;p&gt;This is the core idea of ​​Vuex, inspired by Flux, Redux, and Elm Architecture. Unlike other patterns, Vuex is implemented as a library designed explicitly for Vue.js to use its reactivity system for efficient updates.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Main Components and Capabilities of Vuex
&lt;/h2&gt;

&lt;h3&gt;
  
  
  &lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fd26pm0riky5t4b.cloudfront.net%2Fuploads%2Fimage%2Ffile%2F05053135-9ee7-49a3-b6ee-297f6157321a.png" alt="vue js development company"&gt;
&lt;/h3&gt;

&lt;h3&gt;
  
  
  Store
&lt;/h3&gt;

&lt;p&gt;At the center of any Vuex application is a store. The store is a container that stores the state of your application. Two points distinguish Vuex store from a simple global object:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The Vuex store is reactive. When Vue components rely on their state, they will be reactively and efficiently updated if the state of the store changes.&lt;/li&gt;
&lt;li&gt;You cannot directly change the state of the store. The only way to make changes is to cause a mutation explicitly. This ensures that any change in the state leaves a mark and allows the use of tools to better understand the progress of the application.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;After installing Vuex, a repository is created. It's quite simple, and you need to specify the initial state object and some actions and mutations.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="s"&gt;const store = new Vuex.Store({&lt;/span&gt;
  &lt;span class="s"&gt;state&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;counter&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;0 // initial store state&lt;/span&gt;
  &lt;span class="pi"&gt;}&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;actions&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;increment(&lt;/span&gt;&lt;span class="pi"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;commit&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;dispatch&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;getters&lt;/span&gt; &lt;span class="pi"&gt;}&lt;/span&gt;&lt;span class="nv"&gt;)&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt;
       &lt;span class="nv"&gt;commit('INCREMENT')&lt;/span&gt;
    &lt;span class="pi"&gt;},&lt;/span&gt;
    &lt;span class="nv"&gt;decrement(&lt;/span&gt;&lt;span class="pi"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;commit&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;dispatch&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;getters&lt;/span&gt; &lt;span class="pi"&gt;}&lt;/span&gt;&lt;span class="nv"&gt;)&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt;
       &lt;span class="nv"&gt;commit('DECREMENT')&lt;/span&gt;
    &lt;span class="pi"&gt;}&lt;/span&gt;
  &lt;span class="pi"&gt;}&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;mutations&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;INCREMENT(state)&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt;
      &lt;span class="nv"&gt;state.counter++&lt;/span&gt;
    &lt;span class="pi"&gt;},&lt;/span&gt;
    &lt;span class="nv"&gt;DECREMENT(state)&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt;
      &lt;span class="nv"&gt;state.counter--&lt;/span&gt;
    &lt;span class="pi"&gt;}&lt;/span&gt;
  &lt;span class="pi"&gt;}&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;getters&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;counter(state)&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt;
      &lt;span class="nv"&gt;return state.counter&lt;/span&gt;
    &lt;span class="pi"&gt;}&lt;/span&gt;
  &lt;span class="pi"&gt;}&lt;/span&gt;
&lt;span class="err"&gt;}&lt;/span&gt;&lt;span class="s"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The reason we are committing a mutation instead of changing &lt;code&gt; store.state.count&lt;/code&gt; directly, is because we want to explicitly track it. This simple convention makes your intention more explicit, so that you can reason about state changes in your app better when reading the code. In addition, this gives us the opportunity to implement tools that can log every mutation, take state snapshots, or even perform time travel debugging.&lt;/p&gt;

&lt;h3&gt;
  
  
  State. Single state tree
&lt;/h3&gt;

&lt;p&gt;Vuex uses a single state tree when one object contains the entire global state of the application and serves as the only one source. It also means that the app will have only one such storage. A single state tree makes it easy to find the part you need or take snapshots of the current state of the application for debugging purposes.&lt;/p&gt;

&lt;p&gt;The data you store in Vuex follows the same rules as the &lt;code&gt;data&lt;/code&gt; in a Vue instance, ie the state object must be plain. So how do we display state inside the store in our Vue components? Since Vuex stores are reactive, the simplest way to "retrieve" state from it is simply returning some store state from within a computed property. Whenever &lt;code&gt;store.state.count&lt;/code&gt; changes, it will cause the computed property to re-evaluate, and trigger associated DOM updates.&lt;/p&gt;

&lt;p&gt;This pattern causes the component to rely on the global store singleton. When using a module system, it requires importing the store in every component that uses store state, and also requires mocking when testing the component. Vuex provides a mechanism to "inject" the store into all child components from the root component with the &lt;code&gt;$store&lt;/code&gt; option (enabled by &lt;code&gt;Vue.use(Vuex)&lt;/code&gt;)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="s"&gt;export default {&lt;/span&gt;
  &lt;span class="s"&gt;methods&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;incrementCounter()&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt;
      &lt;span class="nv"&gt;this.$store.dispatch('increment')&lt;/span&gt;
    &lt;span class="pi"&gt;}&lt;/span&gt;
  &lt;span class="pi"&gt;}&lt;/span&gt;
&lt;span class="err"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When a component needs to make use of multiple store state properties or getters, declaring all these computed properties can get repetitive and verbose. To deal with this we can make use of the &lt;code&gt;mapState&lt;/code&gt; helper which generates computed getter functions for us, saving us some keystrokes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="s"&gt;import { mapState } from 'vuex';&lt;/span&gt;

&lt;span class="s"&gt;export default {&lt;/span&gt;
  &lt;span class="s"&gt;computed&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;...mapState(&lt;/span&gt;&lt;span class="pi"&gt;{&lt;/span&gt;
       &lt;span class="nv"&gt;counter&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;state =&amp;gt; state.counter&lt;/span&gt;
    &lt;span class="pi"&gt;}&lt;/span&gt;&lt;span class="nv"&gt;)&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt;

    &lt;span class="nv"&gt;counterSquared()&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt;
      &lt;span class="nv"&gt;return Math.pow(this.counter&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;2)&lt;/span&gt;
    &lt;span class="pi"&gt;}&lt;/span&gt;
  &lt;span class="pi"&gt;}&lt;/span&gt;
&lt;span class="err"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can also pass a string array to &lt;code&gt; mapState&lt;/code&gt; when the name of a mapped computed property is the same as a state sub tree name.&lt;/p&gt;

&lt;p&gt;Note that &lt;code&gt; mapState&lt;/code&gt; returns an object. How do we use it in combination with other local computed properties? Normally, we'd have to use a utility to merge multiple objects into one so that we can pass the final object to &lt;code&gt; computed&lt;/code&gt;. However with the object spread operator (which is a stage-4 ECMAScript proposal), we can greatly simplify the syntax as shown above.&lt;/p&gt;

&lt;p&gt;Using Vuex doesn't mean you should put all the state in Vuex. Although putting more state into Vuex makes your state mutations more explicit and debuggable, sometimes it could also make the code more verbose and indirect. If a piece of state strictly belongs to a single component, it could be just fine leaving it as local state. You should weigh the trade-offs and make decisions that fit the development needs of your app.&lt;/p&gt;

&lt;h3&gt;
  
  
  Getters
&lt;/h3&gt;

&lt;p&gt;Sometimes we may need to compute derived state based on store state, for example filtering through a list of items and counting them.&lt;/p&gt;

&lt;p&gt;If more than one component needs to make use of this, we have to either duplicate the function, or extract it into a shared helper and import it in multiple places - both are less than ideal.&lt;/p&gt;

&lt;p&gt;Vuex allows us to define "getters" in the store. You can think of them as computed properties for stores. Like computed properties, a getter's result is cached based on its dependencies, and will only re-evaluate when some of its dependencies have changed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="s"&gt;// In store&lt;/span&gt;
&lt;span class="na"&gt;getters&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt;
  &lt;span class="nv"&gt;counter(state)&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;return state.counter&lt;/span&gt;
  &lt;span class="pi"&gt;},&lt;/span&gt;
  &lt;span class="nv"&gt;counterSquared(state)&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;return Math.pow(state.counter&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;2)&lt;/span&gt;
  &lt;span class="pi"&gt;}&lt;/span&gt;
&lt;span class="pi"&gt;}&lt;/span&gt;

&lt;span class="s"&gt;// In component&lt;/span&gt;
&lt;span class="s"&gt;import { mapGetters } from 'vuex';&lt;/span&gt;

&lt;span class="s"&gt;export default {&lt;/span&gt;
  &lt;span class="s"&gt;computed&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;...mapgetters(&lt;/span&gt;&lt;span class="pi"&gt;[&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;counter'&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;counterSquared'&lt;/span&gt; &lt;span class="pi"&gt;]&lt;/span&gt;&lt;span class="nv"&gt;)&lt;/span&gt;
  &lt;span class="pi"&gt;}&lt;/span&gt;
&lt;span class="err"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can also pass arguments to getters by returning a function. This is particularly useful when you want to query an array in the store. Note that getters accessed via methods will run each time you call them, and the result is not cached.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt; mapGetters&lt;/code&gt; helper simply maps store getters to local computed properties.&lt;/p&gt;

&lt;h3&gt;
  
  
  Mutations
&lt;/h3&gt;

&lt;p&gt;The only way to actually change state in a Vuex store is by committing a mutation. Vuex mutations are very similar to events: each mutation has a string type and a handler. The handler function is where we perform actual state modifications, and it will receive the state as the first argument.&lt;/p&gt;

&lt;p&gt;You cannot directly call a mutation handler. Think of it more like event registration: "When a mutation with type &lt;code&gt; increment&lt;/code&gt; is triggered, call this handler." To invoke a mutation handler, you need to call &lt;code&gt; store.commit&lt;/code&gt; with its type.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="s"&gt;export default {&lt;/span&gt;
  &lt;span class="s"&gt;methods&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;incrementCounter()&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt;
      &lt;span class="nv"&gt;this.$store.commit('INCREMENT')&lt;/span&gt;
    &lt;span class="pi"&gt;}&lt;/span&gt;
  &lt;span class="pi"&gt;}&lt;/span&gt;
&lt;span class="err"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can pass an additional argument to &lt;code&gt;store.commit&lt;/code&gt;, which is called the payload for the mutation. In most cases, the payload should be an object so that it can contain multiple fields, and the recorded mutation will also be more descriptive. An alternative way to commit a mutation is by directly using an object that has a &lt;code&gt;type&lt;/code&gt; property. When using object-style commit, the entire object will be passed as the payload to mutation handlers, so the handler remains the same.&lt;/p&gt;

&lt;p&gt;Since a Vuex store's state is made reactive by Vue, when we mutate the state, Vue components observing the state will update automatically. This also means Vuex mutations are subject to the same reactivity caveats when working with plain Vue:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Prefer initializing your store's initial state with all desired fields upfront.&lt;/li&gt;
&lt;li&gt;When adding new properties to an Object, you should either - use &lt;code&gt;Vue.set(obj, 'newProp', 123)&lt;/code&gt;, or replace that Object with a fresh one. For example, using the object spread syntax.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;However, using constants to indicate the types of mutations is completely optional, although this may be useful in large projects.&lt;/p&gt;

&lt;p&gt;One important rule to remember is that mutation handler functions must be synchronous. Imagine we are debugging the app and looking at the devtool's mutation logs. For every mutation logged, the devtool will need to capture a "before" and "after" snapshots of the state. However, the asynchronous callback inside the example mutation above makes that impossible: the callback is not called yet when the mutation is committed, and there's no way for the devtool to know when the callback will actually be called - any state mutation performed in the callback is essentially untrackable!&lt;/p&gt;

&lt;p&gt;You can commit mutations in components with &lt;code&gt;this.$store.commit('xxx')&lt;/code&gt;, or use the &lt;code&gt;mapMutations&lt;/code&gt; helper which maps component methods to &lt;code&gt;store.commit&lt;/code&gt; calls (requires root &lt;code&gt;$store&lt;/code&gt; injection)&lt;/p&gt;

&lt;p&gt;Asynchronicity combined with state mutation can make your program very hard to reason about. For example, when you call two methods both with async callbacks that mutate the state, how do you know when they are called and which callback was called first? This is exactly why to separate the two concepts. In Vuex, mutations are synchronous transactions. To handle asynchronous operations, should descry Actions.&lt;/p&gt;

&lt;h3&gt;
  
  
  Actions
&lt;/h3&gt;

&lt;p&gt;Actions are similar to mutations with a few differences:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Instead of mutating the state, actions commit mutations.&lt;/li&gt;
&lt;li&gt;Actions can contain arbitrary asynchronous operations.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;actions&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt;
  &lt;span class="nv"&gt;signIn(&lt;/span&gt;&lt;span class="pi"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;commit&lt;/span&gt; &lt;span class="pi"&gt;},&lt;/span&gt; &lt;span class="nv"&gt;payload)&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;// Show spinner when user submit form&lt;/span&gt;
    &lt;span class="nv"&gt;commit('LOGIN_IN_PROGRESS'&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;true);&lt;/span&gt;

    &lt;span class="nv"&gt;// axios - Promise based HTTP client for browser and node.js&lt;/span&gt;
    &lt;span class="nv"&gt;axios&lt;/span&gt;
      &lt;span class="nv"&gt;.post('/api/v1/sign_in'&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;email&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;payload.email&lt;/span&gt;
        &lt;span class="nv"&gt;password&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="nv"&gt;payload.password&lt;/span&gt;
      &lt;span class="pi"&gt;}&lt;/span&gt;&lt;span class="nv"&gt;)&lt;/span&gt;
      &lt;span class="nv"&gt;.then((response) =&amp;gt;&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt;
         &lt;span class="nv"&gt;const&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt; &lt;span class="nv"&gt;user&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;token&lt;/span&gt; &lt;span class="pi"&gt;}&lt;/span&gt; &lt;span class="nv"&gt;= response.data;&lt;/span&gt;
         &lt;span class="nv"&gt;commit('SET_AUTH_TOKEN'&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;token);&lt;/span&gt;
         &lt;span class="nv"&gt;commit('SET_USER'&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;user);&lt;/span&gt;
         &lt;span class="nv"&gt;commit('LOGIN_IN_PROGRESS'&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;false);&lt;/span&gt;
      &lt;span class="pi"&gt;}&lt;/span&gt;&lt;span class="nv"&gt;)&lt;/span&gt;
      &lt;span class="nv"&gt;.catch((error) =&amp;gt;&lt;/span&gt; &lt;span class="pi"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;commit('SET_SIGN_IN_ERROR'&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;error.response.data.reason);&lt;/span&gt;
        &lt;span class="nv"&gt;commit('LOGIN_IN_PROGRESS'&lt;/span&gt;&lt;span class="pi"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;false);&lt;/span&gt;
      &lt;span class="pi"&gt;}&lt;/span&gt;&lt;span class="nv"&gt;)&lt;/span&gt;
  &lt;span class="pi"&gt;}&lt;/span&gt;
&lt;span class="pi"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;em&gt;Asynchronous action on the example of authorization&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Action handlers receive a context object which exposes the same set of methods/properties on the store instance, so you can call &lt;code&gt;context.commit&lt;/code&gt; to commit a mutation, or access the state and getters via &lt;code&gt;context.state&lt;/code&gt; and &lt;code&gt;context.getters&lt;/code&gt;. We can even call other actions with &lt;code&gt;context.dispatch&lt;/code&gt;. We will see why this context object is not the store instance itself when we introduce Modules later.&lt;/p&gt;

&lt;p&gt;In practice, we often use ES2015 argument destructuring to simplify the code a bit especially when we need to call &lt;code&gt;commit&lt;/code&gt; multiple times. Actions are triggered with the &lt;code&gt;store.dispatch&lt;/code&gt; method. This may look silly at first sight if we want to increment the count, why don't we just call &lt;code&gt;store.commit('increment')&lt;/code&gt; directly? Remember that mutations have to be synchronous? Actions don't. We can perform asynchronous operations inside an action. Actions support the same payload format and object-style dispatch.&lt;/p&gt;

&lt;p&gt;A more practical example of real-world actions would be an action to checkout a shopping cart, which involves calling an async API and committing multiple mutations. Performing a flow of asynchronous operations, and recording the side effects (state mutations) of the action by committing them.&lt;/p&gt;

&lt;p&gt;You can dispatch actions in components with &lt;code&gt;this.$store.dispatch('xxx')&lt;/code&gt;, or use the &lt;code&gt;mapActions&lt;/code&gt; helper which maps component methods to &lt;code&gt;store.dispatch&lt;/code&gt; calls (requires root &lt;code&gt;$store&lt;/code&gt; injection). Actions are often asynchronous, so how do we know when an action is done? And more importantly, how can we compose multiple actions together to handle more complex async flows?&lt;/p&gt;

&lt;p&gt;The first thing to know is that &lt;code&gt;store.dispatch&lt;/code&gt; can handle Promise returned by the triggered action handler and it also returns Promise. It's possible for a &lt;code&gt;store.dispatch&lt;/code&gt; to trigger multiple action handlers in different modules. In such a case the returned value will be a Promise that resolves when all triggered handlers have been resolved.&lt;br&gt;&lt;br&gt;
&lt;br&gt;&lt;br&gt;
It is only a small part of what we are going to tell in our next articles about Vue.js and all of its additional tools and benefits. Next, we continue our review of the Vuex library and components.&lt;/p&gt;

&lt;p&gt;Also, in our blog section, you can read more about Vue.js tool here &lt;a href="https://amoniac.eu/blog/post/why-we-fell-in-love-with-vue-js" rel="noopener noreferrer"&gt;https://amoniac.eu/blog/post/why-we-fell-in-love-with-vue-js&lt;/a&gt;&lt;/p&gt;

</description>
      <category>vue</category>
      <category>javascript</category>
      <category>webdev</category>
    </item>
    <item>
      <title>Most Popular JS Frameworks Overview</title>
      <dc:creator>Oleksandr Simonov</dc:creator>
      <pubDate>Mon, 27 Jan 2020 11:46:44 +0000</pubDate>
      <link>https://dev.to/amoniacou/most-popular-js-frameworks-overview-43p0</link>
      <guid>https://dev.to/amoniacou/most-popular-js-frameworks-overview-43p0</guid>
      <description>&lt;h2&gt;
  
  
  JavaScript's Rich and Functional World
&lt;/h2&gt;

&lt;p&gt;The JavaScript world is a rich environment with dozens of tools, libraries, and frameworks. But, with lots of options comes a lot of confusion. It really is a double-edged sword.&lt;/p&gt;

&lt;p&gt;While you get lots of space for creativity and experimentation, sometimes you are unsure about what library or framework to choose.&lt;/p&gt;

&lt;p&gt;The front-end framework you choose can make or break your project in the long run.&lt;/p&gt;

&lt;p&gt;In this article, we will look at some of the most popular JavaScript frameworks, and how they fare against each other. We’ll examine five different perspectives of these frameworks, which eases the process of deciding on your next JavaScript framework.&lt;/p&gt;

&lt;p&gt;Whether you are choosing from one of these popular JavaScript frameworks, or something more esoteric, you should take each of these aspects into consideration. So, without ado, we will go ahead and take a look at the most popular JavaScript frameworks for 2019!&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ydtPrb2o--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://d26pm0riky5t4b.cloudfront.net/uploads/image/file/4de13711-8ee8-4f0e-a258-da4b01157ef7.png" alt="Vue.js development"&gt; VUE
&lt;/h2&gt;

&lt;p&gt;Vue.js is an open-source JavaScript environment designed to simplify and streamline user interface design. The framework, also the ideal blend of Angular and React, has proven itself to be the perfect choice for developing a lightweight, two-way data binding application to the angle structure and server rendering of the React JS framework. Vue.js was nominated as the most popular JavaScript interface on GitHub with 118 thousand stars last year.&lt;/p&gt;

&lt;p&gt;Vue.js may seem like an ideal JavaScript structure for software development, but it also has its pros and cons.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pros
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;A quick set of popularity: in just a few years since its inception, many enterprises have added Vue.js to their technical stack.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Quick Setup: Vue has built-in data binding and an MVC model (model, view, controller), which makes configuration much easier compared to Angular.js and React.js.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Easier integration: the platform supports easier integration with HTML elements.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Small learning curve: compared to the Angular JS Framework, Vue is much easier to learn, understand, and use.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Cons
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Few resources: the structure is still too young to find useful solutions on the Internet and self-study. &lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Small community engagement: Vue.js is new to the market and has less community support than Angular and React technologies.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You can also read more about the framework Vue.js in our article here &lt;a href="https://amoniac.eu/blog/post/why-we-fell-in-love-with-vue-js"&gt;https://amoniac.eu/blog/post/why-we-fell-in-love-with-vue-js&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--uaLThh-k--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://d26pm0riky5t4b.cloudfront.net/uploads/image/file/1de06ba5-9e81-4e11-b87b-ee0d3ae5c3f0.png" alt="React.js development"&gt; REACT
&lt;/h2&gt;

&lt;p&gt;Supported by Facebook, Instagram and other well-known organizations, React is one of the best JavaScript frameworks for the past five years. Also, React.js or React JS, more than 38% of developers worldwide use the front end infrastructure. Netflix, Flipboard, PayPal and the BBC are the first organizations to use React. Let's take a look at all the pros and cons of React.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pros
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Lots of documentation and online resources: thanks to Facebook support, there are many opportunities to use a ton of documentation and online resources for learning and using the Javascript framework for React.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Fast, flexible, efficient and lightweight technology: The JS system is widely recommended for its efficiency, small block size, flexibility and a quicker approach to work due to its simple component model and server-side rendering functionality.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A transition between versions: migration between versions is usually very simple, Facebook provides “codemods” to automate a huge part of the process. 4. Feels great when working with ES6 / 7 ReactJS, can take on any load.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The structure has a component architecture that revolutionized web application development and influenced other technologies.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;DOM allows you to combine HTML, XHTML or XML documents follow certain criteria, most often into a tree, so React is excellent for web browsers when analyzing various elements of web applications.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Cons
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Assembly tools are needed: this JavaScript infrastructure may not work correctly without adequate build tools or may display incompatibility with other libraries and codes due to high DOM.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Big learning curve: Unlike Vue, React takes more time to learn concepts and implement. React JS requires a massive amount of knowledge in how to integrate the user interface into the MVC structure.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Lack of streamlined documentation: the super-fast exchange of solutions in ReactJS leaves no room for streamlining the documentation, the documents are placed a bit chaotic, since many developers individually enter them into the database without any systematic approach.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--TjtEO4dK--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://d26pm0riky5t4b.cloudfront.net/uploads/image/file/c7d6c908-7fb2-4125-a348-883ee3aad490.png" alt="Angular.js development"&gt; ANGULAR
&lt;/h2&gt;

&lt;p&gt;Angular.js is a full-featured front-end JavaScript environment supported by Google and other famous corporations. This structure is known for its potential capabilities like fast code generation, two-way data binding, and testing parts of an application. Although hundreds of companies and developers enjoy using the Angular front end Javascript framework, there are pros and cons of this technology.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pros
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Two-way data binding.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Mobile approach to web development.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Support PWA.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Stable and long-term support for Google.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Universal MVVM module, allows you to separately operate in one section of the application, using the same data set.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Interdependence of functions, because of their connectedness with components and modules.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;RXJS, lightning fast compilation, less than 2.9 seconds, modified start HttpClient.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Cons
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;The problem with the drainage of the battery: applications created using the framework system Javascript, known for excessively discharging the battery of the device.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Poor optimization: Angular.js based applications require more optimization to solve low-performance problems.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Big learning curve: Angular shows a high learning scale, you need more time to master this structure.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Integration errors: may occur during the transition from the old version to the new one.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Difficult programming language: although Angular uses TypeScript 2.4.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--_VOwPLlE--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://d26pm0riky5t4b.cloudfront.net/uploads/image/file/258ca4e4-ea70-42b8-b97e-03408c23c04c.png" alt="Ember.js development"&gt; EMBER
&lt;/h2&gt;

&lt;p&gt;Ember.js has been used in the design of many complex websites, like Kickstarter, Heroku, and LinkedIn. Ember.js is ideal for developing complex web applications, and the string system of templates with which it is delivered contributes to a significant reduction in load time. The front end JavaScript Framework also focuses on scalability so that developers can quickly work with both mobile and web applications.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pros
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Ember Data Library: this is one of the best libraries for API level requests and data retrieval in the local app store.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Ember CLI: an idea stolen from Rails, but this feature makes Ember.js very convenient.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Many extensions (ember addons) that can be easily added to the application using a single terminal command (ember install). The centralized repository of all add-ons along with the search is also enjoyable.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Built-in testing tools: standard ember-cli comes with QUnit.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Cons
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Ember Data: suitable for standard REST API requests only.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Many ember addons: ports existing in the jQuery library.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Relationship with jQuery: it would be much more convenient if Ember would use axios or a standard sample to create ajax requests.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;A huge learning curve: first you need to learn Javascript, then Ember, this can take a lot of time, especially from scratch.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;No server-side rendering.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;No Redux. Enough said.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--7zIDC2kc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://d26pm0riky5t4b.cloudfront.net/uploads/image/file/ec4295cc-5ff1-4745-99be-5b518ccf6313.png" alt="Backbone.js development"&gt; BACKBONE
&lt;/h2&gt;

&lt;p&gt;Backbone is an MV* framework. Backbone partly implements an MVC architecture, as Backbone’s View part carries out the responsibilities of the Controller.&lt;/p&gt;

&lt;p&gt;Backbone has a strong dependency on the jQuery and the Underscore library that gives us many helper functions for convenient cross-browser work with JavaScript. Unlike many other full-fledged JavaScript frameworks, Backbone attempts to reduce complexity to avoid performance issues. More specifically, you won't get performance problems because of two-way data binding or built-in loops like in AngularJS.&lt;/p&gt;

&lt;h3&gt;
  
  
  Pros
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;View: the view part of Backbone apps, Backbone views implement component logic, how model data is rendered to the browser, similar to a Controller in MVC, you can bind views and models so that the view will change whenever model data is altered. Backbone view can use third-party templating engines like Mustache and Underscore.js.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Collection: which are just arrays of similar models, if your app has different types of users, each user type will be represented by a separate model, and all user models can be iterated over in Backbone collections.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Events: a class that let's implement and use events, both custom, and built-in, and bind various events to Backbone models, collections, routes, and views.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Router: an interface that maps URLs to different components of an app, Backbone's router depends on the history object to work with browser history.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;REST: a simple API that we can use to synchronize the front end and back end more specifically, to request persistent model data and collections from the server.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Cons
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Backbone parts are not sufficient to develop an advanced client-side app: another way, Backbone is almost always used with additional JavaScript libraries.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Backbone’s view layer can’t render itself to the DOM: This is where Marionette and Thorax come into, they let make Backbone views to the DOM.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Work with Backbone: it’s almost inevitable that also need to learn Marionette, Chaplin, or Thorax.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;Our team's favorite is Vue.js, one of those selected here. But the real answer depends entirely on the project. Do you need the most popular JavaScript framework? Probably no. How about the biggest and the biggest or the smallest and the lightest? These factors may or may not matter.&lt;/p&gt;

&lt;p&gt;Each developer has his own opinion, but we all need to understand one thing that cannot find the best structure among the JavaScript frameworks. Choosing the most appropriate structure depends entirely on the needs of a project. Thus, it is to consider the pros and cons of all the above frameworks and decide which one to start a project with.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>vue</category>
      <category>react</category>
    </item>
    <item>
      <title>Why we love and choose Ruby instead of Node.js?</title>
      <dc:creator>Oleksandr Simonov</dc:creator>
      <pubDate>Thu, 23 Jan 2020 12:30:27 +0000</pubDate>
      <link>https://dev.to/amoniacou/why-we-love-and-choose-ruby-instead-of-node-js-4pdh</link>
      <guid>https://dev.to/amoniacou/why-we-love-and-choose-ruby-instead-of-node-js-4pdh</guid>
      <description>&lt;h2&gt;
  
  
  Making pretty code with Ruby
&lt;/h2&gt;

&lt;p&gt;Ruby on Rails is an open-source platform from which programmers become happy, code is pretty, and development is reliable and fast.&lt;/p&gt;

&lt;p&gt;RoR is a framework written in the Ruby programming language, implements the architectural pattern Model-View-Controller for web applications, and also provides integration with a web server and database server. It opens software and licensed under conditions of the MIT license.&lt;/p&gt;

&lt;p&gt;Created by David Heinemeier Hansson based on his 37signals work on the Basecamp project management tool that released in 2004.&lt;/p&gt;

&lt;p&gt;RoR fully-fledged website framework that includes everything to complete a website project including an ability to manage logic, routing, and applications, all from the box. These handy tools also include database integration and controllers which makes it easier to facilitate web development on an end to end basis.&lt;/p&gt;



&lt;h2&gt;
  
  
  Key benefits of Ruby and Ruby on Rails
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--HEuC-5mw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://d26pm0riky5t4b.cloudfront.net/uploads/image/file/db48d6f5-d50b-43f5-bea4-88f20651b10e.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--HEuC-5mw--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://d26pm0riky5t4b.cloudfront.net/uploads/image/file/db48d6f5-d50b-43f5-bea4-88f20651b10e.png" alt="ruby web development"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Development speed
&lt;/h3&gt;

&lt;p&gt;The main advantage of the Ruby language is the speed of development that increased by 30-40 percent with any other programming language or framework. The growth rate of development determined by an extensive set of ready-to-work standard RoR tools, a massive set of already made solutions in the community, the Ruby language and the simplicity of programming on it.&lt;/p&gt;

&lt;p&gt;One of the most critical parts of the RoR culture is sociality. Solved the problem and helped solve others. I implemented my module, so, share it with the community. Thus, thousands of ready-made solutions of various tasks stored in open access. Authentication, authorization, commenting, payment systems, mailing lists and much more implemented by others, implemented and tested and recommended by numerous communities.&lt;/p&gt;

&lt;h3&gt;
  
  
  Culture and Standards
&lt;/h3&gt;

&lt;p&gt;Ruby on Rails is a framework that does not allow you amateur performance. In RoR, you can “invent your own bike” and program in any direction without relying on standards; but this is not required. Criteria for placing files, standards for writing code, general rules for programming in the community actively structure any project. Due to this, it becomes readable. Entry into the project of newcomers is high-speed. Experience shows that any newcomer to the project on the first day of work makes its first useful edits. Due to this, it not a big problem if the project development by one team of programmers and project support or revision by an entirely different team. The project on RoR is a priori clear to any developer.&lt;/p&gt;

&lt;h3&gt;
  
  
  Testing Tools
&lt;/h3&gt;

&lt;p&gt;When developing any major project, a reasonable question arises. How and who will test the project? There is not always the means and desire to create entire departments of testing, especially to automate this process. Unlike other frameworks, RoR has excellent automated testing tools. There are no standard testing tools in other programming languages and frameworks. There is third-party development that allows you to organize automatic testing of a project in other languages, but they are not out of the box, and programmers do not think about using them. In a project on RoR, ideally, the project code is not written until tests written for this code. RoR ideology implies the initial use of BDD (Behavior Driven Development) or TDD (Test Driven Development) methods.&lt;/p&gt;

&lt;p&gt;More info about testing can be found in our previous article here &lt;a href="https://amoniac.eu/blog/post/tests-as-must-have-for-complex-projects"&gt;https://amoniac.eu/blog/post/tests-as-must-have-for-complex-projects&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Caching tools
&lt;/h3&gt;

&lt;p&gt;Project caching is one of the most critical stages in the development of a large Internet project. Different languages have different data caching options. These options and tools are screwed, attached, fastened, attached at the side. Until now, there is no consensus in the community what is to use, how to cache the data, what tools to use.&lt;/p&gt;

&lt;p&gt;Ruby on Rails in its basic configuration has regular data caching tools. At the start, tools provided that allow you to implement data caching on the project. You can cache whole pages or blocks of code. You can cache query results and ActiveRecord — models. You can cache as with Memcached or Redis and other means. To implement caching on a Ruby on Rails project, in 95 percent of cases you will not need anything other than ready-made and standard solutions.&lt;/p&gt;

&lt;h3&gt;
  
  
  Localization tools
&lt;/h3&gt;

&lt;p&gt;There is a situation when someone has done a project, and then suddenly realizes that to continue the development of the project, a version in some other language is necessary. Developers working with other programming languages at the same time begin to talk about the fact that it not foreseen in advance, that it is long and complicated. Let's say, let's open a parallel project, which will be a complete copy of this, and translate it.&lt;/p&gt;

&lt;p&gt;The basic configuration of Ruby on Rails has project localization tools. You may consider the need to support various languages ​​on the site both initially and in the future. RoR can distribute templates for different languages, contains configuration files with a translation of terms and many other regular tools for implementing the project localization.&lt;/p&gt;

&lt;h3&gt;
  
  
  Nice routing
&lt;/h3&gt;

&lt;p&gt;In many projects, we can see when the address of a particular page is huge and unclear. In Ruby, there is a regular ability to flexibly configure your routing, the type of addresses, the names of the main sections. It is possible to quickly change addresses in one place without having to change this address throughout the project. In the community of RoR – developers, REST ideology is actively used. The addresses of pages in projects on Ruby on Rails are always clear, beautiful, correctly understood by search engines and simple.&lt;/p&gt;

&lt;h3&gt;
  
  
  Validations tools
&lt;/h3&gt;

&lt;p&gt;In Ruby on Rails, tools are correctly implemented to validate incoming data. Your users fill out forms, and you need to check the correctness of the entered email address, the presence of a password or the required minimum length of the login — regular means of Rails will help you with this.&lt;/p&gt;

&lt;h3&gt;
  
  
  Migrations and work with the database
&lt;/h3&gt;

&lt;p&gt;The common problem of many projects written in other languages is the inability to control the structure of the database using clear tools and tools. Changes to the structure are made manually and directly into the database. Because of this, many incomprehensible fields and tables appear in the project, about which no one remembers anything. In Ruby on Rails, there are regular database tools - “migrations.” The database structure is stored in the application code and configured from the project. Your structure will always be in the repository, any change to the structure will be documented and tied to a specific commit in the repository.&lt;/p&gt;

&lt;h3&gt;
  
  
  Security
&lt;/h3&gt;

&lt;p&gt;Ruby on Rails is by default heavily sharpened for project security. When using the RoR tools, SQL injections and XSS attacks excluded. All input parameters escaped by default. Displayed variables in templates also avoided unless you specify the opposite option. The developer has no chance to make security mistakes, although there are exceptions.&lt;/p&gt;

&lt;h3&gt;
  
  
  Deploy
&lt;/h3&gt;

&lt;p&gt;There are many convenient and enjoyable tools in the Ruby on Rails environment. Including tools used in the deployment process. Using Capistrano, rolling out a new version of an application on a combat server or several servers will require one command in the console that is cap deploy.&lt;/p&gt;

&lt;h3&gt;
  
  
  Version control systems
&lt;/h3&gt;

&lt;p&gt;When developing any Ruby on Rails project, the use of known version control systems implied. Using git, as we say, “voluntarily — forcibly”, since many systems of automatic project deployment on combat servers do not work without them. RoR programmers initially, when exploring the platform, are forced to learn git, since numerous code examples in the documentation imply the use of these version control systems. Because of this, it is easier for inexperienced beginners to start learning other languages and not to touch Rails until they reach a certain level of understanding of web development as such and its principles.&lt;/p&gt;

&lt;h3&gt;
  
  
  Task managers
&lt;/h3&gt;

&lt;p&gt;Ruby on Rails was initially designed to implement the Basecamp project management system. Also, on RoR an accessible and free Redmine project management system was created. When working on Rails projects voluntarily-compulsorily use of such systems. All of them integrated with version control systems, which allows more flexible management of project development processes.&lt;/p&gt;



&lt;h2&gt;
  
  
  Where Ruby on Rails wins vs. Node.js?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--0VZJy5p6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://d26pm0riky5t4b.cloudfront.net/uploads/image/file/a4ec54f4-3c48-458f-929a-3f479525facf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--0VZJy5p6--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://d26pm0riky5t4b.cloudfront.net/uploads/image/file/a4ec54f4-3c48-458f-929a-3f479525facf.png" alt="ruby on rails web development"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Web development best practice
&lt;/h3&gt;

&lt;p&gt;Rails comes with a view to creating the best practice for web development. The creator intended to make it easy to develop sites accordingly a set framework which puts convention before configuration. As such, Ruby On Rails ships with every necessary library and module. And they all implement the model, view and controller paradigm. The intention is to make web development as predictable and smooth a process as possible.&lt;/p&gt;

&lt;h3&gt;
  
  
  Infrastructure that is expansive
&lt;/h3&gt;

&lt;p&gt;RoR’s built for quick site development, so, it includes an integrated web server, plus, it has a database with generators and scripts; these are powerful and make it easy to together a Rails application. You can use all the necessary bits automatically, and pieces a functioning Rails site requires in place. It’s great for rapid development.&lt;/p&gt;

&lt;h3&gt;
  
  
  Database interoperability
&lt;/h3&gt;

&lt;p&gt;You can easily migrate Rails databases. Because the model that supports the Rails database, ActiveRecord, can easily translate the differences amongst the numerous SQL interactions. Instead of writing out SQL code, users of Rails can use the Rails language to describe changes to database tables.&lt;/p&gt;

&lt;p&gt;So, in effect, the schema created is agnostic of the database in use. Which means you can run Rails application in many database environments.&lt;br&gt; &lt;br&gt;
&lt;br&gt; &lt;/p&gt;

&lt;h2&gt;
  
  
  And where does it lose?
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Flexibility can be an issue
&lt;/h3&gt;

&lt;p&gt;Flexibility can be an issue, for every advantage, there is a matching drawback. It is also about RoR. Due to Rails creator’s development vision, you may feel restricted with RoR if your particular application is too unique. The Rails platform imposes a lot of authority on the developmental process, so there can come where adjusting RoR to fit your requirements takes up a massive amount of your time. Whereas merely starting from scratch would have been quicker.&lt;/p&gt;

&lt;h3&gt;
  
  
  Performance is not always optimized
&lt;/h3&gt;

&lt;p&gt;Again, a positive thing that can also be a negative. Because of the large number of modules in the box, RoR can seemingly bog down when running in the real world. The overall framework is heavier than alternatives, including Node.js. So it’s not so efficient at managing a barrage of requests is typical of many website applications. You can add more server instances, but these use up your memory.&lt;/p&gt;

&lt;h3&gt;
  
  
  Debugging can be tedious
&lt;/h3&gt;

&lt;p&gt;Because of Ruby on Rails’ complexity and multiple layers, it can be difficult to troubleshoot a Ruby application. Finding an error in the mix can be very time-consuming. So if something goes wrong, compounded by your application’s custom requirements, you can find Ruby on Rails a very tedious platform to develop on.&lt;br&gt; &lt;br&gt;
&lt;br&gt; &lt;/p&gt;

&lt;h2&gt;
  
  
  What is Node.js?
&lt;/h2&gt;

&lt;p&gt;Node.js is a server platform built on JavaScript Engine from Google Chrome (V8 Engine). Node.js developed by Ryan Dalem in 2009, the latest version of the framework is v0.10.36.&lt;/p&gt;

&lt;p&gt;Node.js is an open-source, cross-platform JavaScript run-time environment that executes JavaScript code outside of a browser. JavaScript is used primarily for client-side scripting, in which scripts written in JavaScript are embedded in a web page's HTML and run client-side by a JavaScript engine in the user's web browser.&lt;/p&gt;

&lt;p&gt;In short, Node.js is a run time environment that allows you to execute server-side, which used to be client-side, code.&lt;/p&gt;

&lt;p&gt;So, Node.js, built on version 8 of the Chrome JavaScript engine, lets you execute JavaScript on a server. It was initially intended to make it easier to create push capability for real-time websites. But Node.js is an expansive platform. And it includes native modules that can manage everything from files to computing resources and security.&lt;/p&gt;

&lt;p&gt;The Node.js distributed development project, governed by the Node.js Foundation, facilitated by the Linux Foundation's Collaborative Projects program.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Y15gGgNX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://d26pm0riky5t4b.cloudfront.net/uploads/image/file/1bc3e56c-0d81-463d-b8e8-44b5a150ee95.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Y15gGgNX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://d26pm0riky5t4b.cloudfront.net/uploads/image/file/1bc3e56c-0d81-463d-b8e8-44b5a150ee95.png" alt="node js web development"&gt;&lt;/a&gt;&lt;br&gt; &lt;br&gt;
&lt;br&gt; &lt;/p&gt;

&lt;h2&gt;
  
  
  Features and uses of Node.js
&lt;/h2&gt;

&lt;p&gt;We list some critical elements that make Node.js popular with software developers.&lt;/p&gt;

&lt;h3&gt;
  
  
  Asynchronous scripts based on events
&lt;/h3&gt;

&lt;p&gt;All Node.js APIs are asynchronous, that is, non-blocking downloads. In essence, Node.js based server never expects data to return from the API. After the call, the server proceeds to the next API, and the Node.js Events notification mechanism helps the server to get a response from the previous API call.&lt;/p&gt;

&lt;h3&gt;
  
  
  Very fast
&lt;/h3&gt;

&lt;p&gt;Being built on the Google Chrome V8 JavaScript browser, the Node.js library and runs very quickly in code. As for our experience, we prefer to rewrite some code to Go instead of Node.js, and only when it is necessary. Thus, we are leveling the speed advantage of Node.js. But you must understand that in complex applications, different parts can affect speed, like a database, a web server, and more — not just pure language speed.&lt;/p&gt;

&lt;h3&gt;
  
  
  Single-flow but easily scalable
&lt;/h3&gt;

&lt;p&gt;Node.js uses a single-threaded model with an event loop. The Event engine helps the server response in a nonblocking manner, and provides high scalability, unlike traditional servers, which create limited threads for processing requests. Node.js uses a single-threaded program, and the same program can serve a much larger number of requests than traditional servers, the Apache HTTP Server.&lt;/p&gt;

&lt;h3&gt;
  
  
  No buffering
&lt;/h3&gt;

&lt;p&gt;Node.js applications do not buffer the data. They output the data in parts.&lt;/p&gt;

&lt;h3&gt;
  
  
  License
&lt;/h3&gt;

&lt;p&gt;Node.js released under the MIT license.&lt;/p&gt;

&lt;h3&gt;
  
  
  Where and who uses Node.js?
&lt;/h3&gt;

&lt;p&gt;In these areas, Node.js has established itself as an ideal technological solution:&lt;/p&gt;

&lt;p&gt;— applications related to data input/output&lt;/p&gt;

&lt;p&gt;— applications for streaming data&lt;/p&gt;

&lt;p&gt;— intensive use of real-time data (DIRT)&lt;/p&gt;

&lt;p&gt;— JSON API based applications&lt;/p&gt;

&lt;p&gt;Among the users are such large companies as eBay, General Electric, GoDaddy, Microsoft, PayPal, Uber, Wikipins, Yahoo! and yammer.&lt;br&gt; &lt;br&gt;
&lt;br&gt; &lt;/p&gt;

&lt;h2&gt;
  
  
  Where Node.js wins vs. Ruby on Rails?
&lt;/h2&gt;

&lt;p&gt;Node.js is excellent for applications that are real-time and which handle a lot of concurrent requests. Under these scenarios, data regularly go between the client and the server. These Real-Time Applications (RTAs) include chat apps, applications for collaborating and video conferencing.&lt;/p&gt;

&lt;p&gt;Because Node.jsis event-based, it’s great for handling these apps. Running on a single page, known as SPAs or Single Page Applications, involves a lot of processing on the client side. The primary function for the back-end under these scenarios is to provide a REST API.&lt;br&gt; &lt;br&gt;
&lt;br&gt; &lt;/p&gt;

&lt;h2&gt;
  
  
  TOP 10 famous Ruby on Rails web apps
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--oOQL95ZD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://d26pm0riky5t4b.cloudfront.net/uploads/image/file/8aab6150-c358-48f6-baf1-4965fa3725fd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--oOQL95ZD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://d26pm0riky5t4b.cloudfront.net/uploads/image/file/8aab6150-c358-48f6-baf1-4965fa3725fd.png" alt="ruby on rails web apps "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Github
&lt;/h3&gt;

&lt;p&gt;Github is a web-based hosting service for version control using Git. It mostly used for computer code. It offers all of the distributed version control and source code management (SCM) functionality of Git as well as adding its features.&lt;/p&gt;

&lt;p&gt;It provides access control and several collaboration features such as bug tracking, feature requests, task management, and wikis for every project.&lt;/p&gt;

&lt;h3&gt;
  
  
  Bloomberg
&lt;/h3&gt;

&lt;p&gt;Bloomberg is a privately held financial, software, data, and media company headquartered in Midtown Manhattan, New York City. It was founded by Michael Bloomberg in 1981, with the help of Thomas Secunda, Duncan MacMillan, Charles Zegar, and a 30% ownership investment by Merrill Lynch. Bloomberg L.P. provides financial software tools such as an analytics and equity trading platform, data services, and news to financial companies and organizations through the Bloomberg Terminal, its core revenue-generating product.&lt;/p&gt;

&lt;h3&gt;
  
  
  Yellow Pages
&lt;/h3&gt;

&lt;p&gt;The yellow pages are any telephone directory of businesses, organized by category rather than alphabetically by business name, and in which advertising is sold. The directories originally printed on yellow paper, as opposed to white pages for non-commercial listings. The traditional term "yellow pages" is now also applied to online directories of businesses.&lt;/p&gt;

&lt;h3&gt;
  
  
  Shopify
&lt;/h3&gt;

&lt;p&gt;Shopify is a Canadian e-commerce company headquartered in Ottawa, Ontario. It is also the name of its proprietary e-commerce platform for online stores and retail point-of-sale systems. Shopify offers online retailers a suite of services including payments, marketing, shipping and customer engagement tools to simplify the process of running an online store for small merchants.&lt;/p&gt;

&lt;h3&gt;
  
  
  Groupon
&lt;/h3&gt;

&lt;p&gt;Groupon is an American worldwide e-commerce marketplace connecting subscribers with local merchants by offering activities, travel, goods and services in 15 countries. Based in Chicago, Groupon was launched in November 2008, and the first market for Groupon was Chicago, followed soon after that by Boston, New York City, and Toronto. By October 2010, Groupon was available in 150 cities in North America and 100 cities in Europe, Asia, and South America.&lt;/p&gt;

&lt;h3&gt;
  
  
  Airbnb
&lt;/h3&gt;

&lt;p&gt;Airbnb is a privately held global company headquartered in San Francisco that operates an online marketplace and hospitality service which is accessible via its websites and mobile apps. Members can use the service to arrange or offer lodging, primarily homestays, or tourism experiences. The company does not own any of the real estate listings, nor does it host events; as a broker, it receives commissions from every booking.&lt;/p&gt;

&lt;h3&gt;
  
  
  Dribbble
&lt;/h3&gt;

&lt;p&gt;Dribbble is an online community for showcasing user-made artwork. It functions as a self-promotion and networking platform for graphic design, web design, illustration, photography, and other creative areas. It was founded in 2009 by Dan Cederholm and Rich Thornett, becoming publicly available in 2010. It is one of the largest platforms for designers to share their work online.&lt;/p&gt;

&lt;h3&gt;
  
  
  SlideShare
&lt;/h3&gt;

&lt;p&gt;SlideShare is a hosting service for professional content including presentations, infographics, documents, and videos. Users can upload files privately or publicly in PowerPoint, Word, PDF, or OpenDocument format. Content can then be viewed on the site itself, on handheld devices or embedded on other sites. The website was originally meant to be used for businesses to share slides among employees more efficiently, but it also has expanded to become a host of a large number of slides that are uploaded merely to entertain.&lt;/p&gt;

&lt;h3&gt;
  
  
  Hulu
&lt;/h3&gt;

&lt;p&gt;Hulu is an American entertainment company that provides "over-the-top media services." It is primarily oriented towards instant streaming of television series, carrying current and past episodes of many series from its owners' respective television networks and other content partners.&lt;/p&gt;

&lt;h3&gt;
  
  
  SoundCloud
&lt;/h3&gt;

&lt;p&gt;SoundCloud was established in Berlin in August 2007 by Swedish sound designer Alexander Ljung and Swedish electronic musician Eric Wahlforss, and the website launched in October 2008. SoundCloud is an online audio distribution platform and music sharing website based in Berlin, Germany that enables its users to upload, promote, and share audio.&lt;/p&gt;

&lt;p&gt;Read more about developments and technologies we use in our blog here &lt;a href="https://amoniac.eu/blog"&gt;https://amoniac.eu/blog&lt;/a&gt;&lt;/p&gt;

</description>
      <category>ruby</category>
      <category>rails</category>
      <category>node</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Why we fell in love with Vue.js?</title>
      <dc:creator>Oleksandr Simonov</dc:creator>
      <pubDate>Wed, 22 Jan 2020 11:43:08 +0000</pubDate>
      <link>https://dev.to/amoniacou/why-we-fell-in-love-with-vue-js-293</link>
      <guid>https://dev.to/amoniacou/why-we-fell-in-love-with-vue-js-293</guid>
      <description>&lt;h2&gt;
  
  
  What is Vue.JS?
&lt;/h2&gt;

&lt;p&gt;Vue.js is an open source JavaScript framework for creating user interfaces. Easily integrated into projects using other JavaScript libraries. It can function as a web framework that helps develop advanced one-page applications.&lt;/p&gt;

&lt;p&gt;In 2013, an employee of Google Evan You, working on one of the projects, concluded that there are no ready-made solutions for rapid prototyping of complex user interfaces of web applications. React was then at an early stage of development, the main tools were such complex frameworks as AngularJS or MVC-oriented Backbone.js, which were not very simple and focused on developing large applications. To overcome this gap, You began developing Vue.js, which, while maintaining simplicity, turned out to be suitable not only for prototyping but also for full-fledged development.&lt;/p&gt;

&lt;p&gt;Theoretically, Vue.js is an alternative to jQuery. But in reality, Vue.JS competes quite successfully with React.JS - the obvious leader in the field of View. From modern popular technologies that solve similar problems, you can also select Angular and Ember. Each of them has its advantages and disadvantages. However, all these frameworks can be reduced to one common denominator - the relative complexity of development.&lt;/p&gt;

&lt;h2&gt;
  
  
  Vue.JS vs others
&lt;/h2&gt;

&lt;p&gt;Vue.JS created with an eye on the best practices of the listed technologies. From React.JS, the Vue team borrowed the idea of a virtual DOM. This approach eliminates direct interaction with interface nodes. The initial work is carried out with its lightweight copy - virtual DOM. And only after this changes applied to the real interface nodes. In parallel, a comparison of the real DOM tree and its virtual copy takes place. Thus the difference is revealed, and only that which has changed redrawn.&lt;/p&gt;

&lt;p&gt;From Angular Vue.JS borrowed two-way data binding. This allows you to design interfaces: firstly, declaratively; secondly, using Vue in template engines. Such as Haml or Pug. But It's true that this approach has been practiced before, for example, in the Knockout.JS framework.&lt;/p&gt;

&lt;p&gt;The Vue.JS kernel, like React, contains only the necessary functionality for working with the interface. Therefore, it is compact, easily integrates with other technologies, including jQuery, and can even be used instead to develop simple interfaces.&lt;/p&gt;

&lt;p&gt;In addition, Vue has a number of plug-ins that implement a modern approach to the development of web applications. What is it about? For example, almost all React applications are designed in tandem with the state control technology Redux, which is a separate library and implements the flux-architecture. The approach practiced by the Redux library turned out to be quite convenient and successful. Therefore, Vue.JS has developed its own application state control technology - Vuex. Vuex completely borrows the ideas of Redux, but the degree of integration of this library with Vue is much higher than in the case of React and Redux. And this translates into speed and convenience.  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--Hyndqfyj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://d26pm0riky5t4b.cloudfront.net/uploads/image/file/f33544fa-ee9b-4e38-9f8e-88ddbc764de8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--Hyndqfyj--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://d26pm0riky5t4b.cloudfront.net/uploads/image/file/f33544fa-ee9b-4e38-9f8e-88ddbc764de8.png" alt="app development vue js"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Vue.js main distinctive ideas
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Reactivity
&lt;/h3&gt;

&lt;p&gt;Reactivity is when the data inside the application is directly related to the data in the display and changing it in any part instantly affects the redrawing of the screen. How is reactivity implemented in React? In short, all data that we use in the application stored in state and props, if necessary, change the data, we change it through setState, then React determines which parts of the app depended on the modified data and redrew it.  &lt;/p&gt;

&lt;p&gt;In Vue.js, a similar approach used, but it has one fundamental difference - each field of application input data is expanded using Object.defineProperty and divided into setter/getter pairs. With their help, Vue keeps track of what data is being read or modified and can specifically determine what affects the rendering of the display.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--FBrT_GyX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://d26pm0riky5t4b.cloudfront.net/uploads/image/file/24332d86-8e94-4508-a3f1-55acd552a588.png" alt="vue js development services"&gt;
&lt;/h3&gt;

&lt;h3&gt;
  
  
  2. Calculated properties
&lt;/h3&gt;

&lt;p&gt;There are several component data types in Vue:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;data - basic data;
&lt;/li&gt;
&lt;li&gt;props - data transmitted from the parent component;
&lt;/li&gt;
&lt;li&gt;computed - data that can be calculated based on the previous two.
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This separation of concepts is a simple but convenient idea. The latter has a number of advantages compared with the approach to React:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;We cease to produce auxiliary methods of the form getFullName for components;
&lt;/li&gt;
&lt;li&gt;They are reactive, and at the first calculation, with the help of extended getters (the principle described in the first paragraph) they collect dependencies and know for sure when changing what data recalculation is necessary;
&lt;/li&gt;
&lt;li&gt;They are lazy, i.e. are counted only when they are accessed, and not with each change of dependent data;
&lt;/li&gt;
&lt;li&gt;Cached based on input data.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Similar behavior, when working with a large sample size in Redux, can be achieved with Reselect.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Built-in FLIP animation
&lt;/h3&gt;

&lt;p&gt;The idea of conveniently describing animations in frameworks is far from new (ng-animate, ReactCSSTransitionGroup). Surprises FLIP-animation right out of the box. In short, this is a kind of animation of moving elements when you first know their total positions and then move with the help of translate. In Vue, this animation can be obtained with just a couple of lines of code:&lt;br&gt;&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--sceG_Us4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://lh3.googleusercontent.com/HcsC3LqtVmUDLEGHRORUksYYfbUX3Pumd-gICG0EiZ4ouwDs4LMRGKbQEJv61OtuFmww7XTeRS57Es7Yd3YJWeYa0MbqFmbSzKbpSixgJfZ8aNjj_Fw1T0SSEIgPagA5IeXwqltZ" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--sceG_Us4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://lh3.googleusercontent.com/HcsC3LqtVmUDLEGHRORUksYYfbUX3Pumd-gICG0EiZ4ouwDs4LMRGKbQEJv61OtuFmww7XTeRS57Es7Yd3YJWeYa0MbqFmbSzKbpSixgJfZ8aNjj_Fw1T0SSEIgPagA5IeXwqltZ" alt="vue js development company"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Components and vue-loader
&lt;/h3&gt;

&lt;p&gt;Vue recommends storing all component code (js, styles, pattern) in a single file like a rather unusual approach. We will not judge how comfortable it is, especially when your components are far from atomic.  &lt;/p&gt;

&lt;p&gt;But there is a curious point, the components loaded via vue-loader for webpack, which hides the complexity of the build from you, allowing to use your favorite technologies right out of the box ES6, coffeeScript, Sass, postCSS, CSS modules, jade (pug) and others.&lt;/p&gt;

&lt;p&gt;And unlike React, we don’t need to deal with the new JSX language, and we continue to use what we are familiar with or use completely different HTML generators, such as PUG.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--qdSW30D8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://d26pm0riky5t4b.cloudfront.net/uploads/image/file/ab8555a3-2e84-4001-8f56-353072614d12.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--qdSW30D8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://d26pm0riky5t4b.cloudfront.net/uploads/image/file/ab8555a3-2e84-4001-8f56-353072614d12.png" alt="hire vue js development company"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;No setting, cool, huh?&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Slots
&lt;/h3&gt;

&lt;p&gt;The idea of the slots came from Web Components and is very simple - if you need to transfer several components inside another component, then you can designate the places where they will be displayed. This approach allows you to make complex components, wrappers that easily abstracted from what is happening inside. So, for example, you can make a layout component with several slots:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--ifB-H1EH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://d26pm0riky5t4b.cloudfront.net/uploads/image/file/c915f3b7-6eee-4002-867b-e326c9d1d680.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ifB-H1EH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://d26pm0riky5t4b.cloudfront.net/uploads/image/file/c915f3b7-6eee-4002-867b-e326c9d1d680.png" alt="web development vue js"&gt;&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  And let's look at a real example?
&lt;/h2&gt;

&lt;p&gt;Most recently, we developed a &lt;a href="https://amoniac.eu/works/cloud-checker"&gt;Cloud Checker&lt;/a&gt; service that allows to analyze cloud services and optimize their use.  &lt;/p&gt;

&lt;p&gt;This is where we actively used Vue. When developing the design for the project, Google Material Design has taken as the basis, it ideally suited for this task due to its simplicity and rigor, but despite this, it is quite pleasant and user-friendly.&lt;/p&gt;

&lt;p&gt;For this reason, at the preparatory stage for writing the frontend part, it was decided to use the ready Material Component Framework as Vuetify. It is intuitive and relatively simple when writing templates, it also stores an incredibly large and powerful base of ready-made components necessary to create a full-fledged ready-made application already from the box.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--J-oaR37k--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://d26pm0riky5t4b.cloudfront.net/uploads/image/file/84f520fc-905c-4ddc-b51b-d5a64f5c344f.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--J-oaR37k--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://d26pm0riky5t4b.cloudfront.net/uploads/image/file/84f520fc-905c-4ddc-b51b-d5a64f5c344f.png" alt="cloud service saving app development vue js"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--jwIS3luM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://d26pm0riky5t4b.cloudfront.net/uploads/image/file/e52f4530-ba6f-44b4-b6af-a225777a0370.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--jwIS3luM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://d26pm0riky5t4b.cloudfront.net/uploads/image/file/e52f4530-ba6f-44b4-b6af-a225777a0370.png" alt="cloud service saving development vue js"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Vue.JS pros and cons
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Vue.JS pros
&lt;/h3&gt;

&lt;p&gt;After examining the key features of the technology and testing them in practice, you can list the main advantages of the Vue framework:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Vue.js has many similar characteristics with Angular, and this can help optimize the processing of HTML blocks using different components.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Vue.js has very extensive documentation that can capture the learning curve for developers and save a lot of time developing an application using only basic knowledge of HTML and JavaScript.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;It provides a fast switching period from other frameworks in Vue.js due to the similarity with Angular and React in terms of design and architecture.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Vue.js can be used both for creating single-page applications and for more complex web interfaces. The main thing is that small interactive parts can be easily integrated into the existing infrastructure without having a negative impact on the entire system.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;There are no stack requirements, so Vue.JS can be used on any project.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Vue.js can weigh around 20 KB, retaining its speed and flexibility, which allows it to achieve much higher performance than other platforms.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Thanks to the use of any templates and the availability of documentation, most of the problems that arise resolved fairly quickly. Including in comparison with React, since in most applications that do not have complicated interfaces, the whole power of this framework is a bit redundant.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Vue.js can help develop fairly large reusable templates that can be made without the extra time allocated for this, in accordance with its simple structure.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;The ability to find and connect to the project almost any developer who is at least a little familiar with front-end. The low threshold of entry allows work with the framework, both front-end and back-end developers.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Vue allows you to create functional applications that meet all modern standards, with a minimal connection of new resources and, in fact, cheaper.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Vue.JS cons
&lt;/h3&gt;

&lt;p&gt;There are also disadvantages, in particular, in comparison with React.JS:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Work on the state of the application is “under the hood”. It increases the entry threshold for new developers, but for our team, this is not a real disadvantage.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Vue.js still has a fairly small market share compared to React or Angular, which means that the sharing of knowledge in this framework is still at an initial stage. But it should be noted that the trends are changing colossally, and Vue is very actively gaining momentum much faster than other frameworks.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Since Vue.js has some Chinese base, many elements and descriptions are still available in Chinese. This leads to partial complexity at some stages of development, however, more and more materials translated into English. As for personal experience, our team copes with tasks of any complexity with the help of Vue and has not encountered any misunderstandings in using the framework.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--O2vRwFM_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://d26pm0riky5t4b.cloudfront.net/uploads/image/file/4aa20224-4b41-4cc2-948b-8ce438bf96e8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--O2vRwFM_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://d26pm0riky5t4b.cloudfront.net/uploads/image/file/4aa20224-4b41-4cc2-948b-8ce438bf96e8.png" alt="vue js soft development "&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Despite such shortcomings in the work of Vue.js, our development team has a huge experience in working with technology and ready to cope with absolutely any complex and even sometimes overwhelming tasks.&lt;/p&gt;

&lt;p&gt;Today, Vue.js is used by such companies as Xiaomi, Alibaba, WizzAir, EuroNews, Grammarly, Gitlab and Laracasts, Adobe, Behance, Codeship, Reuters.&lt;/p&gt;

&lt;p&gt;Angular and React have their own ways to do the things, where, Vue is considerably easy. Many companies are switching to Vue because it is easy to work with. Developing in Angular or React requires good JavaScript knowledge and you need to take a lot of decisions regarding third-party libraries.  &lt;/p&gt;

&lt;p&gt;Now if we consider our frameworks in this case, Angular uses two-way data binding, React goes for single-data flow, and Vue supports both.  &lt;/p&gt;

&lt;p&gt;Every framework has its own pros and cons, meaning that there should be just the right choice for every single case during the product development.&lt;/p&gt;

&lt;p&gt;Read more about developments and technologies we use in our blog here &lt;a href="https://amoniac.eu/blog"&gt;https://amoniac.eu/blog&lt;/a&gt;&lt;/p&gt;

</description>
      <category>vue</category>
      <category>vuefrontend</category>
      <category>react</category>
      <category>angular</category>
    </item>
  </channel>
</rss>
