<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Diego Juliao</title>
    <description>The latest articles on Forem by Diego Juliao (@dianjuar).</description>
    <link>https://forem.com/dianjuar</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%2F235220%2F5d4c1190-1319-4329-9cfc-dc9ec37d29fe.jpeg</url>
      <title>Forem: Diego Juliao</title>
      <link>https://forem.com/dianjuar</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/dianjuar"/>
    <language>en</language>
    <item>
      <title>NPM peerDependencies in Depth: A Comprehensive Introduction</title>
      <dc:creator>Diego Juliao</dc:creator>
      <pubDate>Sat, 19 Oct 2024 07:35:20 +0000</pubDate>
      <link>https://forem.com/dianjuar/npm-peerdependencies-in-depth-a-comprehensive-introduction-1o6g</link>
      <guid>https://forem.com/dianjuar/npm-peerdependencies-in-depth-a-comprehensive-introduction-1o6g</guid>
      <description>&lt;p&gt;As Javascript developers, we all know two different dependencies in our projects, &lt;code&gt;dependencies&lt;/code&gt; and &lt;code&gt;devDependencies&lt;/code&gt;, but what about &lt;code&gt;peerDependencies&lt;/code&gt;?&lt;/p&gt;

&lt;p&gt;In this series, we will examine this less common dependency in Javascript. We will study what they are, what I need to know about as a library user, and what best practices are for library authors.&lt;/p&gt;

&lt;h2&gt;
  
  
  What are dependencies in NPM
&lt;/h2&gt;

&lt;p&gt;Let's recap the different common types:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;code&gt;dependencies&lt;/code&gt;&lt;/strong&gt;: these are the tools used in your application; a good example is &lt;code&gt;react&lt;/code&gt;, &lt;code&gt;angular&lt;/code&gt;, and &lt;code&gt;express&lt;/code&gt;. When your application is in production, the code of the libraries on &lt;code&gt;dependencies&lt;/code&gt; will run under the hood and power your application.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;&lt;code&gt;devDependencies&lt;/code&gt;&lt;/strong&gt;: You will use these utilities to build your application. Here, you will find libraries to compile or parse your code and libraries to run your test.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What are &lt;code&gt;peerDependencies&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Authors specify specific libraries as &lt;code&gt;peerDependency&lt;/code&gt; when they require them to be installed in the workspace/project for everything to work as expected. They tell NPM (and the developers installing the library) that the package requires another package's specific version (or range of versions) to function correctly. Still, the user is responsible for installing and managing that dependency.&lt;/p&gt;

&lt;p&gt;Let's imagine an example: You are creating a utility for your favorite framework, which should be installed in the environment where your library will be running. The way to accurately specify this scenario is using the NPM &lt;code&gt;peerDependency&lt;/code&gt; feature. It provides a clear guideline for the seamless integration of your library.&lt;/p&gt;

&lt;p&gt;This practice is particularly common in libraries that function as "plugins," as they need to indicate the workspace requirements for proper functionality.&lt;/p&gt;

&lt;h2&gt;
  
  
  Real Example of &lt;code&gt;peerDependency&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Let's analyze a popular React library, &lt;a href="https://www.npmjs.com/package/react-datepicker" rel="noopener noreferrer"&gt;&lt;code&gt;react-datepicker&lt;/code&gt;&lt;/a&gt;; if we look at how its &lt;code&gt;package.json&lt;/code&gt; looks today, we can tell that we require at least React version &lt;code&gt;^16.9.0&lt;/code&gt; for &lt;code&gt;react-date picker&lt;/code&gt; to work correctly.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"peerDependencies"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"react"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^16.9.0 || ^17 || ^18"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"react-dom"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"^16.9.0 || ^17 || ^18"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If we fail to comply with this requirement, unexpected behavior will arise. &lt;/p&gt;

&lt;h2&gt;
  
  
  The Challenges &lt;code&gt;peerDependencies&lt;/code&gt; Address
&lt;/h2&gt;

&lt;p&gt;Version conflicts occur when packages in a project rely on different versions of the same library. This can lead to errors, especially for libraries like React, where sharing the same instance is crucial for state management and component communication. Without &lt;code&gt;peerDependencies&lt;/code&gt;, multiple library versions could be installed, resulting in unexpected behavior.&lt;/p&gt;

&lt;p&gt;To prevent these issues, &lt;code&gt;peerDependencies&lt;/code&gt; allow package authors to specify which version of a dependency their package requires without directly installing it. This shifts the responsibility to the developer using the package, ensuring they install a single, compatible dependency version. For example, libraries like &lt;code&gt;react-datepicker&lt;/code&gt; and &lt;code&gt;react-router&lt;/code&gt; use &lt;code&gt;peerDependencies&lt;/code&gt; to ensure they work seamlessly with the same version of React in the project.&lt;/p&gt;

&lt;h3&gt;
  
  
  Another Example
&lt;/h3&gt;

&lt;p&gt;Imagine this scenario: You're creating a library to share a fancy operator for &lt;code&gt;rxjs&lt;/code&gt;. If you set &lt;code&gt;rxjs&lt;/code&gt; as a &lt;code&gt;dependency&lt;/code&gt; instead of a &lt;code&gt;peerDependency&lt;/code&gt;, your library will install its own version of &lt;code&gt;rxjs&lt;/code&gt;. This might not seem like a big deal at first, but in reality, it can lead to version conflicts.&lt;/p&gt;

&lt;p&gt;If the project that installs your library already uses a different version of &lt;code&gt;rxjs&lt;/code&gt;, it could cause significant issues. The application might end up with two instances of &lt;code&gt;rxjs&lt;/code&gt; (one from your library and one from the project itself). Since &lt;code&gt;rxjs&lt;/code&gt; relies heavily on shared observables and subscriptions, having two versions running simultaneously can result in unpredictable behavior, such as streams not synchronizing properly or missing events.&lt;/p&gt;

&lt;p&gt;By using &lt;code&gt;peerDependencies&lt;/code&gt; instead, you can avoid this problem. Your package will signal to the project that it expects a specific version (or a range) of &lt;code&gt;rxjs&lt;/code&gt; to be present, but it won’t install its own version. This way, the project will use a single version of &lt;code&gt;rxjs&lt;/code&gt; shared by your library and other parts of the codebase, ensuring everything runs smoothly and in harmony.&lt;/p&gt;

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

&lt;p&gt;&lt;code&gt;peerDependencies&lt;/code&gt; may not be as commonly discussed as &lt;code&gt;dependencies&lt;/code&gt; or &lt;code&gt;devDependencies&lt;/code&gt;, but they play a critical role in ensuring compatibility and avoiding version conflicts in complex projects. By clearly defining which version of a shared dependency a library needs without directly installing it, &lt;code&gt;peerDependencies&lt;/code&gt; allow developers to maintain control over their project environment.&lt;/p&gt;

&lt;p&gt;The goal of this first post is to create a good understanding foundation of &lt;code&gt;peerDependencies&lt;/code&gt;. In the next chapter of this series, we will explore in a more practical way the different aspects of &lt;code&gt;peerDependencies&lt;/code&gt; as a user of libraries with &lt;code&gt;peerDependencies&lt;/code&gt;, how to overcome common problems, and how they behave in different javascript package managers.&lt;/p&gt;

</description>
      <category>npm</category>
      <category>webdev</category>
      <category>javascript</category>
      <category>node</category>
    </item>
    <item>
      <title>What's coming to ngx-deploy-npm V8</title>
      <dc:creator>Diego Juliao</dc:creator>
      <pubDate>Tue, 16 Jan 2024 21:01:24 +0000</pubDate>
      <link>https://forem.com/dianjuar/whats-coming-to-ngx-deploy-npm-v8-23gn</link>
      <guid>https://forem.com/dianjuar/whats-coming-to-ngx-deploy-npm-v8-23gn</guid>
      <description>&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4ma_Ayr8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/p1ntroyt11260a5ig9vs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4ma_Ayr8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/p1ntroyt11260a5ig9vs.png" alt="ngx-deploy-npm cover" width="800" height="485"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/bikecoders/ngx-deploy-npm"&gt;ngx-deploy-npm&lt;/a&gt; is continuing to evolve. With the release of version 8, the library is set to undergo significant changes that will delight developers waiting for some much-needed upgrades. In this blog post, we will explore what's new in the upcoming version, the motivations behind these changes, and how they will benefit the community of developers who rely on this library to simplify the publishment of their libraries.&lt;/p&gt;

&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Run Migrations&lt;/span&gt;
nx migrate ngx-deploy-npm
nx migrate &lt;span class="nt"&gt;--run-migrations&lt;/span&gt;

&lt;span class="c"&gt;# Review changes 👀&lt;/span&gt;
&lt;span class="c"&gt;# Commit changes&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  &lt;code&gt;ngx-deploy-npm&lt;/code&gt; History 📜
&lt;/h2&gt;

