<?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: italojs</title>
    <description>The latest articles on DEV Community by italojs (@italojs).</description>
    <link>https://dev.to/italojs</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F415948%2F3c14b5e8-0f62-4a8a-97ea-f680d8a59146.png</url>
      <title>DEV Community: italojs</title>
      <link>https://dev.to/italojs</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/italojs"/>
    <language>en</language>
    <item>
      <title>Enhancing Performance in MeteorJS bundler: Complete Guide to CPU Profiling</title>
      <dc:creator>italojs</dc:creator>
      <pubDate>Fri, 28 Mar 2025 19:20:50 +0000</pubDate>
      <link>https://dev.to/meteor/enhancing-performance-in-meteorjs-bundler-complete-guide-to-cpu-profiling-4igo</link>
      <guid>https://dev.to/meteor/enhancing-performance-in-meteorjs-bundler-complete-guide-to-cpu-profiling-4igo</guid>
      <description>&lt;p&gt;Performance is a fundamental concern for any modern web application, and Meteor apps are no exception. Currently, one of our main focuses is optimizing the Meteor bundler, which can be a significant bottleneck in larger projects. Although Meteor already offers built-in tools for performance analysis, using native CPU profiling can provide much deeper insights into performance bottlenecks. In this article, we'll explore how to effectively use CPU profiling in Meteor, including the difference between Meteor's current profiling system and native profiling based on Node.js Inspector, with special emphasis on how this can help improve the bundling process.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is CPU Profiling?
&lt;/h2&gt;

&lt;p&gt;CPU profiling is a performance analysis technique that tracks exactly which functions are being executed by the CPU, for how long, and how frequently. This type of analysis allows you to identify precisely where your code is spending the most processing time.&lt;/p&gt;

&lt;p&gt;Unlike simple time measurement techniques (like basic timers), CPU profiling creates a comprehensive view of code execution, including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Function call tree - shows which functions call other functions&lt;/li&gt;
&lt;li&gt;Execution time for each function&lt;/li&gt;
&lt;li&gt;Frequency of calls for each function&lt;/li&gt;
&lt;li&gt;Memory allocation (in some cases)&lt;/li&gt;
&lt;li&gt;Call stack visualization&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Current Meteor Profiling vs Native CPU Profiling
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Meteor's Built-in Profiling System
&lt;/h3&gt;

&lt;p&gt;Meteor has a built-in profiling system that can be activated by setting the &lt;code&gt;METEOR_PROFILE&lt;/code&gt; environment variable. This system uses a timer-based measurement approach:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;METEOR_PROFILE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1 meteor &amp;lt;&lt;span class="nb"&gt;command&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This profiler is designed specifically for the Meteor ecosystem and works through manual code instrumentation. The result is a report that shows the time spent on different Meteor operations, such as:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;| (#1) Profiling: ProjectContext prepareProjectForBuild
| ProjectContext prepareProjectForBuild..........9,207 ms (1)
|    _initializeCatalog.............................24 ms (1)
|       files.readFile                               7 ms (2)
|       runJavaScript package.js                     2 ms (1)
|       files.rm_recursive                           4 ms (4)
|       other _initializeCatalog                    11 ms
|    _resolveConstraints.........................6,702 ms (1)
|       bundler.readJsImage.........................42 ms (1)
...
| (#1) Total: 9,544 ms (ProjectContext prepareProjectForBuild)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Native CPU Profiling with Node.js Inspector
&lt;/h3&gt;

&lt;p&gt;Recent versions of Meteor have included support for native CPU profiling using Node.js's &lt;code&gt;inspector&lt;/code&gt; module. This approach generates &lt;code&gt;.cpuprofile&lt;/code&gt; files that provide much more detailed data and can be analyzed with advanced tools such as Chrome DevTools or cpupro.&lt;/p&gt;

&lt;p&gt;To enable native CPU profiling:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;METEOR_INSPECT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;bundler.bundle,compiler.compile meteor &amp;lt;&lt;span class="nb"&gt;command&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Advantages of Native CPU Profiling:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Complete execution view:&lt;/strong&gt; Captures all functions being executed, not just those manually instrumented&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Interactive analysis:&lt;/strong&gt; Allows you to visually explore and filter performance data using graphical tools&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Hidden bottleneck discovery:&lt;/strong&gt; Identifies problems in third-party libraries or Node.js code&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Superior precision:&lt;/strong&gt; Uses CPU sampling directly, providing more accurate data about actual CPU usage&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Multiple metrics:&lt;/strong&gt; Beyond time, can provide data on memory allocation and other aspects&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  How to Use Native CPU Profiling in Meteor
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Basic Configuration
&lt;/h3&gt;

&lt;p&gt;To generate a basic CPU profile, use the &lt;code&gt;METEOR_INSPECT&lt;/code&gt; environment variable specifying which functions you want to profile:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Profile a single function&lt;/span&gt;
&lt;span class="nv"&gt;METEOR_INSPECT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;bundler.bundle meteor build ./output-build

&lt;span class="c"&gt;# Profile multiple functions&lt;/span&gt;
&lt;span class="nv"&gt;METEOR_INSPECT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;bundler.bundle,compiler.compile meteor build ./output-build
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Available Functions for Profiling
&lt;/h3&gt;

&lt;p&gt;Meteor supports profiling for several critical functions:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;bundler.bundle&lt;/code&gt; - Application packaging process&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;compiler.compile&lt;/code&gt; - General compilation&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Babel.compile&lt;/code&gt; - Babel-specific compilation&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;_readProjectMetadata&lt;/code&gt; - Reading project metadata&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;initializeCatalog&lt;/code&gt; - Package catalog initialization&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;_downloadMissingPackages&lt;/code&gt; - Downloading missing packages&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;_saveChangeMetadata&lt;/code&gt; - Saving change metadata&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;_realpath&lt;/code&gt; - File path resolution&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;package-client&lt;/code&gt; - Package client operations&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Advanced Configuration Options
&lt;/h3&gt;

&lt;p&gt;You can customize the profiling behavior with additional environment variables:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Identifier for profile files&lt;/span&gt;
&lt;span class="nv"&gt;METEOR_INSPECT_CONTEXT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;context_name

&lt;span class="c"&gt;# Directory where .cpuprofile files will be saved (default: ./profiling)&lt;/span&gt;
&lt;span class="nv"&gt;METEOR_INSPECT_OUTPUT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/path/to/directory

&lt;span class="c"&gt;# Sampling interval in ms - lower values = more details but uses more memory&lt;/span&gt;
&lt;span class="nv"&gt;METEOR_INSPECT_INTERVAL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;500

&lt;span class="c"&gt;# Maximum profile size in MB (default: 2000)&lt;/span&gt;
&lt;span class="nv"&gt;METEOR_INSPECT_MAX_SIZE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;1000
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  For Large Applications
&lt;/h3&gt;

&lt;p&gt;Larger applications may require more memory for profiling. To avoid out-of-memory (OOM) errors:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;NODE_OPTIONS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"--max-old-space-size=4096"&lt;/span&gt; &lt;span class="nv"&gt;METEOR_INSPECT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;bundler.bundle meteor &amp;lt;&lt;span class="nb"&gt;command&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Analyzing CPU Profiling Results
&lt;/h2&gt;

&lt;h3&gt;
  
  
  With Chrome DevTools
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Open Chrome DevTools&lt;/li&gt;
&lt;li&gt;Go to the "Performance" or "Profiler" tab&lt;/li&gt;
&lt;li&gt;Click "Load Profile" and select the generated .cpuprofile file&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  With cpupro (Open-Source Visualizer)
&lt;/h3&gt;

&lt;p&gt;For more advanced analysis, you can use &lt;a href="https://discoveryjs.github.io/cpupro/" rel="noopener noreferrer"&gt;cpupro&lt;/a&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Visit &lt;a href="https://discoveryjs.github.io/cpupro/" rel="noopener noreferrer"&gt;https://discoveryjs.github.io/cpupro/&lt;/a&gt; in your browser&lt;/li&gt;
&lt;li&gt;Drag and drop your .cpuprofile file onto the interface&lt;/li&gt;
&lt;li&gt;Use the interactive visualization to explore your profile data&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;cpupro offers several advantages over Chrome DevTools:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Better handling of large profiles&lt;/li&gt;
&lt;li&gt;More flexible filtering options&lt;/li&gt;
&lt;li&gt;Advanced search capabilities&lt;/li&gt;
&lt;li&gt;Multiple visualization modes&lt;/li&gt;
&lt;li&gt;Ability to compare different profiles&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Practical Use Cases
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Identifying Bottlenecks in Template Compilation
&lt;/h3&gt;

&lt;p&gt;If your Meteor application is taking a long time to restart after template changes, you can use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;METEOR_INSPECT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;compiler.compile meteor run
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Analyze the resulting profile to identify which templates are causing the most overhead.&lt;/p&gt;

&lt;h3&gt;
  
  
  Diagnosing Slow Build Problems
&lt;/h3&gt;

&lt;p&gt;For apps with slow builds:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;METEOR_INSPECT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;bundler.bundle meteor build ./output
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Look in the profile for functions that are consuming excessive time, such as CSS processing, code transpilation, or minification.&lt;/p&gt;

&lt;h3&gt;
  
  
  Optimizing Package Loading
&lt;/h3&gt;

&lt;p&gt;If you suspect packages are affecting performance:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;METEOR_INSPECT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;_downloadMissingPackages,package-client meteor update
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  When to Use Each Type of Profiling
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Use Meteor's Built-in Profiling (&lt;code&gt;METEOR_PROFILE&lt;/code&gt;) when:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;You need a quick and general overview of Meteor tool performance&lt;/li&gt;
&lt;li&gt;You're analyzing specific issues in Meteor operations&lt;/li&gt;
&lt;li&gt;You prefer simple text-based reports&lt;/li&gt;
&lt;li&gt;You have limited system resources (less memory usage)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Use Native CPU Profiling (&lt;code&gt;METEOR_INSPECT&lt;/code&gt;) when:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;You need more detailed analysis than the standard profiler provides&lt;/li&gt;
&lt;li&gt;You're investigating complex performance issues&lt;/li&gt;
&lt;li&gt;You want to identify specific bottlenecks in heavy functions like bundler or compiler&lt;/li&gt;
&lt;li&gt;You need interactive visualization and in-depth analysis&lt;/li&gt;
&lt;li&gt;You're looking to understand issues in third-party libraries or Node.js runtime&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Real life demo
&lt;/h3&gt;

&lt;p&gt;When using CPU profiling in real Meteor applications, we can identify specific bottlenecks that significantly impact performance. Let's analyze two practical examples:&lt;/p&gt;

&lt;h4&gt;
  
  
  Case 1: Babel as the main CPU consumer
&lt;/h4&gt;

&lt;p&gt;When examining a Meteor CPU profile, we can clearly observe that Babel is the module consuming most of the processing time, both in self time (time spent within the function itself) and total time (time including calls to other functions):&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0utl507f9adl3y67dbrr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F0utl507f9adl3y67dbrr.png" alt="Image description" width="800" height="316"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is a known issue in the Meteor community and fortunately it's already being addressed by PRs &lt;a href="https://github.com/meteor/meteor/pull/13675" rel="noopener noreferrer"&gt;#13675&lt;/a&gt; and &lt;a href="https://github.com/meteor/meteor/pull/13674" rel="noopener noreferrer"&gt;#13674&lt;/a&gt;, which aim to replace Babel with SWC, a much faster transpiler written in Rust.&lt;/p&gt;

&lt;p&gt;PR #13675, in particular, implements a smart approach: it uses SWC for initial transpilation, but preserves reify to maintain Meteor-specific features, such as reify modules, nested imports, and top-level await support. This allows gaining speed without losing important functionalities of the Meteor ecosystem.&lt;/p&gt;

&lt;h4&gt;
  
  
  Case 2: Analyzing by Self Time - The bottleneck in compiler-plugin
&lt;/h4&gt;

&lt;p&gt;When sorting the same profile by "self time", we find the "script" module appearing as the one consuming the most processing time.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk6qq43qriy0km4opbtx5.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk6qq43qriy0km4opbtx5.png" alt="Image description" width="800" height="118"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Digging deeper, we see that the &lt;code&gt;compiler-plugin.js&lt;/code&gt; file is responsible for much of this consumption. And digging even deeper, the &lt;code&gt;_linkJS&lt;/code&gt; function stands out as the most expensive of all.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmml4foc9zvevun32rnsf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmml4foc9zvevun32rnsf.png" alt="Image description" width="800" height="124"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Examining the flame graph of this function, we can see that there is especially intensive processing in the generation of hashes for the cache system:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4fnj3cc9tllhx63g7hh4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4fnj3cc9tllhx63g7hh4.png" alt="Image description" width="800" height="202"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;cacheKeyPrefix&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;sha1&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="nx"&gt;linkerOptions&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;files&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nb"&gt;Promise&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="nx"&gt;jsResources&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;inputFile&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="nx"&gt;fileHashes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;inputFile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;hash&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
      &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;meteorInstallOptions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;inputFile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;meteorInstallOptions&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;absModuleId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;inputFile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;absModuleId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;sourceMap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="o"&gt;!!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;inputFile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sourceMap&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="na"&gt;mainModule&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;inputFile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mainModule&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;imported&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;inputFile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;imported&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;alias&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;inputFile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;alias&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;lazy&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;inputFile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;lazy&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;bare&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;inputFile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bare&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;};&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}));&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;cacheKeySuffix&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;sha1&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;stringify&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="nx"&gt;LINKER_CACHE_SALT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="nx"&gt;fileHashes&lt;/span&gt;