&lt;p&gt;Knowing some of this plugin's origins is meaningful to understand the upcoming changes. Nearly four and a half years ago, this plugin was born, but not as we know it today; at its dawn, it was an Angular Builder to publish Angular Libraries to NPM. It was designed to work on Angular Workspaces. (now, you know why the &lt;code&gt;ngx&lt;/code&gt; prefix is on the plugin's name).&lt;/p&gt;

&lt;p&gt;Back then, the standard way to publish an Angular Library was:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Compile your library in &lt;code&gt;production&lt;/code&gt; mode&lt;/li&gt;
&lt;li&gt;Step on &lt;code&gt;dist&lt;/code&gt; folder&lt;/li&gt;
&lt;li&gt;run &lt;code&gt;npm publish&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And &lt;code&gt;ngx-deploy-npm&lt;/code&gt; automated those steps to simplify Angular libraries publishment.&lt;/p&gt;

&lt;p&gt;We later decided to support Nx Workspaces to open it to publish any kind of library to NPM, migrating the Angular Builder to an Nx Plugin. At that time, we could manage both workspaces with (almost) the same code. Documentation was written for both workspaces, and integration tests were implemented in our publishment process to ensure everything worked as expected for both workspaces.&lt;/p&gt;

&lt;h2&gt;
  
  
  Upcoming breaking changes 🔥
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Drop support for Angular workspaces 🅰️
&lt;/h3&gt;

&lt;p&gt;The Angular workspace support started to be a load for the maintainers. Several times, the compatibility bridge Nx Devkit offered began to crumble until &lt;a href="https://github.com/bikecoders/ngx-deploy-npm/issues/467"&gt;it didn't work anymore&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The Nx ecosystem has continued evolving, and some of the original designs don't quite fit nowadays in Nx, but they do on Angular workspaces. That difference between both ecosystems makes us understand that to continue offering support for Angular workspaces, we must create and maintain two packages with separate approaches that benefit each workspace.&lt;/p&gt;

&lt;p&gt;We have learned in these four years about maintaining packages that &lt;strong&gt;the work of a maintainer is hard&lt;/strong&gt;. Maintaining two different NPM Packages would require considerable effort. We decided to focus on what brings the most value to our current users, and Nx Workspaces is the best way to do that.&lt;/p&gt;

&lt;p&gt;Also, we &lt;a href="https://github.com/dianjuar/ngx-deploy-npm-angular-dependant-script"&gt;wrote a script&lt;/a&gt; to help us determine which percentage of our current users are using an Angular workspace, and the results were that a shallow portion of our users are using an Angular Workspace.&lt;/p&gt;

&lt;h4&gt;
  
  
  Alternatives
&lt;/h4&gt;

&lt;p&gt;We suggest migrating to Nx workspaces as an alternative to continue using &lt;code&gt;ngx-deploy-npm&lt;/code&gt;. A stand-alone approach of Nx workspaces is an option that you should consider.&lt;/p&gt;

&lt;h3&gt;
  
  
  Removing the internal build process 🏗️
&lt;/h3&gt;

&lt;p&gt;Since the project's early days, we've built the library before publishing. This process has been made using an internal process to accomplish it. We are removing it mainly for a couple of reasons:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It hardcodes the &lt;code&gt;build&lt;/code&gt; target; if your build target is different, there is no way to change it.&lt;/li&gt;
&lt;li&gt;The devkit function used to launch the build &lt;em&gt;doesn't spawn the task orchestrator or any of that, so dependencies are not ran and caching is not considered&lt;/em&gt; (see &lt;a href="https://github.com/nrwl/nx/issues/19531#issuecomment-1760343458"&gt;nrwl/nx#19531&lt;/a&gt;). Making it not so great if you have a composed build process, users are forced to do a workaround to bypass that limitation and use the &lt;code&gt;dependsOn&lt;/code&gt; Nx feature instead.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This change means that everything related to that feature will be gone. The options &lt;code&gt;noBuild&lt;/code&gt; and &lt;code&gt;buildTarget&lt;/code&gt; will be removed in favor of &lt;a href="https://nx.dev/reference/project-configuration#dependson"&gt;&lt;code&gt;dependsOn&lt;/code&gt;&lt;/a&gt;, which is more flexible, declarative, and cache-friendly.&lt;/p&gt;

&lt;h3&gt;
  
  
  Removing auto &lt;code&gt;dist&lt;/code&gt; folder detection and making the &lt;code&gt;distFolderPath&lt;/code&gt; option mandatory. 📦
&lt;/h3&gt;

&lt;p&gt;In its origins, when we only supported Angular libraries, the dist folder path was found in one place. Now that we can support multiple library generators, finding the dist folder path is challenging since there is no standard on where that information should be found.&lt;/p&gt;

&lt;p&gt;To make the library source code smaller and easier to maintain, we decided to drop the auto &lt;code&gt;dist&lt;/code&gt; detection and bring these breaking changes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The &lt;strong&gt;option &lt;code&gt;distFolderPath&lt;/code&gt; is required&lt;/strong&gt; for installation and deployment.&lt;/li&gt;
&lt;li&gt;In the installation generator, we will remove the option &lt;code&gt;projects&lt;/code&gt; in favor of the new one &lt;code&gt;project&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How do you prepare for V8?
&lt;/h2&gt;

&lt;p&gt;We created migration scripts to do all the required changes for you automagically.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nx migrate ngx-deploy-npm
nx migrate &lt;span class="nt"&gt;--run-migrations&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We have explained all the changes and their motivations to guide you through this new release in case you have trouble running the migration scripts.&lt;/p&gt;

&lt;p&gt;After publishing this post, we plan to release version 8 in a couple of days.&lt;/p&gt;




&lt;p&gt;In conclusion, the upcoming version of &lt;code&gt;ngx-deploy-npm&lt;/code&gt; is set to undergo significant changes that will bring much-needed upgrades to the library. &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Removal of &lt;code&gt;dist&lt;/code&gt; folder path detection.

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;distFolderPath&lt;/code&gt; option is now mandatory.&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Drop support for Angular workspaces.&lt;/li&gt;
&lt;li&gt;Drop the internal build process in favor of &lt;code&gt;dependsOn&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These are among the breaking changes that developers can expect. Overall, these changes aim to provide a better experience for the community of developers who rely on &lt;code&gt;ngx-deploy-npm&lt;/code&gt; to simplify their libraries' publishment. Also, make the &lt;code&gt;ngx-deploy-npm&lt;/code&gt; core simpler.&lt;/p&gt;

&lt;p&gt;If this project has positively impacted you, consider supporting it by:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Giving it a star ⭐ on &lt;a href="https://github.com/bikecoders/ngx-deploy-npm"&gt;GitHub&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Start a &lt;a href="https://github.com/bikecoders/ngx-deploy-npm/discussions/new?category=show-and-tell"&gt;discussion 💬&lt;/a&gt; and tell everybody how unique this project is.&lt;/li&gt;
&lt;li&gt;Make a &lt;a href="https://github.com/sponsors/dianjuar?frequency=one-time&amp;amp;sponsor=dianjuar"&gt;donation 🫶&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>nx</category>
      <category>npm</category>
      <category>javascript</category>
      <category>devops</category>
    </item>
    <item>
      <title>7 VSCode Extensions to Boost Your Performance as an Angular Developer</title>
      <dc:creator>Diego Juliao</dc:creator>
      <pubDate>Wed, 28 Sep 2022 18:03:27 +0000</pubDate>
      <link>https://forem.com/herodevs/7-vscode-extensions-to-boost-your-performance-as-an-angular-developer-2dnb</link>
      <guid>https://forem.com/herodevs/7-vscode-extensions-to-boost-your-performance-as-an-angular-developer-2dnb</guid>
      <description>&lt;p&gt;Extensions on VSCode are invaluable tools for us developers to turn repetitive manual tasks in a few clicks or key bindings ⚡, do complex operations automagically ✨, and increase our development satisfaction by providing us a whole new experience on gray areas 🚀.&lt;/p&gt;

&lt;p&gt;Today, we will see 7 VSCode extensions that will increase our performance and enhance our experience with Angular.&lt;/p&gt;

&lt;h2&gt;
  
  
  Nx Console
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://marketplace.visualstudio.com/items?itemName=nrwl.angular-console" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5a7vypkgbu4mbqtaybd2.png" title="Nx Console" alt="Nx Console"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://marketplace.visualstudio.com/items?itemName=nrwl.angular-console" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimg.shields.io%2Fstatic%2Fv1%3Flabel%3DView%2520on%2520Marketplace%26message%3DNx%2520Console%26%3Fstyle%3Dfor-the-badge%26logo%3Dvisualstudiocode" alt="Nx Console"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is my favorite so far 😍. It was previously known as Angular Console. The description of this plugin has everything we need to know:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Spend less time looking up command-line arguments and more time shipping incredible products.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This extension is a UI for the Angular CLI. You will have all schematic parameters with their description available to decide better what fits your current needs. It’s an excellent opportunity to discover what the Angular CLI offers; it’s encouraged to mess around with the parameters’ values because everything runs with the &lt;code&gt;--dry-run&lt;/code&gt; option as default (no changes applied). Still, the effects of those changes are displayed in a console below to decide what fits you better.&lt;/p&gt;

&lt;p&gt;Don’t get confused or intimidated if you don’t know Nx. It works like a charm on Angular Workspaces.&lt;/p&gt;

&lt;p&gt;Here, you can see how to generate an Angular Component.&lt;/p&gt;

&lt;h2&gt;
  
  
  angular2-switcher
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://marketplace.visualstudio.com/items?itemName=infinity1207.angular2-switcher" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsqswlp1j9kcd5wf8q5vl.png" title="angular2-switcher" alt="angular2-switcher"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://marketplace.visualstudio.com/items?itemName=infinity1207.angular2-switcher" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimg.shields.io%2Fstatic%2Fv1%3Flabel%3DView%2520on%2520Marketplace%26message%3Dangular2-switcher%26%3Fstyle%3Dfor-the-badge%26logo%3Dvisualstudiocode" alt="angular2-switcher"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Simple but powerful, it allows navigating between the files using hotkeys on your Angular component. You can navigate the template, the component, styles, or the tests file with a couple of keys. It allows you to avoid opening the explorer, locating your component across tens of folders, and, finally, the file you were looking for.&lt;/p&gt;

&lt;p&gt;This is the key combination:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;Windows&lt;/th&gt;
&lt;th&gt;macOS&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Switch to HTML&lt;/td&gt;
&lt;td&gt;Alt+O&lt;/td&gt;
&lt;td&gt;Shift+Alt+O&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Switch to CSS&lt;/td&gt;
&lt;td&gt;Alt+I&lt;/td&gt;
&lt;td&gt;Shift+Alt+I&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Switch to ts&lt;/td&gt;
&lt;td&gt;Alt+U&lt;/td&gt;
&lt;td&gt;Shift+Alt+U&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Switch to spec.ts&lt;/td&gt;
&lt;td&gt;Alt+P&lt;/td&gt;
&lt;td&gt;Shift+Alt+P&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5gxurmqqim5mkhiyxzf0.gif" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5gxurmqqim5mkhiyxzf0.gif" alt="angular2-switcher in action"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Angular Language Service
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://marketplace.visualstudio.com/items?itemName=Angular.ng-template" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F3m4swf8q0umech6778ii.png" title="Angular Language Service" alt="Angular Language Service"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://marketplace.visualstudio.com/items?itemName=Angular.ng-template" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimg.shields.io%2Fstatic%2Fv1%3Flabel%3DView%2520on%2520Marketplace%26message%3DAngular%2520Language%2520Service%26%3Fstyle%3Dfor-the-badge%26logo%3Dvisualstudiocode" alt="Angular Language Service"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This extension provides autocompletion on the templates of our components. No more awkward moments of try and error. Now, you will have a tool to communicate the HTML with your component. All the methods will be at your fingertips.&lt;/p&gt;

&lt;h2&gt;
  
  
  Code Spell Checker
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://marketplace.visualstudio.com/items?itemName=streetsidesoftware.code-spell-checker" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fge6w7fjlrgnqpkhgpz0u.png" title="Code Spell Checker" alt="Code Spell Checker"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://marketplace.visualstudio.com/items?itemName=streetsidesoftware.code-spell-checker" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimg.shields.io%2Fstatic%2Fv1%3Flabel%3DView%2520on%2520Marketplace%26message%3DCode%2520Spell%2520Checkere%26%3Fstyle%3Dfor-the-badge%26logo%3Dvisualstudiocode" alt="Code Spell Checker"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;How often has the QA discovered a wrong spelling world on an interface you have worked on and held a ticket from its deadline? How many times was the backend “broken”, and the problem was because you incorrectly spelled a parameter? Say goodbye to those embarrassing moments and detect all the slips on the spot.&lt;/p&gt;

&lt;h2&gt;
  
  
  Bookmarks
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://marketplace.visualstudio.com/items?itemName=alefragnani.Bookmarks" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5qy0m36tjl2kfzpidftg.png" title="Bookmarks" alt="Bookmarks"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://marketplace.visualstudio.com/items?itemName=alefragnani.Bookmarks" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimg.shields.io%2Fstatic%2Fv1%3Flabel%3DView%2520on%2520Marketplace%26message%3DBookmarks%26%3Fstyle%3Dfor-the-badge%26logo%3Dvisualstudiocode" alt="Bookmarks"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Are you dealing with a complex project and lost your path among all the files you need to have open to tracking a feature? Dealing with very long files and lost focus on the long scrolling? Stay focused on what matters to you by putting bookmarks on the lines you want to stay concentrated on and start navigating between them.&lt;/p&gt;

&lt;h2&gt;
  
  
  Jest Runner
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://marketplace.visualstudio.com/items?itemName=firsttris.vscode-jest-runner" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ff0vh9xaiggekj9dxv8qy.png" title="Jest Runner" alt="Jest Runner"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://marketplace.visualstudio.com/items?itemName=firsttris.vscode-jest-runner" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimg.shields.io%2Fstatic%2Fv1%3Flabel%3DView%2520on%2520Marketplace%26message%3DJest%2520Runner%26%3Fstyle%3Dfor-the-badge%26logo%3Dvisualstudiocode" alt="Jest Runner"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Jest has been gaining terrain on the Angular ecosystem, especially on Nx, where it’s the default test runner. With this extension, you can run a specific test causing you troubles. Also, you can run that particular test in debug mode for a more detailed inspection.&lt;/p&gt;

&lt;h2&gt;
  
  
  Angular snippets
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://marketplace.visualstudio.com/items?itemName=Mikael.Angular-BeastCode" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4c3pzoinp8af5acycerz.png" title="Angular 10 Snippets — TypeScript, Html, Angular Material, ngRx, RxJS &amp;amp; Flex Layout" alt="Angular 10 Snippets — TypeScript, Html, Angular Material, ngRx, RxJS &amp;amp; Flex Layout"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://marketplace.visualstudio.com/items?itemName=Mikael.Angular-BeastCode" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimg.shields.io%2Fstatic%2Fv1%3Flabel%3DView%2520on%2520Marketplace%26message%3DAngular%252010%2520Snippets%2520%25E2%2580%2594%2520TypeScript%2C%2520Html%2C%2520Angular%2520Material%2C%2520ngRx%2C%2520RxJS%2520%26%2520Flex%2520Layout%26%3Fstyle%3Dfor-the-badge%26logo%3Dvisualstudiocode" alt="Angular 10 Snippets — TypeScript, Html, Angular Material, ngRx, RxJS &amp;amp; Flex Layout"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://marketplace.visualstudio.com/items?itemName=johnpapa.Angular2" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Flvb35l71ptoej6dqpwdz.png" title="Angular Snippets (Version 13)" alt="Angular Snippets (Version 13)"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://marketplace.visualstudio.com/items?itemName=johnpapa.Angular2" rel="noopener noreferrer"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fimg.shields.io%2Fstatic%2Fv1%3Flabel%3DView%2520on%2520Marketplace%26message%3DAngular%2520Snippets%2520%28Version%252013%29%26%3Fstyle%3Dfor-the-badge%26logo%3Dvisualstudiocode" alt="Jest Runner"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I recommend using two extensions, &lt;a href="https://marketplace.visualstudio.com/items?itemName=johnpapa.Angular2" rel="noopener noreferrer"&gt;Angular Snippets (Version 13)&lt;/a&gt; and &lt;a href="https://marketplace.visualstudio.com/items?itemName=Mikael.Angular-BeastCode" rel="noopener noreferrer"&gt;Angular 10 Snippets — TypeScript, Html, Angular Material, ngRx, RxJS &amp;amp; Flex Layout&lt;/a&gt;. Both offer snippets for your Angular day-to-day work generate in seconds complex structures for Angular itself (components, modules, pipes, &lt;code&gt;ngFor&lt;/code&gt;, &lt;code&gt;ngIf&lt;/code&gt;, etc.), NgRx, Material Design, RxJs, and Testing.&lt;/p&gt;




&lt;p&gt;Extensions are good instruments to improve our performance as developers. I love that when something automates a process, I can liberate some thinking load in a particular area and stay focused on what matters, building excellent products.&lt;/p&gt;

&lt;p&gt;Do you have one extension that has changed your life? Let us know in the comments.&lt;/p&gt;