&lt;span class="p"&gt;}));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This snippet shows that for each JavaScript file processed, the function executes:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Multiple &lt;code&gt;await&lt;/code&gt; operations to access properties like &lt;code&gt;hash&lt;/code&gt; and &lt;code&gt;sourceMap&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Conversions to JSON (via &lt;code&gt;JSON.stringify&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Multiple SHA-1 hash calculations&lt;/li&gt;
&lt;li&gt;Promise operations that occur for each file individually&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The impact of this code is significant because it is executed for each JavaScript file in each module/package, becoming a serious bottleneck in larger applications with many files. Each call of this function processes all files again to generate cache keys, even when most files haven't changed.&lt;/p&gt;

&lt;p&gt;This is an area where focused optimization could bring significant benefits.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;While Meteor's built-in profiling system offers a more practical solution for performance analysis, native CPU profiling based on Node.js Inspector provides deeper and more detailed insights into your application's build performance. By combining both approaches, Meteor developers can identify and solve performance problems with unprecedented precision.&lt;/p&gt;

&lt;p&gt;Try these techniques in your next performance debugging session and see how CPU profiling can transform your approach to optimizing Meteor applications. &lt;/p&gt;

</description>
    </item>
    <item>
      <title>🇧🇷 child_process: spawn, fork ou exec, qual usar?</title>
      <dc:creator>italojs</dc:creator>
      <pubDate>Thu, 02 Nov 2023 21:31:10 +0000</pubDate>
      <link>https://dev.to/italojs/childprocess-spawn-fork-ou-exec-qual-usar-112m</link>
      <guid>https://dev.to/italojs/childprocess-spawn-fork-ou-exec-qual-usar-112m</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb7nk73cij24krnavtwr8.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb7nk73cij24krnavtwr8.jpg" alt="Image description" width="650" height="591"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Introdução
&lt;/h2&gt;

&lt;p&gt;Uma das características valiosas do Node.js é sua capacidade de gerenciar processos filhos através de métodos como spawn, fork e exec. Embora sirvam propósitos semelhantes, há diferenças cruciais entre eles que podem impactar a eficiência e a facilidade de implementação em diferentes cenários. Este artigo visa elucidar as distinções entre spawn, fork e exec, e fornecerá exemplos práticos e casos de uso para uma compreensão aprofundada.&lt;/p&gt;

&lt;h2&gt;
  
  
  Spawn
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Descrição&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;O método spawn, disponível através do módulo child_process no Node.js, é utilizado para criar processos filhos. Ele é capaz de executar qualquer comando no sistema operacional e é ideal para tarefas que demandam a execução de comandos externos.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Exemplo de Código&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;spawn&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;child_process&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ls&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;spawn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ls&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;-lh&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/usr&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;

&lt;span class="nx"&gt;ls&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stdout&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;data&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`stdout: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;ls&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stderr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;data&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`stderr: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;ls&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;close&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;code&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`child process exited with code &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;code&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Caso de Uso: Processamento de Imagens&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Em uma aplicação web, pode ser necessário converter formatos de imagem ou vídeo. Utilizando o spawn, é possível executar comandos externos para realizar estas conversões.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;spawn&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;child_process&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;ffmpeg&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;spawn&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ffmpeg&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;-i&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;input.mp4&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;output.avi&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;
&lt;span class="nx"&gt;ffmpeg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;stderr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;data&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toString&lt;/span&gt;&lt;span class="p"&gt;()));&lt;/span&gt;
&lt;span class="nx"&gt;ffmpeg&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;close&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;code&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Process exited with code &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;code&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Quando não usar&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Embora o método spawn seja extremamente útil para executar comandos externos, ele não é recomendado em cenários onde:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A saída do comando não é relevante, pois pode consumir recursos desnecessariamente.&lt;/li&gt;
&lt;li&gt;A comunicação bidirecional entre o processo principal e o filho é necessária. Neste caso, o fork seria mais apropriado.&lt;/li&gt;
&lt;li&gt;Comandos simples do shell são necessários, pois exec poderia ser mais conciso.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Fork
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Descrição&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;O método fork é uma variação especial do spawn que é utilizada para criar um novo processo Node.js. Ele facilita a comunicação entre o processo pai e o processo filho através de um canal IPC (Inter-process Communication).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Exemplo de Código&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;fork&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;child_process&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;child&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;fork&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;child.js&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nx"&gt;child&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;message&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Message from child&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;msg&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;child&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="na"&gt;hello&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;world&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Caso de Uso: APIs de Longa Execução&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Em cenários onde há APIs que levam muito tempo para serem processadas, pode-se utilizar o fork para processar essas requisições em um processo separado, mantendo o servidor principal livre para atender outras requisições.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;fork&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;child_process&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;express&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)();&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/long-running-api&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;fork&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;longRunningApi.js&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;req&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;body&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;message&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;result&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="nx"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;listen&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Server is running on port 3000&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Quando não usar&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;O método fork é uma ferramenta poderosa, mas não é a melhor escolha quando:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A tarefa não exige um novo processo Node.js, pois pode causar sobrecarga desnecessária.&lt;/li&gt;
&lt;li&gt;Não há necessidade de comunicação IPC entre os processos.&lt;/li&gt;
&lt;li&gt;Se deseja executar comandos que não são específicos do Node.js. Nesse caso, spawn ou exec seria mais apropriado.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Exec
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Descrição&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;O método exec é utilizado para executar comandos no shell. Ele é semelhante ao spawn, mas difere em que ele gera um shell e executa o comando dentro desse shell, bufferizando qualquer saída produzida.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Exemplo de Código&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;exec&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;child_process&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nf"&gt;exec&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ls -lh /usr&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;stdout&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;stderr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Error: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;error&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;stderr&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;error&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Stderr: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;stderr&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

  &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`Stdout: &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;stdout&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Caso de Uso: Execução de Scripts Shell&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Em uma aplicação web, pode haver uma necessidade de executar scripts shell para automação ou administração do sistema. O exec facilita a execução desses scripts diretamente do código Node.js.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Quando não usar&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;O método exec é excelente para comandos simples do shell, mas deve ser evitado quando:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A saída do comando é extensa, pois ele bufferiza a saída e pode levar a problemas de memória.&lt;/li&gt;
&lt;li&gt;A execução de comandos externos de longa duração é necessária, pois pode bloquear o Event Loop.&lt;/li&gt;
&lt;li&gt;Precisão e controle detalhado sobre o processo filho são necessários. Neste caso, o spawn seria a melhor escolha.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;A escolha entre spawn, fork e exec depende das necessidades específicas do projeto. O entendimento profundo desses métodos e de suas aplicações práticas permite uma programação mais eficaz e eficiente em Node.js.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fra9rgybkxatyaajhljyn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fra9rgybkxatyaajhljyn.png" alt="Image description" width="800" height="129"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Newsletter
&lt;/h2&gt;

&lt;p&gt;Gostou desse conteúdo? Aproveita pra se inscrever na nossa newsletter &lt;a href="https://highperformanceletterbr.substack.com/" rel="noopener noreferrer"&gt;https://highperformanceletterbr.substack.com/&lt;/a&gt;&lt;br&gt;
Postamos conteúdos sobre performance e otimização todas as semanas!&lt;/p&gt;

&lt;h2&gt;
  
  
  Primeiro curso de performance backend js do brasil(ou do mundo)
&lt;/h2&gt;

&lt;h4&gt;
  
  
  🚀 Domine o Desempenho Backend com JavaScript! 🚀
&lt;/h4&gt;

&lt;p&gt;🎓 Apresentamos o PRIMEIRO Curso de Performance Backend em JavaScript no Brasil! 🇧🇷&lt;/p&gt;

&lt;p&gt;🔥 Seja um dos pioneiros a explorar o mundo do desenvolvimento backend com foco em eficiência e velocidade. Este curso exclusivo é sua porta de entrada para se tornar um especialista em otimização e desempenho de aplicações JavaScript.&lt;/p&gt;

&lt;h4&gt;
  
  
  🌟 O Que Oferecemos:
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;Instrutores Especialista:&lt;/strong&gt; Aprenda com um profissional que atua com esse assunto no dia a dia.&lt;br&gt;
&lt;strong&gt;Conteúdo Avançado:&lt;/strong&gt; Desde fundamentos até técnicas avançadas de otimização.&lt;br&gt;
&lt;strong&gt;Projetos Práticos:&lt;/strong&gt; Coloque suas habilidades à prova com desafios reais.&lt;br&gt;
&lt;strong&gt;Comunidade e Networking:&lt;/strong&gt; Junte-se a uma comunidade vibrante de desenvolvedores.&lt;br&gt;
&lt;strong&gt;🛠️ Domine Ferramentas e Técnicas Essenciais:&lt;/strong&gt; Conteúdo prático sobre as melhores tools de monitoramento e análise de recursos&lt;/p&gt;

&lt;h4&gt;
  
  
  Análise de Performance;
&lt;/h4&gt;

&lt;p&gt;Diagnóstico;&lt;br&gt;
Otimização de Código;&lt;br&gt;
Gerenciamento Eficiente de Memória;&lt;br&gt;
Eventos e streaming;&lt;/p&gt;

&lt;h4&gt;
  
  
  🚀 Transforme a forma que os outros devs te veem:
&lt;/h4&gt;

&lt;p&gt;Esteja na vanguarda do desenvolvimento backend. As habilidades que você adquirirá são inestimáveis e altamente procuradas no mercado de trabalho para posições senior.&lt;/p&gt;

&lt;p&gt;✅ Acesse: &lt;a href="https://highperformanceschool.hotmart.host/" rel="noopener noreferrer"&gt;https://highperformanceschool.hotmart.host/&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>🇧🇷 Multi-Threading deixando a app mais lenta? como?</title>
      <dc:creator>italojs</dc:creator>
      <pubDate>Thu, 02 Nov 2023 21:31:03 +0000</pubDate>
      <link>https://dev.to/italojs/multi-threading-deixando-a-app-mais-lenta-como-2b4k</link>
      <guid>https://dev.to/italojs/multi-threading-deixando-a-app-mais-lenta-como-2b4k</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx4x2hykvcd04jbih27rj.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx4x2hykvcd04jbih27rj.jpg" alt="Image description" width="650" height="591"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Introdução 🧐
&lt;/h2&gt;

&lt;p&gt;O multi-threading é uma técnica comum para melhorar a performance de aplicativos, mas não é isenta de desafios. Este artigo se propõe a explorar, de maneira objetiva, as circunstâncias sob as quais o multi-threading pode não oferecer os benefícios esperados, utilizando um exemplo prático em Node.js.&lt;/p&gt;

&lt;h2&gt;
  
  
  Contextualização
&lt;/h2&gt;

&lt;p&gt;A capacidade de executar várias threads simultaneamente pode, teoricamente, reduzir o tempo de execução de tarefas complexas. No entanto, a realidade é que o overhead de gerenciamento de threads e a contenção de recursos podem impactar negativamente a performance.&lt;/p&gt;

&lt;h2&gt;
  
  
  Exemplo Prático 👩🏾‍💻
&lt;/h2&gt;

&lt;p&gt;Para ilustrar isso, consideremos um exemplo específico em Node.js, onde o objetivo é calcular números primos. O código abaixo foi utilizado para comparar a eficiência entre a execução single-threaded e multi-threaded.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
    &lt;span class="nx"&gt;Worker&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
    &lt;span class="nx"&gt;isMainThread&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
    &lt;span class="nx"&gt;parentPort&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
    &lt;span class="nx"&gt;workerData&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;worker_threads&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;performance&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;perf_hooks&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;// Função para encontrar números primos em um intervalo&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;findPrimes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;start&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;end&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;primes&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt;

    &lt;span class="c1"&gt;// Itera por todos os números no intervalo [start, end]&lt;/span&gt;
    &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;start&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="nx"&gt;end&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;isPrime&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="c1"&gt;// Verifica se o número 'i' é divisível por algum número &lt;/span&gt;
        &lt;span class="c1"&gt;// entre 2 e sua raiz quadrada&lt;/span&gt;
        &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;j&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;sqrt&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sqrt&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="nx"&gt;j&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="nx"&gt;sqrt&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;j&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;%&lt;/span&gt; &lt;span class="nx"&gt;j&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="nx"&gt;isPrime&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
                &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="c1"&gt;// Se 'i' for primo (e maior que 1), adiciona-o ao &lt;/span&gt;
        &lt;span class="c1"&gt;// array de primos&lt;/span&gt;
        &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;isPrime&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;primes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;primes&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Função para calcular números primos em um único thread&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;singleThread&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;max&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Marca o início da medição de tempo&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;stStart&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;performance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; 

    &lt;span class="c1"&gt;// Chama a função para encontrar números primos no &lt;/span&gt;
    &lt;span class="c1"&gt;// intervalo [2, max]&lt;/span&gt;
    &lt;span class="nf"&gt;findPrimes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;max&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 

     &lt;span class="c1"&gt;// Marca o final da medição de tempo&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;stEnd&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;performance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="c1"&gt;// Imprime o tempo decorrido em milissegundos&lt;/span&gt;
    &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Single-threaded:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;stEnd&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;stStart&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ms&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Função para calcular números primos em vários threads&lt;/span&gt;
&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;multiThread&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;max&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;numbersPerThread&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;threadCount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;mtStart&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;performance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// Marca o início da medição de tempo&lt;/span&gt;
    &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;completed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

    &lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;threadCount&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;start&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nx"&gt;numbersPerThread&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;end&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;i&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;threadCount&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;max&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;start&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;numbersPerThread&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

        &lt;span class="c1"&gt;// Cria um novo thread para calcular primos em um subintervalo&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;worker&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Worker&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;__filename&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;workerData&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;start&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;end&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;

        &lt;span class="c1"&gt;// Quando o thread conclui, incrementa o contador 'completed'&lt;/span&gt;
        &lt;span class="c1"&gt;// e verifica se todos os threads terminaram para medir o tempo total&lt;/span&gt;
        &lt;span class="nx"&gt;worker&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;on&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;message&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="nx"&gt;completed&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
            &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;completed&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="nx"&gt;threadCount&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="c1"&gt;// Marca o final da medição de tempo quando todos os threads terminam&lt;/span&gt;
                &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;mtEnd&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;performance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; 
                 &lt;span class="c1"&gt;// Imprime o tempo decorrido em milissegundos&lt;/span&gt;
                &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Multi-threaded:&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;mtEnd&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nx"&gt;mtStart&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;ms&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;});&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// Se estiver no thread principal&lt;/span&gt;
&lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;isMainThread&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Define o número máximo no intervalo&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;max&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="nx"&gt;e5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
    &lt;span class="c1"&gt;// Define o número total de threads a serem usadas&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;threadCount&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
    &lt;span class="c1"&gt;// Calcula quantos números cada thread deve processar&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;numbersPerThread&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;Math&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ceil&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;max&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nx"&gt;threadCount&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 
    &lt;span class="c1"&gt;// Calcula primos em um único thread&lt;/span&gt;
    &lt;span class="nf"&gt;singleThread&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;max&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

    &lt;span class="c1"&gt;// Calcula primos em múltiplos threads&lt;/span&gt;
    &lt;span class="nf"&gt;multiThread&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;max&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;numbersPerThread&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;threadCount&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// Se estiver em um thread&lt;/span&gt;
    &lt;span class="c1"&gt;// Recebe os dados de start e end do intervalo a ser processado&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;start&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;end&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;workerData&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; 
    &lt;span class="c1"&gt;// Chama a função para encontrar primos no intervalo especificado&lt;/span&gt;
    &lt;span class="nf"&gt;findPrimes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;start&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;end&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 
    &lt;span class="c1"&gt;// Envia uma mensagem de conclusão após o cálculo&lt;/span&gt;
    &lt;span class="nx"&gt;parentPort&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;postMessage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; 
&lt;span class="p"&gt;}&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Quando você executar o script completo, os resultados que você irá obter serão parecidos com:&lt;/p&gt;