&lt;h2&gt;
  
  
   About HeroDevs
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://www.herodevs.com/" rel="noopener noreferrer"&gt;HeroDevs&lt;/a&gt; is a software engineering and consulting studio that specializes in frontend development. Our team has authored or co-authored projects like the Angular CLI, Angular Universal, Scully, XLTS — extended long-term support for AngularJS, Ng-conf, and many others. We work with fast-growing startups and some of the world’s largest companies like Google, GE, Capital One, Experian, T-Mobile, Corteva, and others. Learn more about us at &lt;a href="https://www.herodevs.com/" rel="noopener noreferrer"&gt;herodevs.com&lt;/a&gt;&lt;/p&gt;

</description>
      <category>angular</category>
      <category>productivity</category>
      <category>vscode</category>
      <category>performance</category>
    </item>
    <item>
      <title>i3wm Screenshot Shortcuts</title>
      <dc:creator>Diego Juliao</dc:creator>
      <pubDate>Sat, 26 Mar 2022 20:53:35 +0000</pubDate>
      <link>https://forem.com/dianjuar/i3wm-screenshot-shortcuts-3n7b</link>
      <guid>https://forem.com/dianjuar/i3wm-screenshot-shortcuts-3n7b</guid>
      <description>&lt;p&gt;Have excellent screenshot shortcuts in your &lt;a href="https://i3wm.org/"&gt;i3wm&lt;/a&gt;.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Feature&lt;/th&gt;
&lt;th&gt;Shortcut&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Full Screen&lt;/td&gt;
&lt;td&gt;&lt;code&gt;PrtScrn&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Selection&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;Shift&lt;/code&gt; + &lt;code&gt;PrtScrn&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Active Window&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;Super&lt;/code&gt; + &lt;code&gt;PrtScrn&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Clipboard Full Screen&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;Ctrl&lt;/code&gt; + &lt;code&gt;PrtScrn&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Clipboard Selection&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;Ctrl&lt;/code&gt; + &lt;code&gt;Shift&lt;/code&gt; + &lt;code&gt;PrtScrn&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Clipboard Active Window&lt;/td&gt;
&lt;td&gt;
&lt;code&gt;Ctrl&lt;/code&gt; + &lt;code&gt;Super&lt;/code&gt; + &lt;code&gt;PrtScrn&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;blockquote&gt;
&lt;p&gt;All the screenshots are saved on &lt;code&gt;~/Pictures/CURRENT_DATE&lt;/code&gt;.&lt;br&gt;
The key &lt;code&gt;super&lt;/code&gt; refers to the modifier key (window/command or alt by default depending on config).&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Requirements
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;maim&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;xclip&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;xdotool&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Set-up
&lt;/h2&gt;

&lt;p&gt;Set this on your i3 config file &lt;code&gt;~/.i3/config&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;## Screenshots
bindsym Print exec --no-startup-id maim "/home/$USER/Pictures/$(date)"
bindsym $mod+Print exec --no-startup-id maim --window $(xdotool getactivewindow) "/home/$USER/Pictures/$(date)"
bindsym Shift+Print exec --no-startup-id maim --select "/home/$USER/Pictures/$(date)"

## Clipboard Screenshots
bindsym Ctrl+Print exec --no-startup-id maim | xclip -selection clipboard -t image/png
bindsym Ctrl+$mod+Print exec --no-startup-id maim --window $(xdotool getactivewindow) | xclip -selection clipboard -t image/png
bindsym Ctrl+Shift+Print exec --no-startup-id maim --select | xclip -selection clipboard -t image/png
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;You may want to remove the default or any other screenshot shortcuts to prevent errors.&lt;br&gt;
Don't forget to reload your window manager &lt;code&gt;super&lt;/code&gt;+ &lt;code&gt;shift&lt;/code&gt;+ &lt;code&gt;c&lt;/code&gt;.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;blockquote&gt;
&lt;p&gt;The source of this information is from my gist &lt;a href="https://gist.github.com/dianjuar/ee774561a8bc02b077989bc17424a19f"&gt;&lt;em&gt;My i3 shortcuts to take screenshots&lt;/em&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>i3wm</category>
      <category>linux</category>
    </item>
    <item>
      <title>Improve your GitHub Actions Workflow execution time by 32% ⚡</title>
      <dc:creator>Diego Juliao</dc:creator>
      <pubDate>Wed, 08 Dec 2021 07:25:27 +0000</pubDate>
      <link>https://forem.com/dianjuar/improve-your-workflow-execution-time-by-32-1nd</link>
      <guid>https://forem.com/dianjuar/improve-your-workflow-execution-time-by-32-1nd</guid>
      <description>&lt;h3&gt;
  
  
  My Workflow
&lt;/h3&gt;

&lt;p&gt;There is a process that gets repeated most of the time across your workflow, a process that is expensive in time speaking; it takes 25 seconds to complete. This process is essential, and without it, you can not do almost anything.&lt;/p&gt;

&lt;p&gt;I'm talking about installing the dependencies for your project, &lt;code&gt;npm install&lt;/code&gt; for node projects. Without it, you can not build, test, lint or do almost any other operation on your workflow.&lt;/p&gt;

&lt;p&gt;We can do something straightforward to downgrade those 25 seconds to 14.3 (an improvement of almost 60%!😮). You only need to apply cache to the dependency installation (&lt;code&gt;npm install&lt;/code&gt;). Those 10 seconds saved across all your jobs will add up to 32% improvement.&lt;/p&gt;

&lt;p&gt;The secret of achieving an execution improvement of 32% is to &lt;strong&gt;be consistent&lt;/strong&gt;, apply &lt;a href="https://en.wikipedia.org/wiki/Don%27t_repeat_yourself"&gt;DRY&lt;/a&gt;. Every time you need to perform the dependency installation, you need to be sure to use the same set of steps.&lt;/p&gt;

&lt;p&gt;Github actions allow us to be consistent super-easy with &lt;a href="https://docs.github.com/en/actions/creating-actions/about-custom-actions"&gt;custom actions&lt;/a&gt;. We can define an activity with all the steps needed and then reuse it every time with just one line of code.&lt;/p&gt;

&lt;h3&gt;
  
  
  Submission Category:
&lt;/h3&gt;

&lt;p&gt;Maintainer Must-Haves&lt;/p&gt;

&lt;h3&gt;
  
  
  Yaml File or Link to Code
&lt;/h3&gt;

&lt;p&gt;This is the actual action using &lt;code&gt;yarn&lt;/code&gt; as the package manager.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="c1"&gt;# .github/actions/setup/action.yml&lt;/span&gt;
&lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Setup&lt;/span&gt;
&lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Setup Node.js, cache and install dependencies&lt;/span&gt;
&lt;span class="na"&gt;inputs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;node-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Node.js version&lt;/span&gt;
    &lt;span class="na"&gt;required&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="no"&gt;false&lt;/span&gt;
    &lt;span class="na"&gt;default&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s1"&gt;'&lt;/span&gt;&lt;span class="s"&gt;16'&lt;/span&gt;
&lt;span class="na"&gt;runs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;using&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;composite&lt;/span&gt;
  &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Install Dependencies&lt;/span&gt;
      &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/setup-node@v2&lt;/span&gt;
      &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
        &lt;span class="na"&gt;cache&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;yarn&lt;/span&gt;
        &lt;span class="na"&gt;node-version&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;${{ inputs.node-version }}&lt;/span&gt;
        &lt;span class="na"&gt;registry-url&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;https://registry.npmjs.org&lt;/span&gt;
    &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;yarn install&lt;/span&gt;
      &lt;span class="na"&gt;shell&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;bash&lt;/span&gt;
      &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;yarn --frozen-lockfile --no-progress --non-interactive --prefer-offline&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;To use it on any job:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;jobs&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
  &lt;span class="na"&gt;any-job&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;runs-on&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;ubuntu-latest&lt;/span&gt;
    &lt;span class="na"&gt;steps&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Get code to get access to custom our actions&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;actions/checkout@v2&lt;/span&gt;
        &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
          &lt;span class="na"&gt;fetch-depth&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;
      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Install Dependencies&lt;/span&gt;
        &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;./.github/actions/setup&lt;/span&gt;

      &lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Doing any-job&lt;/span&gt;
        &lt;span class="na"&gt;run&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;npm run any-job&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Check out the workflow on an actual project.&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--566lAguM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/dianjuar"&gt;
        dianjuar
      &lt;/a&gt; / &lt;a href="https://github.com/dianjuar/improve-workspace-execution-32"&gt;
        improve-workspace-execution-32
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Improve your workflow execution by 32% just by caching the yarn installation
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;h1&gt;
Improve your Workflow execution time by 32% ⚡
&lt;/h1&gt;
&lt;p&gt;Using cache on dependency installation to achieve up to 32% of execution improvement (GitHub Actions)&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Check blog post on &lt;a href="https://dev.to/dianjuar/improve-your-workflow-execution-time-by-32-1nd" rel="nofollow"&gt;Dev.To&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/div&gt;

  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/dianjuar/improve-workspace-execution-32"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;



&lt;h3&gt;
  
  
  Additional Resources / Info
&lt;/h3&gt;

&lt;p&gt;This discovery was formulated, tested, and explained with numbers statically correct on &lt;a href="https://github.com/bikecoders/ngx-deploy-npm/pull/137"&gt;ngx-deploy-npm&lt;/a&gt; project.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;@jscutlery/semver&lt;/code&gt; project &lt;a href="https://github.com/jscutlery/semver/pull/381"&gt;is implementing&lt;/a&gt; this improvement&lt;/p&gt;

</description>
      <category>actionshackathon2</category>
      <category>github</category>
      <category>performance</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Importing modules in JavaScript, are we doing it right?</title>
      <dc:creator>Diego Juliao</dc:creator>
      <pubDate>Tue, 31 Aug 2021 21:39:43 +0000</pubDate>
      <link>https://forem.com/dianjuar/importing-modules-in-javascript-are-we-doing-it-right-nc</link>
      <guid>https://forem.com/dianjuar/importing-modules-in-javascript-are-we-doing-it-right-nc</guid>
      <description>&lt;p&gt;We, as Javascript developers need to use libraries in our day to day, it simplifies our work a lot. Nowadays we mostly do it in this way:&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="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;lib&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;amazing-lib&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;func1&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;amazing-lib&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If we quickly analyze it, in the first statement we are importing everything and putting it on a variable called &lt;code&gt;lib&lt;/code&gt;, on the second, we are importing everything again and destructuring only what we need; what about all the other code that I'm not using?&lt;/p&gt;



&lt;blockquote&gt;
&lt;h2&gt;
  
  
  &lt;em&gt;Will not all the unused library's code end up on the final bundle making my application unnecessary heavier?&lt;/em&gt;
&lt;/h2&gt;
&lt;/blockquote&gt;



&lt;p&gt;Today you will learn how to improve your bundle size just by changing the way you import. After this, you are going to be able to detect a simple optimization opportunity for your bundle!&lt;/p&gt;






&lt;h2&gt;
  
  
  TL; DR
&lt;/h2&gt;

&lt;p&gt;Verify if the library has support for ES6 and you can import freely, you will get always the best result 🙆‍♂️. If it doesn't ⚠️, you need to import using cherry-picking.&lt;/p&gt;






&lt;h2&gt;
  
  
  Can we import as we want without consequences?
&lt;/h2&gt;

&lt;p&gt;When we compile our front-end apps, there is a process that Webpack applies called &lt;a href="https://webpack.js.org/guides/tree-shaking/" rel="noopener noreferrer"&gt;Tree Shaking&lt;/a&gt;. Basically, is code elimination, the code that is not being used by anyone. This process prevents having dead code in our final bundle, making it lighter and the application is going to load faster for our users!&lt;/p&gt;

&lt;p&gt;Let's analyse this:&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="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;lib&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;amazing-lib&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;foo&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;amazing-lib&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In both cases all the library content is being imported, the first place is the easiest to spot, all the library's content is being assigned to the variable &lt;code&gt;lib&lt;/code&gt;, in the second case we are just applying destructuring to the library's content to get what we need. Thanks to Tree Shaking all the unused code doesn't end up on our bundles.&lt;/p&gt;

&lt;p&gt;So, thanks to Tree Shaking I'm excused and I can import however I want and all the unused code imported from the library will be removed automagically?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Is not always the case&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;There is a scenario when Tree Shaking is not going to be able to detect what is dead code having as consequence to remove nothing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Scenarios
&lt;/h2&gt;

&lt;h3&gt;
  
  
  ES6
&lt;/h3&gt;

&lt;p&gt;ECMAScript 2015(aka ES6) Module Syntax; it sounds complex, but it's something really popular nowadays. It's just a syntax to import a JS module, it looks like this:&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="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;foo&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;awesome-lib&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;bar&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../utils&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;lib&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../utils&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;justAConst&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;foobar&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When you are using a library that has ES6 Module Syntax compatibility, you don't need to worry, import as will, Tree Shaking have you covered 😉. In fact, is the only module syntax that Tree Shaking supports, let's take a look at the &lt;a href="https://webpack.js.org/guides/tree-shaking/" rel="noopener noreferrer"&gt;documentation&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Tree shaking&lt;/em&gt; is a term commonly used in the JavaScript context for dead-code elimination. It relies on the static structure of ES2015 module syntax, i.e. &lt;code&gt;import&lt;/code&gt; and &lt;code&gt;export&lt;/code&gt;...&lt;/p&gt;

&lt;p&gt;The webpack 2 release came with built-in support for ES2015 modules (alias harmony modules) as well as unused module export detection...&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h6&gt;
  
  
  If you are completely new about 👉 &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Modules" rel="noopener noreferrer"&gt;JS Modules&lt;/a&gt;
&lt;/h6&gt;

&lt;h3&gt;
  
  
  No ES6 module syntax
&lt;/h3&gt;

&lt;p&gt;A library can be delivered (packaged) with other module systems different than ES6, even though if its source code uses ES6 module syntax, a compilation process could be implemented to only support &lt;a href="https://nodejs.org/api/modules.html#modules_modules_commonjs_modules" rel="noopener noreferrer"&gt;CommonJS&lt;/a&gt; for example. The projects written using pure JS (with no transpilation process (Babel, TypeScript)) that uses the CommonJs module system is another example.&lt;/p&gt;

&lt;p&gt;So, no ES6 module syntax present = no Tree Shaking. The only way to have a healthy bundle when dealing with libraries with no ES6 is importing using a technique called cherry-picking, you need to specify the absolute path to the file that contains the info needed.&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="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;small&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;common-js-lib/small&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;h4&gt;
  
  
  Downsides of cherry-picking
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;You need to know the path to the module needed. (Your IDE could help in this quest)&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;You need to specify each one of the imports that you need, ex:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;has&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;lodash/has&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;capitalize&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;lodash/capitalize&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;lastIndexOf&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;lodash/lastIndexOf&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;/li&gt;
&lt;li&gt;&lt;p&gt;As a maintainer, you may want to have a nice and easy-to-use scaffolding design to detect with ease something in your lib. This needs to be designed, implemented, and maintained.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;You may forget to do it, making your bundle unnecessary heavier. &lt;a href="https://eslint.org/docs/rules/no-restricted-imports" rel="noopener noreferrer"&gt;ESLint&lt;/a&gt; could help you to import correctly.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Performance Test
&lt;/h2&gt;

&lt;p&gt;Having the theory learned I decided to prove all this. What I did was create some libraries with different module support, create several front-end apps on React and Angular&lt;sup id="fnref1"&gt;1&lt;/sup&gt; to test if Tree Shaking really does its job.&lt;/p&gt;

&lt;p&gt;The libraries created were simple, they export two variables &lt;code&gt;small&lt;/code&gt; and &lt;code&gt;big&lt;/code&gt;. &lt;code&gt;small&lt;/code&gt; contains one dog 🐕 (&lt;code&gt;small = '🐕'&lt;/code&gt;), but &lt;code&gt;big&lt;/code&gt; has 1646400 dogs (&lt;code&gt;big = '🐕🐕🐕🐕🐕🐕🐕🐕🐕...'&lt;/code&gt;). This is going to make &lt;code&gt;big&lt;/code&gt; to be 6.3 megabytes of weight.&lt;/p&gt;

&lt;p&gt;Only &lt;code&gt;small&lt;/code&gt; is going to be use at all time, so if &lt;code&gt;big&lt;/code&gt; sneaks into the final bundle we are going to notice it on sight!.&lt;/p&gt;

&lt;h3&gt;
  
  
  Healthy Bundle
&lt;/h3&gt;

&lt;p&gt;This how a healthy bundle looks like:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg0kar9uiffp7oi7pot3w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fg0kar9uiffp7oi7pot3w.png" alt="a healthy, bundle of 211.78KB" width="800" height="497"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Smelly Bundle 🤢
&lt;/h3&gt;

&lt;p&gt;The smelly one! You can notice a big white box that represents &lt;code&gt;big&lt;/code&gt; and represents 96.7% of the application size:&lt;br&gt;
&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhpvw6wwvwfjpbjhf8fjp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhpvw6wwvwfjpbjhf8fjp.png" alt="Smelly Bundle, bundle of 6.49MB" width="800" height="497"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  The Results
&lt;/h3&gt;

&lt;p&gt;The results were as expected, if your library has to offer ES6 module syntax, Tree Shaking will do its job. If not, cherry-picking was the only way to get a healthy bundle.&lt;/p&gt;