&lt;p&gt;`&lt;br&gt;
Single-threaded: 17.95 ms&lt;/p&gt;

&lt;p&gt;Multi-threaded: 75.41 ms`&lt;/p&gt;

&lt;p&gt;😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱😱&lt;/p&gt;

&lt;p&gt;Contrariando as expectativas iniciais, a execução multi-threaded foi mais lenta.&lt;/p&gt;

&lt;h2&gt;
  
  
  Análise 👀
&lt;/h2&gt;

&lt;p&gt;A razão para isso pode ser atribuída ao overhead associado à criação e gerenciamento de threads. Cada thread requer recursos para ser iniciada, executada e, posteriormente, encerrada. Em tarefas que não são intensivamente paralelizáveis ou que são relativamente rápidas, o custo de gerenciamento de threads pode superar os benefícios do processamento paralelo.&lt;/p&gt;

&lt;p&gt;Além disso, a contenção de recursos, onde várias threads competem pelos mesmos recursos do sistema, pode levar a um aumento no tempo de execução, especialmente em sistemas com recursos limitados.&lt;/p&gt;

&lt;h2&gt;
  
  
  Considerações
&lt;/h2&gt;

&lt;p&gt;É essencial, portanto, avaliar a adequação do multi-threading para cada tarefa específica. Fatores como a natureza da tarefa, o ambiente de execução e os recursos disponíveis desempenham um papel crucial na determinação da eficácia do multi-threading.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Necessidade de Benchmarking
&lt;/h2&gt;