&lt;p&gt;Here is the repo if you are curious &lt;a href="https://github.com/dianjuar/how-to-import" rel="noopener noreferrer"&gt;dianjuar/how-to-import&lt;/a&gt;. All this was created in a Monorepo using &lt;a href="https://nx.dev/" rel="noopener noreferrer"&gt;Nx&lt;/a&gt;, the library's npm publishing was mocked using &lt;a href="https://github.com/wclr/yalc" rel="noopener noreferrer"&gt;yalc&lt;/a&gt;. The bundle analysis was made using &lt;a href="https://www.npmjs.com/package/source-map-explorer" rel="noopener noreferrer"&gt;source-map-explorer&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Also, I wanted to make this test with popular libraries, so this is what I got, importing as &lt;code&gt;import { whatINeed } from 'popular-lib'&lt;/code&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Library&lt;/th&gt;
&lt;th&gt;Healthy Bundle&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://www.npmjs.com/package/lodash" rel="noopener noreferrer"&gt;lodash&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://www.npmjs.com/package/moment" rel="noopener noreferrer"&gt;moment&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://www.npmjs.com/package/rxjs" rel="noopener noreferrer"&gt;rxjs&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://www.npmjs.com/package/lodash-es" rel="noopener noreferrer"&gt;lodash-es&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://www.npmjs.com/package/date-fns" rel="noopener noreferrer"&gt;date-fns&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://www.npmjs.com/package/@angular/core" rel="noopener noreferrer"&gt;@angular/core&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://www.n-pmjs.com/package/@angular/material" rel="noopener noreferrer"&gt;@angular/material&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="http://www.npmjs.com/package/react" rel="noopener noreferrer"&gt;react&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="http://www.npmjs.com/package/react-dom" rel="noopener noreferrer"&gt;react-dom&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="http://www.npmjs.com/package/@material-ui/core" rel="noopener noreferrer"&gt;@material-ui/core&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="http://www.npmjs.com/package/@fortawesome/react-fontawesome" rel="noopener noreferrer"&gt;@fortawesome/react-fontawesome&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Useful Tools
&lt;/h2&gt;

&lt;p&gt;Along with this experiment, I was using the VsCode extension &lt;a href="https://marketplace.visualstudio.com/items?itemName=wix.vscode-import-cost" rel="noopener noreferrer"&gt;Import Cost&lt;/a&gt; and was precise along with the result. With the extension, you will be able to see right away how much an import will cost to the bundle. It will not tell you when you are getting a healthy or smelly bundle, but you can tell when an import cost is sus.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://camo.githubusercontent.com/08af5550483d9e9ccee846ebdbcb74332bdb523a738be4cb5aec8e4ba7df49e8/68747470733a2f2f636974772e6465762f5f6e6578742f696d6167653f75726c3d253246706f737473253246696d706f72742d636f73742532463171756f76335446706747327572376d79434c477473412e67696626773d3130383026713d3735" class="article-body-image-wrapper"&gt;&lt;img src="https://camo.githubusercontent.com/08af5550483d9e9ccee846ebdbcb74332bdb523a738be4cb5aec8e4ba7df49e8/68747470733a2f2f636974772e6465762f5f6e6578742f696d6167653f75726c3d253246706f737473253246696d706f72742d636f73742532463171756f76335446706747327572376d79434c477473412e67696626773d3130383026713d3735" alt="Import Cost Live" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;h6&gt;
  
  
  Gif extracted from the &lt;a href="https://github.com/wix/import-cost#import-cost--" rel="noopener noreferrer"&gt;README&lt;/a&gt; of Cost Import
&lt;/h6&gt;
&lt;/blockquote&gt;

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