&lt;p&gt;Um passo essencial e muitas vezes subestimado na implementação do multi-threading é a realização de testes de benchmark rigorosos. Estes testes não são apenas uma formalidade, mas uma necessidade para avaliar objetivamente o impacto real na performance. Os desenvolvedores devem se equipar com dados concretos para tomar decisões informadas, evitando suposições e generalizações.&lt;/p&gt;

&lt;h2&gt;
  
  
  Volume de Dados: Um Fator Crítico
&lt;/h2&gt;

&lt;p&gt;O volume de dados é um elemento inseparável desta discussão. Testes de benchmark realizados com um volume de dados baixo podem não refletir a realidade operacional e, consequentemente, oferecer uma visão distorcida da eficácia do multi-threading. É imperativo que os testes sejam conduzidos em um ambiente que simule as condições reais de operação, com volumes de dados significativos.&lt;/p&gt;

&lt;p&gt;A razão para isso é clara: o overhead de gerenciamento de threads pode ser minimizado ou justificado quando lidamos com volumes de dados grandes. Em contrapartida, para volumes de dados menores, o custo de inicialização, execução e terminação de threads pode superar os benefícios percebidos, como observado em nosso exemplo prático.&lt;/p&gt;

&lt;h2&gt;
  
  
  Recomendação Final
&lt;/h2&gt;

&lt;p&gt;Portanto, a recomendação é clara. Antes de embarcar na jornada do multi-threading, invista tempo e recursos em testes de benchmark detalhados, com um volume de dados que reflita as condições reais de uso. Este passo é fundamental para garantir que a implementação de multi-threading traga benefícios tangíveis em termos de eficiência e performance, e para evitar surpresas indesejadas após a implementação.&lt;/p&gt;

&lt;p&gt;Ao adotar uma abordagem metódica, baseada em dados e adaptada às especificidades de cada aplicação e conjunto de dados, os desenvolvedores podem maximizar os benefícios do multi-threading, transformando-o em um aliado valioso na otimização contínua da performance de aplicativos.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fra9rgybkxatyaajhljyn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fra9rgybkxatyaajhljyn.png" alt="Image description" width="800" height="129"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Newsletter
&lt;/h2&gt;

&lt;p&gt;Gostou desse conteúdo? Aproveita pra se inscrever na nossa newsletter &lt;a href="https://highperformanceletterbr.substack.com/" rel="noopener noreferrer"&gt;https://highperformanceletterbr.substack.com/&lt;/a&gt;&lt;br&gt;
Postamos conteúdos sobre performance e otimização todas as semanas!&lt;/p&gt;

&lt;h2&gt;
  
  
  Primeiro curso de performance backend js do brasil(ou do mundo)
&lt;/h2&gt;

&lt;h4&gt;
  
  
  🚀 Domine o Desempenho Backend com JavaScript! 🚀
&lt;/h4&gt;

&lt;p&gt;🎓 Apresentamos o PRIMEIRO Curso de Performance Backend em JavaScript no Brasil! 🇧🇷&lt;/p&gt;

&lt;p&gt;🔥 Seja um dos pioneiros a explorar o mundo do desenvolvimento backend com foco em eficiência e velocidade. Este curso exclusivo é sua porta de entrada para se tornar um especialista em otimização e desempenho de aplicações JavaScript.&lt;/p&gt;

&lt;h4&gt;
  
  
  🌟 O Que Oferecemos:
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;Instrutores Especialista:&lt;/strong&gt; Aprenda com um profissional que atua com esse assunto no dia a dia.&lt;br&gt;
&lt;strong&gt;Conteúdo Avançado:&lt;/strong&gt; Desde fundamentos até técnicas avançadas de otimização.&lt;br&gt;
&lt;strong&gt;Projetos Práticos:&lt;/strong&gt; Coloque suas habilidades à prova com desafios reais.&lt;br&gt;
&lt;strong&gt;Comunidade e Networking:&lt;/strong&gt; Junte-se a uma comunidade vibrante de desenvolvedores.&lt;br&gt;
&lt;strong&gt;🛠️ Domine Ferramentas e Técnicas Essenciais:&lt;/strong&gt; Conteúdo prático sobre as melhores tools de monitoramento e análise de recursos&lt;/p&gt;

&lt;h4&gt;
  
  
  Análise de Performance;
&lt;/h4&gt;

&lt;p&gt;Diagnóstico;&lt;br&gt;
Otimização de Código;&lt;br&gt;
Gerenciamento Eficiente de Memória;&lt;br&gt;
Eventos e streaming;&lt;/p&gt;

&lt;h4&gt;
  
  
  🚀 Transforme a forma que os outros devs te veem:
&lt;/h4&gt;

&lt;p&gt;Esteja na vanguarda do desenvolvimento backend. As habilidades que você adquirirá são inestimáveis e altamente procuradas no mercado de trabalho para posições senior.&lt;/p&gt;

&lt;p&gt;✅ Acesse: &lt;a href="https://highperformanceschool.hotmart.host/" rel="noopener noreferrer"&gt;https://highperformanceschool.hotmart.host/&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>🇧🇷 Otimizando buscas em mais de 1000x de maneira rápida e fácil</title>
      <dc:creator>italojs</dc:creator>
      <pubDate>Thu, 02 Nov 2023 21:30:54 +0000</pubDate>
      <link>https://dev.to/italojs/otimizando-buscas-em-mais-de-1000x-de-maneira-rapida-e-facil-449o</link>
      <guid>https://dev.to/italojs/otimizando-buscas-em-mais-de-1000x-de-maneira-rapida-e-facil-449o</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjzk0qle13qjamxll1six.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjzk0qle13qjamxll1six.png" alt="Image description" width="650" height="591"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;code&gt;Map.get&lt;/code&gt; vs &lt;code&gt;Array.find&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Quer fazer a boa no seu time e trazer uma baita performance pra sua aplicação com pouco esforço? se liga nessa dica! 🤯&lt;/p&gt;

&lt;p&gt;De um ctrl+f e busque pelo #find e se possível os substitua por uma estrutura de dados #Map&lt;/p&gt;

&lt;h2&gt;
  
  
  Sabe por que? 🧐
&lt;/h2&gt;

&lt;h3&gt;
  
  
  BuscaLinear (find):
&lt;/h3&gt;

&lt;p&gt;Percorre o array objeto por objeto até encontrar o que procura.&lt;/p&gt;

&lt;p&gt;Complexidade de tempo: &lt;code&gt;O(n)&lt;/code&gt;, onde n é o número de objetos no array.&lt;/p&gt;

&lt;h3&gt;
  
  
  Índices:
&lt;/h3&gt;

&lt;p&gt;Complexidade de tempo: Aproximadamente &lt;code&gt;O(1)&lt;/code&gt; (em média, para a maioria dos casos).&lt;/p&gt;

&lt;p&gt;Para buscas frequentes, pode ser benéfico usar índices com base na propriedade que você está pesquisando.&lt;/p&gt;

&lt;h4&gt;
  
  
  🔎 Busca linear: #find
&lt;/h4&gt;

&lt;p&gt;As formas mais tradicionais de busca em arrays no #javascript é o #find, mas ele apesar de muito útil, ele tem um problema, ele é linear &lt;code&gt;O(n)&lt;/code&gt;, onde pode percorrer todo o seu arrau até encontrar o que deseja.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;const product = products.find(p =&amp;gt; p.id === 1);&lt;/code&gt;&lt;/p&gt;

&lt;h4&gt;
  
  
  ⚡️ Índices: #Map
&lt;/h4&gt;

&lt;p&gt;Uma forma de otimizar muitos cenários de busca é usar a estrutura de dados #Map&lt;/p&gt;

&lt;p&gt;Nesse &lt;a href="//rb.gy/ljb89"&gt;link&lt;/a&gt; eu deixo um #benchmark com um #exemplo de busca de produtos onde você pode ver um resultaod semelhante a esse aqui :&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Busca Linear: 12.647450000047684ms