&lt;p&gt;Tree Shaking have you covered! You can import however you want and you will be getting a healthy bundle &lt;strong&gt;if and only if&lt;/strong&gt; the library has support for ES6 Module Syntax (&lt;code&gt;import&lt;/code&gt; and &lt;code&gt;export&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;You can make your bundle unnecessary heavy if you don't cherry-pick the imports on libraries without ES6 module support, like &lt;a href="https://www.npmjs.com/package/lodash" rel="noopener noreferrer"&gt;lodash&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://marketplace.visualstudio.com/items?itemName=wix.vscode-import-cost" rel="noopener noreferrer"&gt;Import Cost&lt;/a&gt; can help you to spot an import that needs some refinement.&lt;/p&gt;







&lt;ol&gt;

&lt;li id="fn1"&gt;
&lt;p&gt;The experiment is agnostic to the Framework or Library used, if webpack is involved in the bundling it would take the same effect. ↩&lt;/p&gt;
&lt;/li&gt;

&lt;/ol&gt;

</description>
      <category>javascript</category>
      <category>typescript</category>
      <category>es6</category>
      <category>treeshaking</category>
    </item>
    <item>
      <title>Importando módulos en Javascript, lo estamos haciendo bien?</title>
      <dc:creator>Diego Juliao</dc:creator>
      <pubDate>Tue, 31 Aug 2021 15:24:17 +0000</pubDate>
      <link>https://forem.com/ngvenezuela/importando-modulos-en-javascript-lo-estamos-haciendo-bien-3hif</link>
      <guid>https://forem.com/ngvenezuela/importando-modulos-en-javascript-lo-estamos-haciendo-bien-3hif</guid>
      <description>&lt;p&gt;Todos los desarrolladores Javascript usamos librerías en nuestro día a día, facilita mucho nuestro trabajo. Hoy en día lo hacemos mayormente de esta manera:&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="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;lib&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;super-lib&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;func1&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;super-lib&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Si analizamos rápidamente esto, en la primera sentencia estamos importando todo y asignándolo a la variable &lt;code&gt;lib&lt;/code&gt;, en el segundo, estamos importando todo nuevamente pero usando destructuring obtenemos solo lo que queremos; qué sucede con todo el código que no se está usando?&lt;/p&gt;



&lt;blockquote&gt;
&lt;h2&gt;
  
  
  &lt;em&gt;¿Todo el código que no se está usando terminará en el bundle final haciendo mi aplicación innecesariamente pesada?&lt;/em&gt;
&lt;/h2&gt;
&lt;/blockquote&gt;



&lt;p&gt;Hoy, aprenderemos cómo mejorar el tamaño de un bundle simplemente cambiando la manera en que importamos. Después de leer esto, serás capaz de detectar una simple oportunidad de optimización para el bundle.&lt;/p&gt;






&lt;h2&gt;
  
  
  TL; DR
&lt;/h2&gt;

&lt;p&gt;Verifica si la libería tiene soporte para ES6 y serás capaz de importar como quieras, siempre obtendrás el mejor resultado 🙆‍♂️. Si no lo soporta ⚠️, tendrás que importar usando cherry-picking.&lt;/p&gt;






&lt;h2&gt;
  
  
  ¿Podemos importar de cualquier manera sin consecuencias?
&lt;/h2&gt;

&lt;p&gt;Cuando compilamos aplicaciones front-end, hay un proceso que Webpack aplica llamado &lt;a href="https://webpack.js.org/guides/tree-shaking/"&gt;Tree Shaking&lt;/a&gt;. Básicamente, es eliminación de código, el código que no está siendo usado por nadie. Esto es un proceso que previene que código muerto termine en nuestro bundle final, haciéndolo más liviano así las aplicaciones van a cargar más rápidamente para nuestros usuarios!.&lt;/p&gt;

&lt;p&gt;Analicemos esto:&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="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;lib&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;amazing-lib&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;foo&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;amazing-lib&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;En ambos casos todo el contenido de la librería está siendo importado, en la primera línea es donde se observa más claramente, todo el contenido está siendo asignado a la variable &lt;code&gt;lib&lt;/code&gt;, en la segunda línea estamos simplemente aplicando destructuring al contenido de la librería para obtener lo que queremos. Gracias a Tree Shaking todo el código que no es usado no termina en el bundle final.&lt;/p&gt;

&lt;p&gt;Así que, gracias a Tree Shaking tengo un pase libre a importar como yo quiera y todo el código muerto importado de la librería será removido automágicamente?&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;No siempre es el caso&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Hay un escenario cuando Tree Shaking no será capaz de detectar qué es código muerto, teniendo como consecuencia que no se removerá nada.&lt;/p&gt;

&lt;h2&gt;
  
  
  Escenarios
&lt;/h2&gt;

&lt;h3&gt;
  
  
  ES6
&lt;/h3&gt;

&lt;p&gt;La Sintaxis de Modulo ECMAScript 2015(también conocido como ES6); suena complejo, pero es algo bastante popular en estos días. Es solo una sintaxis para importar un modulo Javascript, luce así:&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="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;foo&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;super-lib&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;bar&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../utils&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;lib&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;../utils&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;justAConst&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;foobar&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Cuando usas una librería que ofrece soporte para para sintaxis ES6, no hay de qué preocuparse, importa libremente, Tree Shaking estará ahí 😉. De hecho, es con la única sintaxis de modulo que Tree Shaking soporta. Miremos a la &lt;a href="https://webpack.js.org/guides/tree-shaking/"&gt;documentación&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Tree Shaking&lt;/em&gt; es un término comúnmente usado en el contexto Javascript para la eliminación del código muerto. Él se apoya en la estructura estática de la sintaxis de modulo ES2015, esto es &lt;code&gt;import&lt;/code&gt; y &lt;code&gt;export&lt;/code&gt;...&lt;/p&gt;

&lt;p&gt;El lanzamiento de Webpack 2 vino con soporte para los módulos ES2015 (también conocido como módulos de armonía) junto a la detección de módulos exportados que no están siendo usados...&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h6&gt;
  
  
  Si eres completamente nuevo acerca de los 👉 &lt;a href="https://developer.mozilla.org/es/docs/Web/JavaScript/Guide/Modules"&gt;Módulos JS&lt;/a&gt;
&lt;/h6&gt;

&lt;h3&gt;
  
  
  Sin sintaxis de modulo ES6
&lt;/h3&gt;

&lt;p&gt;Una librería puede ser empaquetada con otro sistema de módulos diferente a ES6, un proceso de compilación pudo haberse implementado para soportar solo &lt;a href="https://nodejs.org/api/modules.html#modules_modules_commonjs_modules"&gt;CommonJS&lt;/a&gt; por ejemplo. Los proyectos escritos usando Javascript puro (sin procesos de transpiración (Babel, TypeScript)) que usan unicamente CommonJs para gestionar sus módulos es otro ejemplo.&lt;/p&gt;

&lt;p&gt;Así que, sin sintaxis ES6 significa no Tree Shaking. La única manera de tener un bundle saludable cuando se lidia con librerías sin soporte para la sintaxis de módulo ES6 es importar usando una técnica llamada cherry-picking, se necesita especificar la ruta absoluta al archivo que contiene la información que necesitamos.&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="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;small&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;common-js-lib/small&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;h4&gt;
  
  
  Inconvenientes del cherry-picking
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;Es necesario saber la ruta al modulo necesitado. (Tu IDE puede ayudar en esto)&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Es necesario especificar uno a uno los módulos requeridos, ej:&lt;br&gt;
&lt;/p&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;has&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;lodash/has&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;capitalize&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;lodash/capitalize&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;lastIndexOf&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;lodash/lastIndexOf&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;/li&gt;
&lt;li&gt;&lt;p&gt;Como autor de una librería, probablemente querrás un sistema de carpetas fácil de usar para detectar rápidamente algo en tu librería.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Puedes olvidar hacerlo y sin querer se hace el bundle innecesariamente más pesado. &lt;a href="https://eslint.org/docs/rules/no-restricted-imports"&gt;EsLint&lt;/a&gt; puede ayudarte a importar correctamente.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Test de Performance
&lt;/h2&gt;

&lt;p&gt;Teniendo la teoría aprendida decidí probar todo esto. Lo que hice fue crear algunas librerías con soporte para diferentes módulos, crear algunas aplicaciones front-end con Angular y React&lt;sup id="fnref1"&gt;1&lt;/sup&gt; para probar si Tree Shaking estaba realmente haciendo su trabajo.&lt;/p&gt;

&lt;p&gt;Las librerías creadas fueron simples, ellas exportan dos variables &lt;code&gt;small&lt;/code&gt; y &lt;code&gt;big&lt;/code&gt;. &lt;code&gt;small&lt;/code&gt; contiene un perro 🐕 (&lt;code&gt;small = '🐕'&lt;/code&gt;), pero &lt;code&gt;big&lt;/code&gt; tiene 1646400 perros (&lt;code&gt;big = '🐕🐕🐕🐕🐕🐕🐕🐕🐕...'&lt;/code&gt;). Esto hará que &lt;code&gt;big&lt;/code&gt; pese 6.3 megabytes.&lt;/p&gt;

&lt;p&gt;Únicamente será usado &lt;code&gt;small&lt;/code&gt; todo el tiempo, así que si &lt;code&gt;big&lt;/code&gt; logra escabullirse hasta el bundle se podrá notar de inmediato.&lt;/p&gt;

&lt;h3&gt;
  
  
  Bundle Saludable
&lt;/h3&gt;

&lt;p&gt;Así es como un bundle saludable se ve:&lt;br&gt;
&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--miW7B2fu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g0kar9uiffp7oi7pot3w.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--miW7B2fu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/g0kar9uiffp7oi7pot3w.png" alt="bundle saludable, de 211.78KB" width="808" height="502"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Bundle Oloroso 🤢
&lt;/h3&gt;

&lt;p&gt;El bundle oloroso! Puedes notar una gran caja blanca que representa el 96.7% de la aplicación: &lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--xWljwxf9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hpvw6wwvwfjpbjhf8fjp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xWljwxf9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/hpvw6wwvwfjpbjhf8fjp.png" alt="Bundle Oloroso, bundle de 6.49MB" width="808" height="502"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Los Resultados
&lt;/h3&gt;

&lt;p&gt;Los resultados fueron los esperados, si la libería tenía para ofrecer la sintaxis de módulos de ES6, Tree Shaking hará su trabajo. Si no, cherry-picking es el único camino hacia el bundle saludable.&lt;/p&gt;

&lt;p&gt;Aquí está el repositorio si son de los curiosos &lt;a href="https://github.com/dianjuar/how-to-import"&gt;dianjuar/how-to-import&lt;/a&gt;. Todo esto fue creado en un monorepo usando &lt;a href="https://nx.dev/"&gt;Nx&lt;/a&gt;, para simular la publicación del paquete en NPM se usó &lt;a href="https://github.com/wclr/yalc"&gt;yalc&lt;/a&gt;. El análisis del bundle fue hecho con &lt;a href="https://www.npmjs.com/package/source-map-explorer"&gt;source-map-explorer&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Yo también quise aplicar este test a algunas librerías conocidas y esto fue lo que encontré al importar de la siguiente manera &lt;code&gt;import { whatINeed } from 'popular-lib'&lt;/code&gt;&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Librería&lt;/th&gt;
&lt;th&gt;Bundle Saludable&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://www.npmjs.com/package/lodash"&gt;lodash&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://www.npmjs.com/package/moment"&gt;moment&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;❌&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://www.npmjs.com/package/rxjs"&gt;rxjs&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://www.npmjs.com/package/lodash-es"&gt;lodash-es&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://www.npmjs.com/package/date-fns"&gt;date-fns&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://www.npmjs.com/package/@angular/core"&gt;@angular/core&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://www.n-pmjs.com/package/@angular/material"&gt;@angular/material&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="http://www.npmjs.com/package/react"&gt;react&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="http://www.npmjs.com/package/react-dom"&gt;react-dom&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="http://www.npmjs.com/package/@material-ui/core"&gt;@material-ui/core&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="http://www.npmjs.com/package/@fortawesome/react-fontawesome"&gt;@fortawesome/react-fontawesome&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;✅&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Herramientas Útiles
&lt;/h2&gt;

&lt;p&gt;Durante este experimento estuve usando la extensión de VsCode &lt;a href="https://marketplace.visualstudio.com/items?itemName=wix.vscode-import-cost"&gt;Import Cost&lt;/a&gt; y fue precisa paralelamente con los resultados. Con esta extensión podrán ver de manera inmediata cuánto costará el import en el bundle. No dirá directamente si estás teniendo un bundle saludable o no, pero te darás cuenta cuándo un import es sospechoso.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://camo.githubusercontent.com/08af5550483d9e9ccee846ebdbcb74332bdb523a738be4cb5aec8e4ba7df49e8/68747470733a2f2f636974772e6465762f5f6e6578742f696d6167653f75726c3d253246706f737473253246696d706f72742d636f73742532463171756f76335446706747327572376d79434c477473412e67696626773d3130383026713d3735" class="article-body-image-wrapper"&gt;&lt;img src="https://camo.githubusercontent.com/08af5550483d9e9ccee846ebdbcb74332bdb523a738be4cb5aec8e4ba7df49e8/68747470733a2f2f636974772e6465762f5f6e6578742f696d6167653f75726c3d253246706f737473253246696d706f72742d636f73742532463171756f76335446706747327572376d79434c477473412e67696626773d3130383026713d3735" alt="Import Cost Live" width="838" height="146"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;h6&gt;
  
  
  Gif extraído del &lt;a href="https://github.com/wix/import-cost#import-cost--"&gt;README&lt;/a&gt; de Cost Import
&lt;/h6&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Conclusión
&lt;/h2&gt;

&lt;p&gt;Tree Shaking te tiene cubierto! Puedes importar como desees y siempre tendrás un bundle saludable &lt;strong&gt;si y solo si&lt;/strong&gt; la librería tiene soporte para la sintaxis de módulos de ES6 (&lt;code&gt;import&lt;/code&gt; y &lt;code&gt;export&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;Puedes hacer el bundle innecesariamente pesado si no haces cherry-pick al importar en librerías sin soporte de módulos ES6, como &lt;a href="https://www.npmjs.com/package/lodash"&gt;lodash&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://marketplace.visualstudio.com/items?itemName=wix.vscode-import-cost"&gt;Import Cost&lt;/a&gt; te puede ayudar a detectar un import que necesite algún refinamiento.&lt;/p&gt;







&lt;ol&gt;

&lt;li id="fn1"&gt;
&lt;p&gt;El experimento es agnóstico al framework o librería usada, si webpack está encargado de generar el bundle el resultado sería el mismo. ↩&lt;/p&gt;
&lt;/li&gt;

&lt;/ol&gt;

</description>
      <category>javascript</category>
      <category>typescript</category>
      <category>es6</category>
      <category>treeshaking</category>
    </item>
    <item>
      <title>Publish your libraries to NPM with one command (Angular and Nx)</title>
      <dc:creator>Diego Juliao</dc:creator>
      <pubDate>Mon, 10 May 2021 07:00:41 +0000</pubDate>
      <link>https://forem.com/dianjuar/publish-your-libraries-to-npm-with-one-command-angular-and-nx-4lao</link>
      <guid>https://forem.com/dianjuar/publish-your-libraries-to-npm-with-one-command-angular-and-nx-4lao</guid>
      <description>&lt;p&gt;To publish a library to NPM we have to do simple steps:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Build the library, compile it.&lt;/li&gt;
&lt;li&gt;Change the version that you want to publish on the library's package.json&lt;/li&gt;
&lt;li&gt;Run &lt;code&gt;npm publish&lt;/code&gt; on the folder of your built library&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This can be performed by hand or can be done by a couple of hours of creating a script that does the work for us to automate it. If we think about it, this is relatively easy to do but let's think about some considerations 🤔:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;What if we don't have only one library but several because we are using the mono-repo approach?&lt;/li&gt;
&lt;li&gt;What if is our fourth library and we are tired of writing/test/maintain the same thing over and over again?&lt;/li&gt;
&lt;li&gt;What if we just don't want or don't have the time and patience to do so 😅?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;With &lt;a href="https://www.npmjs.com/package/ngx-deploy-npm"&gt;ngx-deploy-npm&lt;/a&gt; you can publish any kind of library on your Angular or Nx workspace with just one command.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;By &lt;em&gt;any kind&lt;/em&gt; I mean literally &lt;strong&gt;any kind&lt;/strong&gt; of publishable library no matter the technology you use, Angular, React, Node, or NestJs 🚀.&lt;/p&gt;

&lt;p&gt;You just need to have your library on an &lt;a href="https://angular.io/"&gt;Angular&lt;/a&gt; or &lt;a href="https://nx.dev/"&gt;Nx&lt;/a&gt; workspace&lt;/p&gt;

&lt;h1&gt;
  
  
  TL;DR
&lt;/h1&gt;

&lt;p&gt;Supposing that you have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;An Angular or Nx workspace with a publishable library&lt;/li&gt;
&lt;li&gt;Already logged into NPM using &lt;code&gt;npm login&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Publish your package by:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Angular 🅰️&lt;/th&gt;
&lt;th&gt;Nx 🐬&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;pre&gt;# Install (made only once)&lt;br&gt;ng add ngx-deploy-npm&lt;br&gt;&lt;br&gt;# Publish&lt;br&gt;ng deploy your-library&lt;/pre&gt;&lt;/td&gt;
&lt;td&gt;&lt;pre&gt;# Install (made only once)&lt;br&gt;nx generate ngx-deploy-npm:install&lt;br&gt;&lt;br&gt;# Publish&lt;br&gt;nx deploy your-library&lt;/pre&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h1&gt;
  
  
  Publishing your library to NPM with &lt;code&gt;ngx-deploy-npm&lt;/code&gt;
&lt;/h1&gt;

&lt;h2&gt;
  
  
  Pre-steps
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Have a workspace, Angular or Nx (it won't variate too much between them)&lt;/li&gt;
&lt;li&gt;Have a publishable library in your workspace&lt;/li&gt;
&lt;li&gt;Being already logged into NPM, &lt;code&gt;npm login&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;No matter in which workspace you are, you have to do an &lt;strong&gt;installation&lt;/strong&gt; of the builder (only made once) and then you can execute it to &lt;strong&gt;publish&lt;/strong&gt; your library the times that you want.&lt;/p&gt;

&lt;h2&gt;
  
  
  Angular 🅰️
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Angular Installation
&lt;/h3&gt;

&lt;p&gt;First, we need to add this builder to our workspace, this can be done by just&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ng add ngx-deploy-npm
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is going to detect all our libraries and modify your &lt;code&gt;angular.json&lt;/code&gt; file to &lt;em&gt;"install"&lt;/em&gt; this builder. You will notice the architect &lt;code&gt;deploy&lt;/code&gt; was added to all our libraries on our workspace, it's going to look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"deploy"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"builder"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ngx-deploy-npm:deploy"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"options"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"access"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"public"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"buildTarget"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"production"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That is all the configuration needed to publish a package to NPM, now what’s left is the DEPLOY 🚀&lt;/p&gt;

&lt;h3&gt;
  
  
  Angular Publishing
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ng deploy YOUR-LIBRARY-NAME
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And done, your library is published to NPM 😊&lt;/p&gt;

&lt;h2&gt;
  
  
  Nx 🐬
&lt;/h2&gt;

&lt;p&gt;With an Nx workspace, the procedure doesn't change that much, you have to &lt;em&gt;"install"&lt;/em&gt; it first and then publish the times that you want.&lt;/p&gt;

&lt;h3&gt;
  
  
  Nx Installation
&lt;/h3&gt;

&lt;p&gt;It doesn't change that much from the Angular Installation. It takes the same effect and has the same goal, kind of &lt;em&gt;"install"&lt;/em&gt; the builder in your Nx Workspace by detecting all your publishable libraries (libraries that we created as such) and add the corresponding architect &lt;code&gt;deploy&lt;/code&gt; to all of them. It can be done by:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nx generate ngx-deploy-npm:init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Nx Publishing
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nx deploy YOUR-LIBRARY-NAME
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And done, your library is published to NPM 😊&lt;/p&gt;

&lt;h1&gt;
  
  
  Nice Features 🤩
&lt;/h1&gt;

&lt;p&gt;This is a wrapper of &lt;code&gt;npm publish&lt;/code&gt; so all the parameters are available with the same name.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;code&gt;--package-version&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;You can set the future version of your library just using the argument &lt;code&gt;--package-version&lt;/code&gt;, this will write the version that you passed on the &lt;code&gt;package.json&lt;/code&gt;. Really convenient when you have a version pattern in your workspace.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;code&gt;--build-target&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;With this parameter, you can select which environment to build your library. Really convenient for Angular libraries that due to IVY they have a production environment.&lt;/p&gt;

&lt;h2&gt;
  
  
  &lt;code&gt;--dry-run&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Will not execute any operation, just to see how it will go. Very convenient to test and visualize without performing any action.&lt;/p&gt;

&lt;h1&gt;
  
  
  Publishing to private repositories 🔒
&lt;/h1&gt;

&lt;p&gt;This builder is a wrapper of &lt;code&gt;npm publish&lt;/code&gt; so just by having a well configured &lt;code&gt;.npmrc&lt;/code&gt; file you can publish your packages anywhere. If you have the &lt;code&gt;.npmrc&lt;/code&gt; file pointing to a private npm repository &lt;code&gt;ngx-deploy-npm&lt;/code&gt; will publish your libraries there smoothly.&lt;/p&gt;

&lt;h1&gt;
  
  
  Accomplishments 🌟
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;🎉 &lt;code&gt;ngx-deploy-npm&lt;/code&gt; is being referenced on the Angular Official Documentation on &lt;a href="https://angular.io/guide/deployment#automatic-deployment-with-the-cli"&gt;automatic deployment with the cli&lt;/a&gt; section along with other builders.&lt;/li&gt;
&lt;li&gt;🎉 &lt;code&gt;ngx-deploy-npm&lt;/code&gt; is also referenced on &lt;a href="https://nx.dev/nx-community"&gt;Nx Plugins&lt;/a&gt; official page.&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;&lt;code&gt;ngx-deploy-npm&lt;/code&gt; is a tool that helps us to publish any kind of library to NPM just by one command if we have our libraries in an Angular or Nx Workspace. It helps us to automate the publishing process of our libraries making it really easy&lt;/p&gt;

</description>
      <category>angular</category>
      <category>nx</category>
      <category>npm</category>
      <category>devops</category>
    </item>
  </channel>
</rss>