Busca via Map: 0.005816996097564697ms
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;&lt;br&gt;
`&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusão
&lt;/h2&gt;

&lt;p&gt;Usar a estrutura de dados correta na hora de fazer uma busca pode impactar muito no tempo de resposta e consumo de recurso da sua aplicação, claro que nem sempre iremos poder usar uma estrutura de dados do tipo &lt;code&gt;Map&lt;/code&gt; ou &lt;code&gt;Object&lt;/code&gt;, mas tenho certeza que em muitos casos você consegue substituir a criaçao da sua lista por um Map e ganhar um baita ganho de performence!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fra9rgybkxatyaajhljyn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fra9rgybkxatyaajhljyn.png" alt="Image description" width="800" height="129"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Newsletter
&lt;/h2&gt;

&lt;p&gt;Gostou desse conteúdo? Aproveita pra se inscrever na nossa newsletter &lt;a href="https://highperformanceletterbr.substack.com/" rel="noopener noreferrer"&gt;https://highperformanceletterbr.substack.com/&lt;/a&gt;&lt;br&gt;
Postamos conteúdos sobre performance e otimização todas as semanas!&lt;/p&gt;

&lt;h2&gt;
  
  
  Primeiro curso de performance backend js do brasil(ou do mundo)
&lt;/h2&gt;

&lt;h4&gt;
  
  
  🚀 Domine o Desempenho Backend com JavaScript! 🚀
&lt;/h4&gt;

&lt;p&gt;🎓 Apresentamos o PRIMEIRO Curso de Performance Backend em JavaScript no Brasil! 🇧🇷&lt;/p&gt;

&lt;p&gt;🔥 Seja um dos pioneiros a explorar o mundo do desenvolvimento backend com foco em eficiência e velocidade. Este curso exclusivo é sua porta de entrada para se tornar um especialista em otimização e desempenho de aplicações JavaScript.&lt;/p&gt;

&lt;h4&gt;
  
  
  🌟 O Que Oferecemos:
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;Instrutores Especialista:&lt;/strong&gt; Aprenda com um profissional que atua com esse assunto no dia a dia.&lt;br&gt;
&lt;strong&gt;Conteúdo Avançado:&lt;/strong&gt; Desde fundamentos até técnicas avançadas de otimização.&lt;br&gt;
&lt;strong&gt;Projetos Práticos:&lt;/strong&gt; Coloque suas habilidades à prova com desafios reais.&lt;br&gt;
&lt;strong&gt;Comunidade e Networking:&lt;/strong&gt; Junte-se a uma comunidade vibrante de desenvolvedores.&lt;br&gt;
&lt;strong&gt;🛠️ Domine Ferramentas e Técnicas Essenciais:&lt;/strong&gt; Conteúdo prático sobre as melhores tools de monitoramento e análise de recursos&lt;/p&gt;

&lt;h4&gt;
  
  
  Análise de Performance;
&lt;/h4&gt;

&lt;p&gt;Diagnóstico;&lt;br&gt;
Otimização de Código;&lt;br&gt;
Gerenciamento Eficiente de Memória;&lt;br&gt;
Eventos e streaming;&lt;/p&gt;

&lt;h4&gt;
  
  
  🚀 Transforme a forma que os outros devs te veem:
&lt;/h4&gt;

&lt;p&gt;Esteja na vanguarda do desenvolvimento backend. As habilidades que você adquirirá são inestimáveis e altamente procuradas no mercado de trabalho para posições senior.&lt;/p&gt;

&lt;p&gt;✅ Acesse: &lt;a href="https://highperformanceschool.hotmart.host/" rel="noopener noreferrer"&gt;https://highperformanceschool.hotmart.host/&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>🇧🇷 Como Evitar Vazamentos de Memória das closures</title>
      <dc:creator>italojs</dc:creator>
      <pubDate>Thu, 02 Nov 2023 21:30:48 +0000</pubDate>
      <link>https://dev.to/italojs/como-evitar-vazamentos-de-memoria-das-closures-1jla</link>
      <guid>https://dev.to/italojs/como-evitar-vazamentos-de-memoria-das-closures-1jla</guid>
      <description>&lt;h2&gt;
  
  
  Vazamentos de Memória
&lt;/h2&gt;

&lt;p&gt;Vazamentos de memória acontecem quando um programa usa mais memória do que deveria e não a libera de volta para o sistema. Agora, com essa ideia em mente, vamos falar sobre como isso pode acontecer quando usamos closures no Node.js.&lt;/p&gt;

&lt;h2&gt;
  
  
  O que são Closures?
&lt;/h2&gt;

&lt;p&gt;Closures são funções em JavaScript que retêm acesso às variáveis de funções pai onde elas foram criada. Isso significa que um closure pode acessar variáveis de uma funções externas que já terminaram sua execução.&lt;/p&gt;

&lt;h2&gt;
  
  
  Exemplo de Código com Vazamento de Memória ⚠️
&lt;/h2&gt;

&lt;p&gt;Vamos usar um exemplo onde criamos uma função que retorna informações de um produto baseado em seu ID.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;infoProduto&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;produto&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;nome&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Produto &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;detalhes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5000000&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;fill&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;detalhe&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;produto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;nome&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;produto5&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;infoProduto&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nf"&gt;produto5&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// Logará "Produto 5"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Neste exemplo, a função &lt;code&gt;infoProduto(id)&lt;/code&gt; cria um objeto de produto que é mantido na memória pelo closure, mesmo após a execução da função, levando a um possível vazamento de memória se muitos produtos forem carregados.&lt;/p&gt;

&lt;h2&gt;
  
  
  Como Resolver o Problema ✅
&lt;/h2&gt;

&lt;p&gt;Podemos ajustar o código para garantir que apenas as informações necessárias sejam mantidas e que o restante seja liberado.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;infoProduto&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
     &lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;produto&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;nome&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Produto &lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nx"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;detalhes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5000000&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;fill&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;detalhe&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
     &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;produto&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;
     &lt;span class="nx"&gt;produto&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="c1"&gt;// libera objeto grande da memoria&lt;/span&gt;

    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;nome&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;produto5&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;infoProduto&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nf"&gt;produto5&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt; &lt;span class="c1"&gt;// Logará "Produto 5"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Agora, o array pesado detalhes é liberado da memória, enquanto o closure mantém referência apenas ao nome do produto, que é o que realmente precisamos para essa operação.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusão 🎓
&lt;/h2&gt;

&lt;p&gt;Closures são uma ferramenta poderosa, mas é preciso manejá-los com cuidado para evitar vazamentos de memória. Ser consciente das referências que seus closures mantêm pode ajudar a manter sua aplicação Node.js rápida e eficiente.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fra9rgybkxatyaajhljyn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fra9rgybkxatyaajhljyn.png" alt="Image description" width="800" height="129"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Newsletter
&lt;/h2&gt;

&lt;p&gt;Gostou desse conteúdo? Aproveita pra se inscrever na nossa newsletter &lt;a href="https://highperformanceletterbr.substack.com/" rel="noopener noreferrer"&gt;https://highperformanceletterbr.substack.com/&lt;/a&gt;&lt;br&gt;
Postamos conteúdos sobre performance e otimização todas as semanas!&lt;/p&gt;

&lt;h2&gt;
  
  
  Primeiro curso de performance backend js do brasil(ou do mundo)
&lt;/h2&gt;

&lt;h4&gt;
  
  
  🚀 Domine o Desempenho Backend com JavaScript! 🚀
&lt;/h4&gt;

&lt;p&gt;🎓 Apresentamos o PRIMEIRO Curso de Performance Backend em JavaScript no Brasil! 🇧🇷&lt;/p&gt;

&lt;p&gt;🔥 Seja um dos pioneiros a explorar o mundo do desenvolvimento backend com foco em eficiência e velocidade. Este curso exclusivo é sua porta de entrada para se tornar um especialista em otimização e desempenho de aplicações JavaScript.&lt;/p&gt;

&lt;h4&gt;
  
  
  🌟 O Que Oferecemos:
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;Instrutores Especialista:&lt;/strong&gt; Aprenda com um profissional que atua com esse assunto no dia a dia.&lt;br&gt;
&lt;strong&gt;Conteúdo Avançado:&lt;/strong&gt; Desde fundamentos até técnicas avançadas de otimização.&lt;br&gt;
&lt;strong&gt;Projetos Práticos:&lt;/strong&gt; Coloque suas habilidades à prova com desafios reais.&lt;br&gt;
&lt;strong&gt;Comunidade e Networking:&lt;/strong&gt; Junte-se a uma comunidade vibrante de desenvolvedores.&lt;br&gt;
&lt;strong&gt;🛠️ Domine Ferramentas e Técnicas Essenciais:&lt;/strong&gt; Conteúdo prático sobre as melhores tools de monitoramento e análise de recursos&lt;/p&gt;

&lt;h4&gt;
  
  
  Análise de Performance;
&lt;/h4&gt;

&lt;p&gt;Diagnóstico;&lt;br&gt;
Otimização de Código;&lt;br&gt;
Gerenciamento Eficiente de Memória;&lt;br&gt;
Eventos e streaming;&lt;/p&gt;

&lt;h4&gt;
  
  
  🚀 Transforme a forma que os outros devs te veem:
&lt;/h4&gt;

&lt;p&gt;Esteja na vanguarda do desenvolvimento backend. As habilidades que você adquirirá são inestimáveis e altamente procuradas no mercado de trabalho para posições senior.&lt;/p&gt;

&lt;p&gt;✅ Acesse: &lt;a href="https://highperformanceschool.hotmart.host/" rel="noopener noreferrer"&gt;https://highperformanceschool.hotmart.host/&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>🇧🇷 A Ineficiência do Regex e Como Otimizá-lo</title>
      <dc:creator>italojs</dc:creator>
      <pubDate>Thu, 02 Nov 2023 21:29:58 +0000</pubDate>
      <link>https://dev.to/italojs/a-ineficiencia-do-regex-e-como-otimiza-lo-4hi</link>
      <guid>https://dev.to/italojs/a-ineficiencia-do-regex-e-como-otimiza-lo-4hi</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4q9bhlnan7bbjs3ke3ce.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4q9bhlnan7bbjs3ke3ce.jpg" alt="Image description" width="650" height="591"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Regex, o vilão da performance
&lt;/h2&gt;

&lt;p&gt;Você sabia que expressões regulares (regex) podem ser extremamente ineficientes em certos cenários? Isso ocorre principalmente devido a '&lt;strong&gt;backtracking&lt;/strong&gt;' excessivo, que pode levar a tempos de execução exponenciais!&lt;/p&gt;

&lt;p&gt;Por exemplo, considere o regex &lt;code&gt;(a+)+b&lt;/code&gt; e a string &lt;code&gt;a...a!&lt;/code&gt; (onde ... são milhares de 'a'). Esse regex tentará diversas combinações antes de falhar, tornando-se muito lento.&lt;/p&gt;

&lt;p&gt;Mas a boa notícia é: o V8 (motor JavaScript do Chrome e Node.js) introduziu uma flag experimental para lidar com isso: &lt;code&gt;--enable-experimental-regexp_engine-on-excessive-backtracks.&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  🔍  Teste Prático:
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;regex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="se"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;a+&lt;/span&gt;&lt;span class="se"&gt;)&lt;/span&gt;&lt;span class="sr"&gt;+b/&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;input&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;a&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;repeat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5000&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;time&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Regex Sem Otimização&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;input&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;regex&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;timeEnd&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Regex Sem Otimização&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;o resultado será algo em torno de &lt;code&gt;70.885ms&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Para usar a flag no Node.js:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;node &lt;span class="nt"&gt;--enable-experimental-regexp_engine-on-excessive-backtracks&lt;/span&gt; seuScript.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Com isso, ao detectar backtracks excessivos, o V8 mudará para um mecanismo de regex diferente e mais eficiente!&lt;/p&gt;

&lt;p&gt;Aqui o resultado caiu pra &lt;code&gt;1.977ms&lt;/code&gt; 😲&lt;/p&gt;

&lt;p&gt;Lembre-se: regex é uma ferramenta poderosa, mas com grandes poderes vêm grandes responsabilidades. Use com sabedoria e sempre monitore o desempenho!&lt;/p&gt;

&lt;p&gt;Olhe &lt;a href="https://v8.dev/blog/non-backtracking-regexp" rel="noopener noreferrer"&gt;https://v8.dev/blog/non-backtracking-regexp&lt;/a&gt; para mais informações.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fra9rgybkxatyaajhljyn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fra9rgybkxatyaajhljyn.png" alt="Image description" width="800" height="129"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Newsletter
&lt;/h2&gt;

&lt;p&gt;Gostou desse conteúdo? Aproveita pra se inscrever na nossa newsletter &lt;a href="https://highperformanceletterbr.substack.com/" rel="noopener noreferrer"&gt;https://highperformanceletterbr.substack.com/&lt;/a&gt;&lt;br&gt;
Postamos conteúdos sobre performance e otimização todas as semanas!&lt;/p&gt;

&lt;h2&gt;
  
  
  Primeiro curso de performance backend js do brasil(ou do mundo)
&lt;/h2&gt;

&lt;h4&gt;
  
  
  🚀 Domine o Desempenho Backend com JavaScript! 🚀
&lt;/h4&gt;

&lt;p&gt;🎓 Apresentamos o PRIMEIRO Curso de Performance Backend em JavaScript no Brasil! 🇧🇷&lt;/p&gt;

&lt;p&gt;🔥 Seja um dos pioneiros a explorar o mundo do desenvolvimento backend com foco em eficiência e velocidade. Este curso exclusivo é sua porta de entrada para se tornar um especialista em otimização e desempenho de aplicações JavaScript.&lt;/p&gt;

&lt;h4&gt;
  
  
  🌟 O Que Oferecemos:
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;Instrutores Especialista:&lt;/strong&gt; Aprenda com um profissional que atua com esse assunto no dia a dia.&lt;br&gt;
&lt;strong&gt;Conteúdo Avançado:&lt;/strong&gt; Desde fundamentos até técnicas avançadas de otimização.&lt;br&gt;
&lt;strong&gt;Projetos Práticos:&lt;/strong&gt; Coloque suas habilidades à prova com desafios reais.&lt;br&gt;
&lt;strong&gt;Comunidade e Networking:&lt;/strong&gt; Junte-se a uma comunidade vibrante de desenvolvedores.&lt;br&gt;
&lt;strong&gt;🛠️ Domine Ferramentas e Técnicas Essenciais:&lt;/strong&gt; Conteúdo prático sobre as melhores tools de monitoramento e análise de recursos&lt;/p&gt;

&lt;h4&gt;
  
  
  Análise de Performance;
&lt;/h4&gt;

&lt;p&gt;Diagnóstico;&lt;br&gt;
Otimização de Código;&lt;br&gt;
Gerenciamento Eficiente de Memória;&lt;br&gt;
Eventos e streaming;&lt;/p&gt;

&lt;h4&gt;
  
  
  🚀 Transforme a forma que os outros devs te veem:
&lt;/h4&gt;

&lt;p&gt;Esteja na vanguarda do desenvolvimento backend. As habilidades que você adquirirá são inestimáveis e altamente procuradas no mercado de trabalho para posições senior.&lt;/p&gt;

&lt;p&gt;✅ Acesse: &lt;a href="https://highperformanceschool.hotmart.host/" rel="noopener noreferrer"&gt;https://highperformanceschool.hotmart.host/&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>🇧🇷 FlameGraphs, uma introdução</title>
      <dc:creator>italojs</dc:creator>
      <pubDate>Thu, 26 Oct 2023 14:19:00 +0000</pubDate>
      <link>https://dev.to/italojs/flamegraphs-uma-introducao-1n67</link>
      <guid>https://dev.to/italojs/flamegraphs-uma-introducao-1n67</guid>
      <description>&lt;h2&gt;
  
  
  FlameGraphs
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvpzqo4gg9wvmpjxmbb3c.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvpzqo4gg9wvmpjxmbb3c.png" alt="Image description" width="800" height="451"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Ei, devs! 🚀 Se vocês estão procurando uma forma de identificar gargalos de performance nos seus projetos Node.js, eu tenho uma dica quente para vocês: &lt;strong&gt;Flamegraphs&lt;/strong&gt;!&lt;/p&gt;

&lt;p&gt;🔍 O que é um Flamegraph? Um Flamegraph é uma visualização que representa a pilha de chamadas (stack trace) de um programa em execução. Cada barra horizontal representa um arquivo ou função, e sua largura indica o tempo que essa arquivo/função consumiu. Isso pode ser extremamente útil para identificar onde seu código está gastando mais tempo!&lt;/p&gt;

&lt;h2&gt;
  
  
  🛠 Como criar um Flamegraph no Node.js?
&lt;/h2&gt;

&lt;p&gt;Rode sua aplicação com &lt;code&gt;npx 0x index.js&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Feche a aplicação e 0x irá gerar um arquivo HTML com um Flamegraph interativo. Você pode abri-lo em seu navegador e visualizar as áreas do código que consumiram mais tempo.&lt;/p&gt;

&lt;h2&gt;
  
  
  💡 Como se beneficiar disso?
&lt;/h2&gt;

&lt;p&gt;**&lt;br&gt;
Identificação Rápida:** Com um olhar, você pode identificar as funções que estão consumindo mais tempo e se tornar mais eficaz ao otimizar.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Melhoria Contínua:&lt;/strong&gt; Ao fazer ajustes no código e comparar os Flamegraphs antes e depois, você tem uma visão clara do impacto das suas mudanças.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Performance em Produção:&lt;/strong&gt; Você pode até usar ferramentas, como o 0x, para criar Flamegraphs de aplicativos Node.js em produção.&lt;/p&gt;

&lt;h2&gt;
  
  
  🔑 Conclusão
&lt;/h2&gt;

&lt;p&gt;Se você está comprometido em otimizar a performance do seu projeto, o Flamegraph é uma ferramenta essencial. Não só ajuda a identificar os gargalos, mas também a entender a interação entre diferentes partes do código.&lt;/p&gt;

&lt;p&gt;Então, da próxima vez que você se deparar com um desafio de performance, 🕶️ coloque seus óculos de detetive e use o Flamegraph para iluminar seu caminho!&lt;/p&gt;

&lt;p&gt;E você? Já usou o #Flamegraph em seus projetos Node.js? Compartilhe sua experiência! #NodeJS #Optimization &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fra9rgybkxatyaajhljyn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fra9rgybkxatyaajhljyn.png" alt="Image description" width="800" height="129"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Newsletter
&lt;/h2&gt;

&lt;p&gt;Gostou desse conteúdo? Aproveita pra se inscrever na nossa newsletter &lt;a href="https://highperformanceletterbr.substack.com/" rel="noopener noreferrer"&gt;https://highperformanceletterbr.substack.com/&lt;/a&gt;&lt;br&gt;
Postamos conteúdos sobre performance e otimização todas as semanas!&lt;/p&gt;

&lt;h2&gt;
  
  
  Primeiro curso de performance backend js do brasil(ou do mundo)
&lt;/h2&gt;

&lt;h4&gt;
  
  
  🚀 Domine o Desempenho Backend com JavaScript! 🚀
&lt;/h4&gt;

&lt;p&gt;🎓 Apresentamos o PRIMEIRO Curso de Performance Backend em JavaScript no Brasil! 🇧🇷&lt;/p&gt;

&lt;p&gt;🔥 Seja um dos pioneiros a explorar o mundo do desenvolvimento backend com foco em eficiência e velocidade. Este curso exclusivo é sua porta de entrada para se tornar um especialista em otimização e desempenho de aplicações JavaScript.&lt;/p&gt;

&lt;h4&gt;
  
  
  🌟 O Que Oferecemos:
&lt;/h4&gt;

&lt;p&gt;&lt;strong&gt;Instrutores Especialista:&lt;/strong&gt; Aprenda com um profissional que atua com esse assunto no dia a dia.&lt;br&gt;
&lt;strong&gt;Conteúdo Avançado:&lt;/strong&gt; Desde fundamentos até técnicas avançadas de otimização.&lt;br&gt;
&lt;strong&gt;Projetos Práticos:&lt;/strong&gt; Coloque suas habilidades à prova com desafios reais.&lt;br&gt;
&lt;strong&gt;Comunidade e Networking:&lt;/strong&gt; Junte-se a uma comunidade vibrante de desenvolvedores.&lt;br&gt;
&lt;strong&gt;🛠️ Domine Ferramentas e Técnicas Essenciais:&lt;/strong&gt; Conteúdo prático sobre as melhores tools de monitoramento e análise de recursos&lt;/p&gt;

&lt;h4&gt;
  
  
  Análise de Performance;
&lt;/h4&gt;

&lt;p&gt;Diagnóstico;&lt;br&gt;
Otimização de Código;&lt;br&gt;
Gerenciamento Eficiente de Memória;&lt;br&gt;
Eventos e streaming;&lt;/p&gt;

&lt;h4&gt;
  
  
  🚀 Transforme a forma que os outros devs te veem:
&lt;/h4&gt;

&lt;p&gt;Esteja na vanguarda do desenvolvimento backend. As habilidades que você adquirirá são inestimáveis e altamente procuradas no mercado de trabalho para posições senior.&lt;/p&gt;

&lt;p&gt;✅ Acesse: &lt;a href="https://highperformanceschool.hotmart.host/" rel="noopener noreferrer"&gt;https://highperformanceschool.hotmart.host/&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Saving time when starting a project</title>
      <dc:creator>italojs</dc:creator>
      <pubDate>Mon, 11 Oct 2021 12:30:54 +0000</pubDate>
      <link>https://dev.to/italojs/saving-time-when-starting-a-project-c9n</link>
      <guid>https://dev.to/italojs/saving-time-when-starting-a-project-c9n</guid>
      <description>&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fndgfvxujtqsah1641ju0.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fndgfvxujtqsah1641ju0.jpg" alt="clock on the plate" width="800" height="450"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How much time do you spend setting up the basis of a new project?
&lt;/h2&gt;

&lt;p&gt;No matter how simple or complex is your service, we have to build the base, that basic base: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create entities&lt;/li&gt;
&lt;li&gt;Create the folder structure&lt;/li&gt;
&lt;li&gt;Then create some repositories&lt;/li&gt;
&lt;li&gt;Some usecases/services for each entity&lt;/li&gt;
&lt;li&gt;Configure the api, routes, midlewares&lt;/li&gt;
&lt;li&gt;etc&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Come oooooooonnnn, who likes to do this?&lt;/p&gt;

&lt;h2&gt;
  
  
  How to save time configuring the base's project?
&lt;/h2&gt;

&lt;p&gt;Today we will create a Postgres-based api with two presentation layers: Graphql and REST in less then 1 minute.&lt;/p&gt;

&lt;p&gt;For today's dish, we use the ingredients: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://herbsjs.org/docs/" rel="noopener noreferrer"&gt;@herbs/herbs&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/herbsjs/herbs-cli" rel="noopener noreferrer"&gt;Herbs CLI&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To start our "fast project" we need first of all to modeling our base. Imagine we are creating an e-commerce backend app, in an e-commerce we would have 3 entities: &lt;strong&gt;user&lt;/strong&gt;, &lt;strong&gt;product&lt;/strong&gt; and &lt;strong&gt;sale&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpta9uiq58tocdm26ww91.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpta9uiq58tocdm26ww91.png" alt="black boy thinking" width="800" height="536"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The first step to build our project will be to create the entities using the &lt;a class="mentioned-user" href="https://dev.to/herbs"&gt;@herbs&lt;/a&gt;/herbs lib that will provide some metadata to build everything else based in our entities: usecases, repositories, migrations, graphql, rest etc.&lt;/p&gt;

&lt;p&gt;Building an entity with Herbs is very simple, just import the &lt;code&gt;entity&lt;/code&gt; module and pass the parameters &lt;code&gt;entity("entityName", { fields })&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;All our entities will be inside a folder &lt;code&gt;/entities&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// entities/customer.js&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;entity&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;field&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@herbsjs/herbs&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;


&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Customer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;entity&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Customer&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;field&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="na"&gt;cellphone&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;field&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;field&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="na"&gt;gender&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;field&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="na"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;field&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="na"&gt;discountClub&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;field&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Boolean&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="na"&gt;city&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;field&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="na"&gt;state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;field&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="na"&gt;address&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;field&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="na"&gt;zipcode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;field&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="na"&gt;lastName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;field&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="na"&gt;fisrtName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;field&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="na"&gt;civilDocument&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;field&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Customer&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After create our simple entity, what about add some validations? To do this with Herbs is very simple too, just add an option object with some rules as second parameter &lt;code&gt;field(Type, { options })&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If you'd like to see more about validation types, you can check out the Herbs documentation &lt;a href="https://herbsjs.org/docs/entity/validation/" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// entities/customer.js&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;entity&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;field&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@herbsjs/herbs&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;requiredString&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;validation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;presence&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;length&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;minimum&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;maximum&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;255&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Customer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;entity&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Customer&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;field&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Optional option&lt;/span&gt;
        &lt;span class="na"&gt;validation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;presence&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;numericality&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="na"&gt;greaterThan&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="na"&gt;onlyInteger&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}),&lt;/span&gt;
    &lt;span class="na"&gt;cellphone&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;field&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;validation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;format&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sr"&gt;/^&lt;/span&gt;&lt;span class="se"&gt;\+[&lt;/span&gt;&lt;span class="sr"&gt;1-9&lt;/span&gt;&lt;span class="se"&gt;]{1}[&lt;/span&gt;&lt;span class="sr"&gt;0-9&lt;/span&gt;&lt;span class="se"&gt;]{3,14}&lt;/span&gt;&lt;span class="sr"&gt;$/&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}),&lt;/span&gt;
    &lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;field&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;validation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;requiredString&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;validation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; 
    &lt;span class="p"&gt;}),&lt;/span&gt;
    &lt;span class="na"&gt;gender&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;field&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;validation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;requiredString&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;validation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;contains&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;allowed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;M&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;W&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;X&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; 
    &lt;span class="p"&gt;}),&lt;/span&gt;
    &lt;span class="na"&gt;age&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;field&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="na"&gt;discountClub&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;field&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Boolean&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="na"&gt;city&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;field&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;requiredString&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="na"&gt;state&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;field&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;requiredString&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="na"&gt;address&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;field&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;requiredString&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="na"&gt;zipcode&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;field&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;requiredString&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="na"&gt;lastName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;field&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;requiredString&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="na"&gt;fisrtName&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;field&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;requiredString&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="na"&gt;civilDocument&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;field&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;requiredString&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Customer&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// entities/product.js&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;entity&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;field&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@herbsjs/herbs&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;required&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;validation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;presence&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;requiredString&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;validation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="p"&gt;...&lt;/span&gt;&lt;span class="nx"&gt;required&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;validation&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;length&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;minimum&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;maximum&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;255&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;entity&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Product&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;field&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Optional option&lt;/span&gt;
        &lt;span class="na"&gt;validation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;presence&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;numericality&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="na"&gt;greaterThan&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="na"&gt;onlyInteger&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}),&lt;/span&gt;
    &lt;span class="na"&gt;limitDiscount&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;field&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
        &lt;span class="na"&gt;validation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; 
            &lt;span class="na"&gt;greaterThan&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;lessThan&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;onlyInteger&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; 
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}),&lt;/span&gt;
    &lt;span class="na"&gt;size&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;  &lt;span class="nf"&gt;field&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;required&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="na"&gt;stock&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;field&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;required&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="na"&gt;color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;field&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;required&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;field&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;requiredString&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="na"&gt;brand&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;field&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;requiredString&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="na"&gt;category&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;field&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;requiredString&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;field&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;requiredString&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="na"&gt;price&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;field&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;validation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;presence&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;greaterThan&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// entities/sale.js&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;entity&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;field&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@herbsjs/herbs&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;required&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;validation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;presence&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;module&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;exports&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;entity&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Sale&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;field&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="c1"&gt;// Optional option&lt;/span&gt;
        &lt;span class="na"&gt;validation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;presence&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;numericality&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="na"&gt;greaterThan&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
                &lt;span class="na"&gt;onlyInteger&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}),&lt;/span&gt;
    &lt;span class="na"&gt;productID&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;field&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;required&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="na"&gt;customerID&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;field&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;required&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="na"&gt;total&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;field&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;required&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="na"&gt;quantity&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nf"&gt;field&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;required&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the end we will have this result:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2b3rur4fva927rk2b8c0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F2b3rur4fva927rk2b8c0.png" alt="Alt Text" width="358" height="200"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  generating the project
&lt;/h2&gt;

&lt;p&gt;Finally our dreamed come to be true, where we generated our project based on our entities!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmwpi3yo1yay5l414hyoo.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmwpi3yo1yay5l414hyoo.gif" alt="amazing jack" width="498" height="278"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The Herbs CLI was created to help you create and maintain your project in a faster way when you uses the entire Herbs ecosystem.&lt;/p&gt;

&lt;p&gt;When we type &lt;code&gt;herbs new&lt;/code&gt; herbs will ask a some things about your project to generate our project.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffxx0ibveg0sjaxpy2mhq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffxx0ibveg0sjaxpy2mhq.png" alt="cli options" width="800" height="263"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Note the last question is an &lt;strong&gt;optional&lt;/strong&gt; question, if you don't specify your entities folder path, the project will be generated based on a default “User” entity, but we're not here to generate a “boilerplate” are we? So let's fill it in with out entities folder path.&lt;/p&gt;

&lt;p&gt;When you press Enter our app will be generated and you will find a folder with the project name.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7erhmuab9sa7ser0nwdv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7erhmuab9sa7ser0nwdv.png" alt="Generated folder structure" width="751" height="1650"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;look this! How much automatically generated stuff! How much time we saved here! Very satisfying! Note that the entire project is done: migrations, repositories, api(graphl and rest) create, read, update and delete usecases and everything else!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp10sophlm5c9o52iteua.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fp10sophlm5c9o52iteua.gif" alt="wow gif" width="498" height="374"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Explaining the project
&lt;/h2&gt;

&lt;p&gt;Okay, but what we built here? &lt;/p&gt;

&lt;p&gt;The diagram below shows a little bit how the project is organized (which you can check on the Herbs &lt;a href="https://herbsjs.org" rel="noopener noreferrer"&gt;doc home&lt;/a&gt;), the generated app is based on the clean architecture, there we have our &lt;code&gt;domain&lt;/code&gt; with our &lt;code&gt;entities&lt;/code&gt; and our &lt;code&gt;usecases&lt;/code&gt;, around from this we have the rest of our application (api, database, clients, documentation, etc.) and in all these other layers use the herbsjs "glues" that read the entities and usecases metadatas to facilitate our day-a-day software development, &lt;code&gt;remembering that no glue is a code generator&lt;/code&gt;, are just tools to speed up the development of your code.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyy67ynm7klnwo5111ien.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fyy67ynm7klnwo5111ien.png" alt="Herbs archtecture ecosystem" width="800" height="405"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;now let's be a little practical and talk about the our project's folder structure.&lt;/p&gt;

&lt;p&gt;NOTE: remembering that architecture is not a folder structure!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb0l57zols7j71t18bma3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fb0l57zols7j71t18bma3.png" alt="Folder structure" width="227" height="513"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Inside &lt;code&gt;domain&lt;/code&gt; folder we have our entities and usecases that provide some metadata as usecase's name, request and output schema, entity fields, types and more.&lt;/p&gt;

&lt;p&gt;Above we have herbs2gql glue example, the &lt;a href="https://herbsjs.org/docs/glues/herbs2gql" rel="noopener noreferrer"&gt;herbs2gql&lt;/a&gt; receive a usecase and a resolver so it return the Graphql schemas string. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwq8mu86lqgdlqycohd00.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwq8mu86lqgdlqycohd00.png" alt="Glue example" width="800" height="360"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The concept of “glue” runs throughout the application, from the presentation layer to the repository, remembering it isn't mandatory and this libraries are only meant to help you develop and maintain your project. :)&lt;/p&gt;

&lt;p&gt;Inside our usecases we can see that exists not anly a simples creation, but there have a validations too, so it means the generated project is done to production! &lt;/p&gt;

&lt;h2&gt;
  
  
  Running the project
&lt;/h2&gt;

&lt;p&gt;Once we've generated and understood the code, let's put this code to work! Just give the &lt;code&gt;npm run start&lt;/code&gt; command and watch the magic happen. Note that all REST routes are printed on the terminal and that they are all based on our usecases.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F57l28r175zho75b0ep0u.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F57l28r175zho75b0ep0u.png" alt="REST terminal routes" width="800" height="457"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Also, if you open your browser on the &lt;code&gt;http://localhost:3000/graphql&lt;/code&gt; route you will see all generated schemas for the Graphql presentation layer with the Graphql playground documentation&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flzfd9p9f98bfsa07fhg8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flzfd9p9f98bfsa07fhg8.png" alt="graphql playground" width="800" height="290"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Beside everything we generated here, the herbs generates a dynamic documentation too, so imagine you'll never need to worry about your API's documentation since everything will be automatically generated via usecase metadata and your Readme.md file! To do that we use the &lt;a href="https://herbsjs.org/docs/glues/herbsshelf" rel="noopener noreferrer"&gt;HerbsShelf&lt;/a&gt; glue&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwmahdqukp9fszjbx2cho.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwmahdqukp9fszjbx2cho.png" alt="Herbsshlef" width="800" height="390"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So now just implement your business rule and go up to production!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcgn9rrixd8lh0mfq53z3.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcgn9rrixd8lh0mfq53z3.gif" alt="The end gif" width="480" height="480"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
