<?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: Mario</title>
    <description>The latest articles on DEV Community by Mario (@mariokandut).</description>
    <link>https://dev.to/mariokandut</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%2F55603%2F5091e319-7be4-413f-9913-4e21fa9516f2.png</url>
      <title>DEV Community: Mario</title>
      <link>https://dev.to/mariokandut</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mariokandut"/>
    <language>en</language>
    <item>
      <title>How to add husky to React</title>
      <dc:creator>Mario</dc:creator>
      <pubDate>Wed, 20 Sep 2023 00:00:00 +0000</pubDate>
      <link>https://dev.to/mariokandut/how-to-add-husky-to-react-1oha</link>
      <guid>https://dev.to/mariokandut/how-to-add-husky-to-react-1oha</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;This article is based on &lt;a href="https://github.com/typicode/husky/releases/tag/v8.0.1" rel="noopener noreferrer"&gt;Husky v8.0.1&lt;/a&gt; and &lt;a href="https://react.dev/reference/react" rel="noopener noreferrer"&gt;React v18.2.0&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Husky makes modern native Git hooks easy to use in your React project. You can use it to lint your commit messages, run tests, lint code, or many more when you commit or push.&lt;/p&gt;

&lt;p&gt;But what are Git hooks and how can you add husky to your project?&lt;/p&gt;

&lt;h2&gt;
  
  
  What are Git hooks?
&lt;/h2&gt;

&lt;p&gt;Git hooks are scripts/programs that you can set up to run at certain points in git's execution (git lifecycle). These points include different stages of a commit, like &lt;strong&gt;before a commit (pre-commit)&lt;/strong&gt; or &lt;strong&gt;after a commit (post-commit)&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Git hooks allow developers to enforce standards by automating other scripts to run those tasks, like run &lt;code&gt;npm test&lt;/code&gt; before a commit, or run &lt;code&gt;eslint&lt;/code&gt; to avoid eslint errors and warnings.&lt;/p&gt;

&lt;p&gt;Husky supports all Git hooks. You can find a list with all available Git hooks &lt;a href="https://git-scm.com/docs/githooks" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Add husky to your React project
&lt;/h2&gt;

&lt;p&gt;There are two ways to install husky in your project:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Automatic (recommended)&lt;/li&gt;
&lt;li&gt;Manual&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Automatic installation (recommended)
&lt;/h3&gt;

&lt;p&gt;The package &lt;a href="https://www.npmjs.com/package/husky-init" rel="noopener noreferrer"&gt;husky-init&lt;/a&gt; is used to quickly install and initialize a project with husky.&lt;/p&gt;

&lt;p&gt;From your project root, type the following commands (depending on your package manager) to install &lt;code&gt;husky&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Important:&lt;/strong&gt; If your &lt;code&gt;package.json&lt;/code&gt; is in a subdirectory, see how to set up a &lt;a href="https://typicode.github.io/husky/#/?id=custom-directory" rel="noopener noreferrer"&gt;custom directory&lt;/a&gt; with husky.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx husky-init &amp;amp;&amp;amp; npm install # npm
npx husky-init &amp;amp;&amp;amp; yarn # Yarn 1
yarn dlx husky-init --yarn2 &amp;amp;&amp;amp; yarn # Yarn 2+
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After successful execution of this script several things did happen:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A folder named &lt;code&gt;.husky&lt;/code&gt; in your project root has been added. It contains a file called &lt;code&gt;pre-commit&lt;/code&gt;, which is the initial pre-commit hook. And a folder &lt;code&gt;_&lt;/code&gt; which contains the automatically generated shell script for husky. (Do not commit this, see &lt;code&gt;.gitignore&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;package.json&lt;/code&gt; was modified, with a &lt;code&gt;prepare&lt;/code&gt; script and &lt;code&gt;husky&lt;/code&gt; was added as a devDependency.&lt;/li&gt;
&lt;li&gt;And your &lt;code&gt;package-lock.json&lt;/code&gt; was updated.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That's it, you are ready to use husky in your React project. 😀&lt;/p&gt;

&lt;h3&gt;
  
  
  Manually installation
&lt;/h3&gt;

&lt;p&gt;Three steps, though the outcome should be the same as with automatic installation.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Install husky
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install husky --save-dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Enable Git hooks
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx husky install
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;To automatically have Git hooks enabled after install, edit package.json
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm pkg set scripts.prepare="husky install"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Using hooks
&lt;/h2&gt;

&lt;p&gt;After a successful installation you should already have a &lt;code&gt;pre-commit&lt;/code&gt; hook installed.&lt;/p&gt;

&lt;p&gt;The content of the generated &lt;code&gt;pre-commit&lt;/code&gt; hook are:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

npm test
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This means that before every commit, the script &lt;code&gt;npm test&lt;/code&gt; is running. If the tests fail, you will get an error and, you can`t commit, unless you fix the tests. I think you see already how useful this can be in any size of project.&lt;/p&gt;

&lt;h3&gt;
  
  
  Create a hook
&lt;/h3&gt;

&lt;p&gt;The syntax to add a command to a hook or to create a new hook is:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;&lt;br&gt;
husky add &amp;lt;file&amp;gt; [cmd]&lt;br&gt;
&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;For example, you want to run &lt;code&gt;ng lint&lt;/code&gt; after &lt;code&gt;npm test&lt;/code&gt; in your &lt;code&gt;pre-commit&lt;/code&gt; hook.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;&lt;br&gt;
husky add .husky/pre-commit ng lint&lt;br&gt;
&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The pre-commit hook has been updated:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;`&lt;/p&gt;

&lt;h1&gt;
  
  
  !/usr/bin/env sh
&lt;/h1&gt;

&lt;p&gt;. "$(dirname -- "$0")/_/husky.sh"&lt;/p&gt;

&lt;p&gt;npm test&lt;br&gt;
ng lint&lt;br&gt;
`&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;🌟Congratulations🌟You have husky successfully installed and setup &lt;strong&gt;husky&lt;/strong&gt; in your React project.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Husky is a tool to use git hooks easily to automatically run scripts on git lifecycle events.&lt;/li&gt;
&lt;li&gt;For example: If you want to run a npm script, before code is committed use a &lt;code&gt;pre-commit&lt;/code&gt; hook.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thanks for reading and if you have any &lt;strong&gt;questions&lt;/strong&gt; , use the &lt;strong&gt;comment&lt;/strong&gt; function or &lt;strong&gt;send me a message&lt;/strong&gt; &lt;strong&gt;&lt;a href="https://www.twitter.com/mariokandut" rel="noopener noreferrer"&gt;@mariokandut&lt;/a&gt;&lt;/strong&gt;. If you want to know more about &lt;strong&gt;&lt;a href="https://www.mariokandut.com/tags/react" rel="noopener noreferrer"&gt;React&lt;/a&gt;&lt;/strong&gt;, have a look at these &lt;a href="https://www.mariokandut.com/tags/react" rel="noopener noreferrer"&gt;React Tutorials&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;References (and Big thanks):&lt;/strong&gt;&lt;a href="https://git-scm.com/docs/githooks" rel="noopener noreferrer"&gt;Git hooks&lt;/a&gt;,&lt;a href="https://react.dev/reference/react" rel="noopener noreferrer"&gt;React&lt;/a&gt;,&lt;a href="https://typicode.github.io/husky/#/" rel="noopener noreferrer"&gt;Husky&lt;/a&gt;,&lt;a href="https://www.npmjs.com/package/husky" rel="noopener noreferrer"&gt;NPM - husky&lt;/a&gt;&lt;/p&gt;

</description>
      <category>react</category>
      <category>cleancode</category>
    </item>
    <item>
      <title>Getting started with Webpack</title>
      <dc:creator>Mario</dc:creator>
      <pubDate>Tue, 19 Sep 2023 00:00:00 +0000</pubDate>
      <link>https://dev.to/mariokandut/getting-started-with-webpack-31f0</link>
      <guid>https://dev.to/mariokandut/getting-started-with-webpack-31f0</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;This article is based on &lt;strong&gt;Node v18.13.0&lt;/strong&gt; and &lt;strong&gt;webpack v5.8.2&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In a nutshell, &lt;strong&gt;webpack is a static module bundler&lt;/strong&gt; for modern JavaScript applications. When it processes the application, it builds a dependency graph and then combines every module your project needs into bundles, which are static assets to serve your content from.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;"Okay, but why do we need it and what are the benefits?"&lt;/em&gt;, you might be asking. Let's dive a bit deeper, and answer your questions.&lt;/p&gt;

&lt;h2&gt;
  
  
  What is Webpack?
&lt;/h2&gt;

&lt;p&gt;If you are around long enough in web development, you have noticed that websites are not written in plain HTMl with a bit of JavaScript anymore, they're often entirely built by JavaScript (or TypeScript), and often use SSR (Server Side Rendering). In that case, we have to &lt;strong&gt;bundle&lt;/strong&gt; , &lt;strong&gt;minify&lt;/strong&gt; , and &lt;strong&gt;transpile&lt;/strong&gt; the code into something browsers can understand, and this spot is where webpack comes in.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Webpack is a static module bundler for modern JavaScript applications.&lt;/strong&gt; When webpack processes your application, it internally builds a dependency graph from one or more entry points and then combines every module your project needs into one or more bundles, which are static assets to serve your content from.&lt;/p&gt;

&lt;p&gt;This bundling allows you to write the latest JavaScript with Babel or use TypeScript, and compile it into something cross-browser compatible minified. Webpack also allows you to import static assets into your JavaScript.&lt;/p&gt;

&lt;p&gt;In a development environment, webpack supplies you with a development server that can update modules and styles instantly when you save (hot reloading). For example &lt;code&gt;vue create&lt;/code&gt; and &lt;code&gt;create-react-app&lt;/code&gt; use webpack under the hood.&lt;/p&gt;

&lt;p&gt;Webpack can do much more than that, let's start with the basics to get familiar with the concepts. Have a look at the core concepts of webpack at the &lt;a href="https://webpack.js.org/concepts/" rel="noopener noreferrer"&gt;webpack docs&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Let's start with the basic setup of a mini project to practically illustrate why webpack is an essential tool. This sample is sourced from &lt;a href="https://webpack.js.org/guides/getting-started/#basic-setup" rel="noopener noreferrer"&gt;webpack&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Code example
&lt;/h3&gt;

&lt;p&gt;Create a webpack-demo folder and initialize npm and install webpack and the webpack-cli as devDependencies.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir webpack-demo
cd webpack-demo
npm init -y
npm install webpack webpack-cli --save-dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we'll create an &lt;code&gt;index.html&lt;/code&gt;file, a &lt;code&gt;src&lt;/code&gt; folder, and add an &lt;code&gt;index.js&lt;/code&gt; file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;touch index.html
mkdir src
cd src
touch index.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add this sample code to your &lt;code&gt;index.js&lt;/code&gt; file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;function component() {
  const element = document.createElement('div');

  element.innerHTML = _.join(['Hello', 'webpack'], ' ');

  return element;
}

document.body.appendChild(component());
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add this code to your &lt;code&gt;index.html&lt;/code&gt; file.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html&amp;gt;
  &amp;lt;head&amp;gt;
    &amp;lt;meta charset="utf-8" /&amp;gt;
    &amp;lt;title&amp;gt;Getting Started&amp;lt;/title&amp;gt;
    &amp;lt;script src="https://unpkg.com/lodash@4.17.20"&amp;gt;&amp;lt;/script&amp;gt;
  &amp;lt;/head&amp;gt;
  &amp;lt;body&amp;gt;
    &amp;lt;script src="./src/index.js"&amp;gt;&amp;lt;/script&amp;gt;
  &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We also need to adjust our &lt;code&gt;package.json&lt;/code&gt; file to mark our package as private and to remote the main entry. This is &lt;strong&gt;to prevent an accidental publish&lt;/strong&gt; of your code.&lt;/p&gt;

&lt;p&gt;The package.json should look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "name": "webpack-demo",
  "version": "1.0.0",
  "private": true,
  "scripts": {
    "test": "echo \"Error: no test specified\" &amp;amp;&amp;amp; exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "description": "",
  "devDependencies": {
    "webpack": "^5.88.2",
    "webpack-cli": "^5.1.4"
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now open the &lt;code&gt;index.html&lt;/code&gt; in your browser, you should see &lt;code&gt;hello webpack&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In this example, there are &lt;strong&gt;implicit dependencies&lt;/strong&gt; between the &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; tags. This means, that the &lt;code&gt;index.js&lt;/code&gt; file depends on &lt;code&gt;lodash&lt;/code&gt; being included before it runs. This is because index.js never explicitly declared a need for lodash; it assumes that the global variable &lt;code&gt;_&lt;/code&gt; exists.&lt;/p&gt;

&lt;p&gt;This approach can lead to serious problems:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It is not immediately apparent that the script depends on an external library.&lt;/li&gt;
&lt;li&gt;If a dependency is missing, or included in the wrong order, the application will not function properly.&lt;/li&gt;
&lt;li&gt;If a dependency is included but not used, the browser will be forced to download unnecessary code.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Don't worry. There is a solution to all these problems. Webpack can manage this instead, and create a bundle.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to create a bundle with webpack
&lt;/h2&gt;

&lt;p&gt;To create a bundle (in this example), we first have to &lt;strong&gt;separate our source code from the distribution code&lt;/strong&gt;. We create a &lt;code&gt;dist&lt;/code&gt; folder, and move the &lt;code&gt;index.html&lt;/code&gt; into this folder. (Please be aware, in a normal setup the index.html is created via webpack. This is only a quick showcase.)&lt;/p&gt;

&lt;p&gt;The &lt;strong&gt;source&lt;/strong&gt; code is the code that we'll write and edit, and the &lt;strong&gt;distribution&lt;/strong&gt; code is the minimized and optimized output of our build process that will be loaded in the browser.&lt;/p&gt;

&lt;p&gt;Create a dist folder and move the index.html into it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir dist
mv index.html dist/ # to move the index.html file into dist
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To bundle the &lt;code&gt;lodash&lt;/code&gt; dependency with &lt;code&gt;index.js&lt;/code&gt;, we'll need to install the library locally:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install lodash
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After installing it, lodash has to be imported. Add the following code to &lt;code&gt;index.js&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;import _ from 'lodash';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Since we are going to be bundling our scripts, we have to update our &lt;code&gt;index.html&lt;/code&gt; file and, remove the lodash &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt;, as we now import it as a dependency, and modify the other &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; tag to load the bundle, instead of the raw ./src file:&lt;/p&gt;

&lt;p&gt;Update the &lt;code&gt;index.html&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;&amp;lt;!DOCTYPE html&amp;gt;
&amp;lt;html&amp;gt;
  &amp;lt;head&amp;gt;
    &amp;lt;meta charset="utf-8" /&amp;gt;
    &amp;lt;title&amp;gt;Getting Started&amp;lt;/title&amp;gt;
  &amp;lt;/head&amp;gt;
  &amp;lt;body&amp;gt;
    &amp;lt;script src="main.js"&amp;gt;&amp;lt;/script&amp;gt;
  &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this setup, &lt;code&gt;index.js&lt;/code&gt; &lt;strong&gt;explicitly requires lodash&lt;/strong&gt; to be present, and binds it to &lt;code&gt;_&lt;/code&gt;. This means &lt;strong&gt;no global scope pollution&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;When you state what dependencies a module needs, webpack can use this to build a &lt;strong&gt;dependency graph&lt;/strong&gt;. Then the graph is used to generate an &lt;strong&gt;optimized bundle&lt;/strong&gt; , where scripts will be executed in the correct order.&lt;/p&gt;

&lt;p&gt;Let's run this application with &lt;code&gt;npx webpack&lt;/code&gt;. When you open the index.html in the dist folder in your browser. The output should be the same as before.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;npx webpack&lt;/code&gt; will take our script at &lt;code&gt;src/index.js&lt;/code&gt; as the entry point, and will generate &lt;code&gt;dist/main.js&lt;/code&gt; as the output. The npx command (Node v8.2 or higher), runs the webpack binary in &lt;code&gt;./node_modules/.bin/webpack&lt;/code&gt; from the installed webpack package.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Webpack is a static module bundler for modern JavaScript applications.&lt;/li&gt;
&lt;li&gt;Webpack builds a dependency graph from points and then combines every module your project needs into one or more bundles, which are static assets to serve your content from.&lt;/li&gt;
&lt;li&gt;Use webpack to bundle your application and don't worry about &lt;strong&gt;global scope pollution&lt;/strong&gt; , &lt;strong&gt;missing dependencies&lt;/strong&gt; , &lt;strong&gt;installed but not used dependencies&lt;/strong&gt; , &lt;strong&gt;wrong order of imports&lt;/strong&gt; or &lt;strong&gt;implicit dependencies&lt;/strong&gt; (which you are not aware of) anymore.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thanks for reading and if you have any &lt;strong&gt;questions&lt;/strong&gt; , use the &lt;strong&gt;comment&lt;/strong&gt; function or &lt;strong&gt;send me a message&lt;/strong&gt; &lt;strong&gt;&lt;a href="https://www.twitter.com/mariokandut" rel="noopener noreferrer"&gt;@mariokandut&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;If you want to know more about &lt;strong&gt;&lt;a href="https://www.mariokandut.com/tags/node" rel="noopener noreferrer"&gt;Node&lt;/a&gt;&lt;/strong&gt;, have a look at these &lt;a href="https://www.mariokandut.com/tags/node" rel="noopener noreferrer"&gt;Node Tutorials&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  References (and Big thanks):
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://webpack.js.org/guides/getting-started/" rel="noopener noreferrer"&gt;Webpack&lt;/a&gt;,&lt;a href="https://stackshare.io/webpack" rel="noopener noreferrer"&gt;StackShare&lt;/a&gt;,&lt;a href="https://nodejs.org" rel="noopener noreferrer"&gt;NodeJS&lt;/a&gt;,&lt;a href="https://docs.npmjs.com/" rel="noopener noreferrer"&gt;NPM&lt;/a&gt;,&lt;a href="https://www.smashingmagazine.com/2021/06/getting-started-webpack/" rel="noopener noreferrer"&gt;Smashing Magazine&lt;/a&gt;,&lt;a href="https://www.taniarascia.com/how-to-use-webpack" rel="noopener noreferrer"&gt;Tania Rascia&lt;/a&gt;&lt;/p&gt;

</description>
      <category>node</category>
      <category>typescript</category>
      <category>webpack</category>
    </item>
    <item>
      <title>How to list/debug npm packages?</title>
      <dc:creator>Mario</dc:creator>
      <pubDate>Mon, 18 Sep 2023 00:00:00 +0000</pubDate>
      <link>https://dev.to/mariokandut/how-to-listdebug-npm-packages-2o81</link>
      <guid>https://dev.to/mariokandut/how-to-listdebug-npm-packages-2o81</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;This article is based on &lt;strong&gt;Node v18.13.0&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Installing and uninstalling dependencies are a core part of working with any Node.js project or framework React, Angular, NextJS, Express, Vue, etc. But how do you list your installed dependencies? &lt;em&gt;If you are just starting with Node.js, have a look at the NodeJS intro article &lt;a href="https://www.mariokandut.com/how-to-install-npm-packages/" rel="noopener noreferrer"&gt;install node packages&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;If you work on different projects with different environments and different node versions, surely, some effort is needed to manage this, and version conflicts are anything but nice. For example, globally installed dependencies, can cause version issues in your project, if you use a wrong version. Or you are currently in the process of a major update in a project, and try to upgrade the dependencies, and all of a sudden you get an error when installing. Most likely, &lt;code&gt;npm ERR! Invalid version&lt;/code&gt; in the log after running &lt;code&gt;npm install&lt;/code&gt;. Then you have to start to debug and the fun starts.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to fix version conflicts in installed NPM Packages?
&lt;/h2&gt;

&lt;p&gt;The first step when facing version issues with installed packages is to &lt;strong&gt;delete and reinstall&lt;/strong&gt;.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Clean the &lt;code&gt;node_modules&lt;/code&gt; folder &lt;code&gt;rm -r node_modules&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Re-install packages with &lt;code&gt;npm install&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If the issue still persists &lt;strong&gt;clean NPM cache&lt;/strong&gt;. You can forcefully clean the NPM cache with &lt;code&gt;npm cache clean --force&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;In a lot of cases, the issue is resolved now. If it isn't, you have to start debugging. First you have to list your installed packages&lt;/p&gt;

&lt;h2&gt;
  
  
  How to list installed NPM Packages?
&lt;/h2&gt;

&lt;p&gt;The first step is the &lt;a href="https://docs.npmjs.com/cli/v10/commands/npm-ls?v=true" rel="noopener noreferrer"&gt;NPM&lt;/a&gt;, you are going to look for the &lt;code&gt;npm ls&lt;/code&gt; command.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;npm ls [[&amp;lt;@scope&amp;gt;/]&amp;lt;pkg&amp;gt; ...]&lt;/code&gt; will print to stdout all the versions of packages that are installed, as well as their dependencies when --all is specified, in a tree structure.&lt;/p&gt;

&lt;p&gt;Let's create a small project and see what it prints out to stdout. Create a project with npm init and install a single dependency &lt;code&gt;express&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;mkdir npm-ls-test
cd npm-ls-test
npm init -y
npm i express
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you then run &lt;code&gt;npm ls&lt;/code&gt; in the sample project folder, you will get the entire packages installed, when you install &lt;code&gt;express&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;npm-ls-test@1.0.0
└─┬ express@4.18.2
  ├─┬ accepts@1.3.8
  │ ├─┬ mime-types@2.1.35
  │ │ └── mime-db@1.52.0
  │ └── negotiator@0.6.3
  ├── array-flatten@1.1.1
  ├─┬ body-parser@1.20.1
  │ ├── bytes@3.1.2
  │ ├── content-type@1.0.5 deduped
  │ ├── debug@2.6.9 deduped
  │ ├── depd@2.0.0 deduped
  │ ├── destroy@1.2.0
  │ ├── http-errors@2.0.0 deduped
  │ ├─┬ iconv-lite@0.4.24
  │ │ └── safer-buffer@2.1.2
  │ ├── on-finished@2.4.1 deduped
  │ ├── qs@6.11.0 deduped
  │ ├─┬ raw-body@2.5.1
  │ │ ├── bytes@3.1.2 deduped
  │ │ ├── http-errors@2.0.0 deduped
  │ │ ├── iconv-lite@0.4.24 deduped
  │ │ └── unpipe@1.0.0 deduped
  │ ├── type-is@1.6.18 deduped
  │ └── unpipe@1.0.0
  ├─┬ content-disposition@0.5.4
  │ └── safe-buffer@5.2.1 deduped
  ├── content-type@1.0.5
  ├── cookie@0.5.0
  ├── cookie-signature@1.0.6
  ├─┬ debug@2.6.9
  │ └── ms@2.0.0
  ├── depd@2.0.0
  ├── encodeurl@1.0.2
  ├── escape-html@1.0.3
  ├── etag@1.8.1
  ├─┬ finalhandler@1.2.0
  │ ├── debug@2.6.9 deduped
  │ ├── encodeurl@1.0.2 deduped
  │ ├── escape-html@1.0.3 deduped
  │ ├── on-finished@2.4.1 deduped
  │ ├── parseurl@1.3.3 deduped
  │ ├── statuses@2.0.1 deduped
  │ └── unpipe@1.0.0 deduped
  ├── fresh@0.5.2
  ├─┬ http-errors@2.0.0
  │ ├── depd@2.0.0 deduped
  │ ├── inherits@2.0.4
  │ ├── setprototypeof@1.2.0 deduped
  │ ├── statuses@2.0.1 deduped
  │ └── toidentifier@1.0.1
  ├── merge-descriptors@1.0.1
  ├── methods@1.1.2
  ├─┬ on-finished@2.4.1
  │ └── ee-first@1.1.1
  ├── parseurl@1.3.3
  ├── path-to-regexp@0.1.7
  ├─┬ proxy-addr@2.0.7
  │ ├── forwarded@0.2.0
  │ └── ipaddr.js@1.9.1
  ├─┬ qs@6.11.0
  │ └─┬ side-channel@1.0.4
  │ ├─┬ call-bind@1.0.2
  │ │ ├── function-bind@1.1.1
  │ │ └── get-intrinsic@1.2.1 deduped
  │ ├─┬ get-intrinsic@1.2.1
  │ │ ├── function-bind@1.1.1 deduped
  │ │ ├─┬ has@1.0.3
  │ │ │ └── function-bind@1.1.1 deduped
  │ │ ├── has-proto@1.0.1
  │ │ └── has-symbols@1.0.3
  │ └── object-inspect@1.12.3
  ├── range-parser@1.2.1
  ├── safe-buffer@5.2.1
  ├─┬ send@0.18.0
  │ ├── debug@2.6.9 deduped
  │ ├── depd@2.0.0 deduped
  │ ├── destroy@1.2.0 deduped
  │ ├── encodeurl@1.0.2 deduped
  │ ├── escape-html@1.0.3 deduped
  │ ├── etag@1.8.1 deduped
  │ ├── fresh@0.5.2 deduped
  │ ├── http-errors@2.0.0 deduped
  │ ├── mime@1.6.0
  │ ├── ms@2.1.3
  │ ├── on-finished@2.4.1 deduped
  │ ├── range-parser@1.2.1 deduped
  │ └── statuses@2.0.1 deduped
  ├─┬ serve-static@1.15.0
  │ ├── encodeurl@1.0.2 deduped
  │ ├── escape-html@1.0.3 deduped
  │ ├── parseurl@1.3.3 deduped
  │ └── send@0.18.0 deduped
  ├── setprototypeof@1.2.0
  ├── statuses@2.0.1
  ├─┬ type-is@1.6.18
  │ ├── media-typer@0.3.0
  │ └── mime-types@2.1.35 deduped
  ├── utils-merge@1.0.1
  └── vary@1.1.2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Without an argument &lt;code&gt;npm ls&lt;/code&gt; lists all the dependencies down the dependency tree. If you are just interested in for example &lt;code&gt;serve-static&lt;/code&gt;, you have to add an argument in the format &lt;code&gt;name@version-range&lt;/code&gt;. Hence, you would do &lt;code&gt;npm ls serve-static@1.15.0&lt;/code&gt;. The stdout will be only for this package.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm-ls-test@1.0.0
└─┬ express@4.18.2
  └── serve-static@1.15.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you want to specify the depth in the dependency tree, add an argument for &lt;code&gt;depth&lt;/code&gt;. The default level is infinity, which makes the stdout quite long. The stdout for &lt;code&gt;npm-ls-test npm ls --depth=1&lt;/code&gt;, is only one level deep.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm-ls-test@1.0.0
└─┬ express@4.18.2
  ├── accepts@1.3.8
  ├── array-flatten@1.1.1
  ├── body-parser@1.20.1
  ├── content-disposition@0.5.4
  ├── content-type@1.0.5
  ├── cookie@0.5.0
  ├── cookie-signature@1.0.6
  ├── debug@2.6.9
  ├── depd@2.0.0
  ├── encodeurl@1.0.2
  ├── escape-html@1.0.3
  ├── etag@1.8.1
  ├── finalhandler@1.2.0
  ├── fresh@0.5.2
  ├── http-errors@2.0.0
  ├── merge-descriptors@1.0.1
  ├── methods@1.1.2
  ├── on-finished@2.4.1
  ├── parseurl@1.3.3
  ├── path-to-regexp@0.1.7
  ├── proxy-addr@2.0.7
  ├── qs@6.11.0
  ├── range-parser@1.2.1
  ├── safe-buffer@5.2.1
  ├── send@0.18.0
  ├── serve-static@1.15.0
  ├── setprototypeof@1.2.0
  ├── statuses@2.0.1
  ├── type-is@1.6.18
  ├── utils-merge@1.0.1
  └── vary@1.1.2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you have found the culprit package, which causes the version conflict, and re-installing and cleaning the cache didn't resolve it, you can use the &lt;code&gt;overrides&lt;/code&gt; section in the &lt;code&gt;package.json&lt;/code&gt; to make changes to a specific package, see &lt;a href="https://docs.npmjs.com/cli/v10/configuring-npm/package-json?v=true" rel="noopener noreferrer"&gt;NPM&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;For example, we want to use a specific version for &lt;code&gt;super-nice-package&lt;/code&gt;, we can simply add the following code to the package.json.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "overrides": {
    "super-nice-package": "12.15.1"
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Version conflicts can also arise when for example a maintainer of a package is lacking a bit behind another major package. Usually, after some time, the maintainer updates it, and the version conflicts get resolved, but until this happens, you can use the &lt;code&gt;overrides&lt;/code&gt; method.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Be aware&lt;/strong&gt; , to regularly update your project, and &lt;strong&gt;remove the overrides&lt;/strong&gt; , if possible.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to list installed globally packages?
&lt;/h2&gt;

&lt;p&gt;You can list globally installed packages with &lt;code&gt;npm ls --global&lt;/code&gt; or &lt;code&gt;npm ls -g&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;For example, if you use &lt;code&gt;nvm&lt;/code&gt;, the output should look something like this. In this example I used &lt;code&gt;npm ls -g --depth=0&lt;/code&gt; to list my global installed packages.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/PATH/.nvm/versions/node/v18.13.0/lib
├── @angular/cli@15.1.4
├── corepack@0.15.2
├── gatsby-cli@5.8.0
├── npm@8.19.3
└── serve@14.2.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Please be aware, that if you have to change a globally installed package for whatever reason (update cycle, security fixes, license updates, etc.) within a team of multiple developers, you have to communicate this to every relevant person.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;The NPM CLI has a built-in command to list dependencies &lt;code&gt;npm ls&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;You can use the &lt;code&gt;overrides&lt;/code&gt; section in the &lt;code&gt;package.json&lt;/code&gt; to override specific dependencies.&lt;/li&gt;
&lt;li&gt;When facing version conflicts, remove and reinstall dependencies, and/or forcefully clean the npm cache to fix it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thanks for reading and if you have any &lt;strong&gt;questions&lt;/strong&gt; , use the &lt;strong&gt;comment&lt;/strong&gt; function or &lt;strong&gt;send me a message&lt;/strong&gt; &lt;strong&gt;&lt;a href="https://www.twitter.com/mariokandut" rel="noopener noreferrer"&gt;@mariokandut&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;If you want to know more about &lt;strong&gt;&lt;a href="https://www.mariokandut.com/tags/node" rel="noopener noreferrer"&gt;Node&lt;/a&gt;&lt;/strong&gt;, have a look at these &lt;a href="https://www.mariokandut.com/tags/node" rel="noopener noreferrer"&gt;Node Tutorials&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  References (and Big thanks):
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://nodejs.org" rel="noopener noreferrer"&gt;NodeJS&lt;/a&gt;,&lt;a href="https://docs.npmjs.com/cli/v10/commands/npm-ls?v=true" rel="noopener noreferrer"&gt;NPM&lt;/a&gt;,&lt;a href="https://weekendprojects.dev/posts/how-to-fix-npm-err-invalid-version/#why-are-we-getting-this-error" rel="noopener noreferrer"&gt;Kentaro&lt;/a&gt;&lt;/p&gt;

</description>
      <category>node</category>
      <category>npm</category>
      <category>react</category>
    </item>
    <item>
      <title>How to specify a Node.js version</title>
      <dc:creator>Mario</dc:creator>
      <pubDate>Tue, 28 Mar 2023 00:00:00 +0000</pubDate>
      <link>https://dev.to/mariokandut/how-to-specify-a-nodejs-version-3dgf</link>
      <guid>https://dev.to/mariokandut/how-to-specify-a-nodejs-version-3dgf</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;This article is based on &lt;strong&gt;Node v18.13.0&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Specifying a Node.js version is important, to reduce issues, especially when working in a big team. There are many more factors to consider, like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Compatibility&lt;/strong&gt; : Different Node.js versions have different features and capabilities.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Stability&lt;/strong&gt; : The Node.js ecosystem is moving fast, and new major releases can introduce breaking changes.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Reproducibility&lt;/strong&gt; : It's easier to reproduce if the version is specified. For example: If every user in your project has the same version of Node.js you can easier reproduce bugs and solve issues. Also, when you are working on multiple projects, with different node.js versions, it would be a requirement to specify the version.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dependencies&lt;/strong&gt; : Third-party dependencies require a specific node.js version to work properly. A different version can introduce issues with these dependencies.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Your Single-Page-Application or Node.js Application should be stable, compatible and reliable. Hence, specify the Node.js version and save yourself some headaches.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to specify your Node.js version?
&lt;/h2&gt;

&lt;p&gt;There are several ways to specify a version. You can add a configuration file for NVM or extend &lt;code&gt;package.json&lt;/code&gt; or you write a custom script.&lt;/p&gt;

&lt;h3&gt;
  
  
  How to specify Node.js when using NVM?
&lt;/h3&gt;

&lt;p&gt;If you installed node with NVM, &lt;a href="https://www.mariokandut.com/how-to-install-node-js-with-nvm-node-version-manager/" rel="noopener noreferrer"&gt;how to install node.js with NVM&lt;/a&gt;, you can simply add a configuration file at the root of your project. This file will also be checked into git, so you can track it.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create a file &lt;code&gt;.nvmrc&lt;/code&gt; at the root of your project.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;touch .nvmrc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Add the required Node.js version to it.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;If you are already using the required version&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;node -v &amp;gt; .nvmrc
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Otherwise, you can specify it directly in the file, use a text editor of your choice&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Use the &lt;code&gt;nvm use&lt;/code&gt; command to tell NVM to use node version in the configuration file. After using the command the output should be similar to this.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Found '.nvmrc' with version &amp;lt;v18.13.0&amp;gt;
Now using node v18.13.0 (npm v8.19.3)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This approach will not create a warning, when installing dependencies. You have to update your &lt;code&gt;README&lt;/code&gt; and inform your team members about the change.&lt;/p&gt;

&lt;h3&gt;
  
  
  How to specify Node.js version in NPM?
&lt;/h3&gt;

&lt;p&gt;To specify a Node.js version, you can simply add an &lt;code&gt;engines&lt;/code&gt; field in your &lt;code&gt;package.json&lt;/code&gt;. See &lt;a href="https://docs.npmjs.com/cli/v9/configuring-npm/package-json" rel="noopener noreferrer"&gt;NPM docs&lt;/a&gt;. Until NPMv3, it was possible to create an &lt;code&gt;.npmrc&lt;/code&gt; file to enable &lt;code&gt;engine-strict=true&lt;/code&gt; so that it would throw an error when installing dependencies while being on the wrong node.js version. Now, it will not throw an error, but show in the console a warning.&lt;/p&gt;

&lt;p&gt;Open your &lt;code&gt;package.json&lt;/code&gt;, add the &lt;code&gt;"engines"&lt;/code&gt; field and specify the &lt;code&gt;node&lt;/code&gt; version. You can use &lt;strong&gt;semver&lt;/strong&gt; to include version ranges or specific limits.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "engines": {
    "node": "&amp;gt;=16.0.0 &amp;lt;17.0.0"
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Unfortunately, this will only create warning when installing the dependencies. Hence, you have to update your &lt;code&gt;README&lt;/code&gt; and inform your team members about the change.&lt;/p&gt;

&lt;h3&gt;
  
  
  How to specify Node.js version with a custom script?
&lt;/h3&gt;

&lt;p&gt;A good approach would be to combine setting the &lt;code&gt;engine&lt;/code&gt; field in your &lt;code&gt;package.json&lt;/code&gt; and check if the current node version is within the version range. To do this we can write a simple script in five steps.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Specify your desired node version in package.json.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "engines": {
    "node": "&amp;gt;=18.0.0"
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Add a custom &lt;code&gt;engineStrict&lt;/code&gt; field to your package.json and set it to true. This field will be read in our custom script. If it's true the script will be executed.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "engineStrict": true
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Install &lt;code&gt;semver&lt;/code&gt; and create a file &lt;code&gt;check-node-version.js&lt;/code&gt;.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm i semver
touch check-node-version.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Now, compare the node version in the process with the set version in the engines field. To satisfy semver we can use the &lt;code&gt;semver&lt;/code&gt; package.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const semver = require('semver');
const engines = require('./package').engines;

const version = engines.node;
if (!semver.satisfies(process.version, version)) {
  console.log(
    `Required node version ${version} not satisfied with current version ${process.version}.`,
  );
  process.exit(1);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Update your &lt;code&gt;package.json&lt;/code&gt; with a &lt;code&gt;preinstall&lt;/code&gt; step and a &lt;code&gt;check-node-version&lt;/code&gt; script.
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "check-node-version": "node check-node-version.js",
  "preinstall": "npm run check-node-version"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And that's it. If you run &lt;code&gt;npm i&lt;/code&gt; in your project, and you are on different Node version than specified, the process will exit.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to specify the Node.js version in React or Angular?
&lt;/h2&gt;

&lt;p&gt;All three approaches from above can be used in React or Angular.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Your Single-Page-Application or Node.js Application should be stable, compatible and reliable. Hence, specify the Node.js version and save yourself some headaches.&lt;/li&gt;
&lt;li&gt;Create a file &lt;code&gt;.nvmrc&lt;/code&gt; at the root of your project, specify version and use with &lt;code&gt;nvm use&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Add &lt;code&gt;engines&lt;/code&gt; field in &lt;code&gt;package.json&lt;/code&gt; and specify Node.js version.&lt;/li&gt;
&lt;li&gt;Write a small custom script to compare &lt;code&gt;engines&lt;/code&gt; field with Node process and exit if it's not within specified semver range.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thanks for reading and if you have any &lt;strong&gt;questions&lt;/strong&gt; , use the &lt;strong&gt;comment&lt;/strong&gt; function or &lt;strong&gt;send me a message&lt;/strong&gt; &lt;strong&gt;&lt;a href="https://www.twitter.com/mariokandut" rel="noopener noreferrer"&gt;@mariokandut&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;If you want to know more about &lt;strong&gt;&lt;a href="https://www.mariokandut.com/tags/node" rel="noopener noreferrer"&gt;Node&lt;/a&gt;&lt;/strong&gt;, have a look at these &lt;a href="https://www.mariokandut.com/tags/node" rel="noopener noreferrer"&gt;Node Tutorials&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  References (and Big thanks):
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://nodejs.org" rel="noopener noreferrer"&gt;NodeJS&lt;/a&gt;,&lt;a href="https://docs.npmjs.com/cli/v9/configuring-npm/package-json" rel="noopener noreferrer"&gt;NPM&lt;/a&gt;,&lt;a href="https://medium.com/@adambisek/how-to-check-minimum-required-node-js-version-4a78a8855a0f" rel="noopener noreferrer"&gt;Adam Bisek&lt;/a&gt;&lt;/p&gt;

</description>
      <category>node</category>
      <category>javascript</category>
      <category>typescript</category>
      <category>npm</category>
    </item>
    <item>
      <title>How to use fontawesome - Angular</title>
      <dc:creator>Mario</dc:creator>
      <pubDate>Mon, 20 Mar 2023 00:00:00 +0000</pubDate>
      <link>https://dev.to/mariokandut/how-to-use-fontawesome-angular-55gd</link>
      <guid>https://dev.to/mariokandut/how-to-use-fontawesome-angular-55gd</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;This article is based on Angular CLI 15.1.4, Node 18.13.0, npm 8.19.3&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://fontawesome.com/" rel="noopener noreferrer"&gt;FontAwesome&lt;/a&gt; is a popular icon library that provides scalable vector icons. It's easy to use FontAwesome in Angular with the &lt;code&gt;@fortawesome/angular-fontawesome&lt;/code&gt; package, which provides Angular components for FontAwesome icons. This article is about how to use fontawesome in your Angular project.&lt;/p&gt;

&lt;p&gt;If you want to know how to install, head over to &lt;a href="https://www.mariokandut.com/how-to-add-fontawesome-to-your-angular-project/" rel="noopener noreferrer"&gt;How to install fontawesome in Angular&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to use fontawesome 5+ in Angular 15?
&lt;/h2&gt;

&lt;p&gt;After successfully installing fontawesome in your Angular project. Follow these three steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Add the &lt;code&gt;FontAwesomeModule&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Tie the icon to the property in your component&lt;/li&gt;
&lt;li&gt;Use the icon in your template.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  1. Add the module in &lt;code&gt;app.module.ts&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Add &lt;code&gt;FontAwesomeModule&lt;/code&gt; to &lt;code&gt;imports&lt;/code&gt; in &lt;code&gt;src/app/app.module.ts&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;import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppComponent } from './app.component';
import { FontAwesomeModule } from '@fortawesome/angular-fontawesome';

@NgModule({
  imports: [BrowserModule, FontAwesomeModule],
  declarations: [AppComponent],
  bootstrap: [AppComponent],
})
export class AppModule {}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Tie the icon to the property in your component
&lt;/h3&gt;

&lt;p&gt;Bind the icon you want to use to a variable in the component, where the icon should be used, for example &lt;code&gt;src/app/app.component.ts&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;import { Component } from '@angular/core';
import { faCoffee } from '@fortawesome/free-solid-svg-icons';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
})
export class AppComponent {
  faCoffee = faCoffee;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Use the icon in your template
&lt;/h3&gt;

&lt;p&gt;Provide the icon to the &lt;code&gt;icon&lt;/code&gt; property in &lt;code&gt;fa-icon&lt;/code&gt; component.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;fa-icon [icon]="faCoffee"&amp;gt;&amp;lt;/fa-icon&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Instead of using property binding you can also supply an array with string values directly in your template. This is useful when layering icons, see &lt;a href="https://fontawesome.com/docs/web/style/layer" rel="noopener noreferrer"&gt;Fontawesome Docs - Layering&lt;/a&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;fa-layers [fixedWidth]="true"&amp;gt;
  &amp;lt;fa-icon [icon]="['fas', 'square']"&amp;gt;&amp;lt;/fa-icon&amp;gt;
  &amp;lt;fa-icon
    [inverse]="true"
    [icon]="['fas', 'spinner']"
    transform="shrink-6"
  &amp;gt;&amp;lt;/fa-icon&amp;gt;
&amp;lt;/fa-layers&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



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

&lt;ul&gt;
&lt;li&gt;To use Font Awesome in Angular,&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thanks for reading and if you have any &lt;strong&gt;questions&lt;/strong&gt; , use the &lt;strong&gt;comment&lt;/strong&gt; function or &lt;strong&gt;send me a message&lt;/strong&gt; &lt;strong&gt;&lt;a href="https://www.twitter.com/mariokandut" rel="noopener noreferrer"&gt;@mariokandut&lt;/a&gt;&lt;/strong&gt;. If you want to know more about &lt;strong&gt;&lt;a href="https://www.mariokandut.com/tags/angular" rel="noopener noreferrer"&gt;Angular&lt;/a&gt;&lt;/strong&gt;, have a look at these &lt;a href="https://www.mariokandut.com/tags/angular" rel="noopener noreferrer"&gt;Angular Tutorials&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;References (and Big thanks):&lt;/strong&gt;&lt;a href="https://angular.io/docs" rel="noopener noreferrer"&gt;Angular&lt;/a&gt;,&lt;a href="https://fontawesome.com/" rel="noopener noreferrer"&gt;fontawesome&lt;/a&gt;&lt;a href="https://www.npmjs.com/package/@fortawesome/angular-fontawesome" rel="noopener noreferrer"&gt;Angular Component for Font Awesome&lt;/a&gt;&lt;/p&gt;

</description>
      <category>angular</category>
      <category>styles</category>
    </item>
    <item>
      <title>How to add fontawesome - Angular</title>
      <dc:creator>Mario</dc:creator>
      <pubDate>Sun, 12 Mar 2023 00:00:00 +0000</pubDate>
      <link>https://dev.to/mariokandut/how-to-add-fontawesome-angular-5dj8</link>
      <guid>https://dev.to/mariokandut/how-to-add-fontawesome-angular-5dj8</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;This article is based on Angular CLI 15.1.4, Node 18.13.0, npm 8.19.3&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Font Awesome is the Internet's icon library and toolkit, used by millions of designers, developers, and content creators, see &lt;a href="https://fontawesome.com/" rel="noopener noreferrer"&gt;fontawesome&lt;/a&gt;. It has two versions, pro(paid) and free. The pro version gives you more icons and human support and has slightly different installation procedure. This article is about different methods on how to install fontawesome version (free) in your Angular project.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to add fontawesome 5+ in Angular 15?
&lt;/h2&gt;

&lt;p&gt;The preferred way to add Font Awesome to Angular is via the officially supported &lt;a href="https://www.npmjs.com/package/@fortawesome/angular-fontawesome" rel="noopener noreferrer"&gt;Angular Component for Font Awesome 5+&lt;/a&gt;. This makes the installation easy and should be done in no time.&lt;/p&gt;

&lt;p&gt;You have three options to add this NPM package:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Use &lt;code&gt;ng add&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;yarn&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;npm&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;To illustrate I'll start with an empty Angular project. Hence, let's create an empty Angular project&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ng new angular-fontawesome
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Use &lt;code&gt;ng add&lt;/code&gt; to install Font Awesome
&lt;/h3&gt;

&lt;p&gt;Angular CLI has a feature to easily add support for external libraries in your project &lt;code&gt;ng add&lt;/code&gt;. This was introduced in Angular v7.&lt;/p&gt;

&lt;p&gt;Simply install the fontawesome Angular component for Angular 15. This would be version &lt;strong&gt;0.12.x&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Go to your project root and run.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ng add @fortawesome/angular-fontawesome@0.12
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After running this command, you will be prompted:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;To choose the fontawesome version &lt;strong&gt;Font Awesome 5 or Font Awesome 6&lt;/strong&gt;. Choose version 6.&lt;/li&gt;
&lt;li&gt;The next prompt will be the icon packages you want to use. Choose the packages (SPACE for selecting) confirm with ENTER. The free options are: &lt;strong&gt;Free Solid Icons, Free Regular Icons, Free Brands Icons&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;And that's it.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;You have &lt;strong&gt;successfully installed Font Awesome&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Use &lt;code&gt;npm i&lt;/code&gt; to install Font Awesome
&lt;/h3&gt;

&lt;p&gt;If you use &lt;code&gt;npm&lt;/code&gt; in your project, and can't use the Angular CLI with &lt;code&gt;ng add&lt;/code&gt;. You can manually add the packages. Choose directly the packages you want to install.&lt;/p&gt;

&lt;p&gt;Go to your project root and install the main package:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install @fortawesome/angular-fontawesome@0.12
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add the icon packages you want to install:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install @fortawesome/fontawesome-svg-core
npm install @fortawesome/free-solid-svg-icons
npm install @fortawesome/free-brands-svg-icons
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To install everything at once:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install @fortawesome/angular-fontawesome@0.12 @fortawesome/fontawesome-svg-core @fortawesome/free-solid-svg-icons @fortawesome/free-brands-svg-icons
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And that's it. You have &lt;strong&gt;successfully installed Font Awesome&lt;/strong&gt; with &lt;code&gt;npm&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Use &lt;code&gt;yarn add&lt;/code&gt; to install Font Awesome
&lt;/h3&gt;

&lt;p&gt;If you use &lt;code&gt;yarn&lt;/code&gt; in your project, and can't use the Angular CLI with &lt;code&gt;ng add&lt;/code&gt;, add the packages manually.&lt;/p&gt;

&lt;p&gt;Go to your project root and install the main package:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yarn add @fortawesome/angular-fontawesome@0.12
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add the icon packages you want to install:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yarn add @fortawesome/fontawesome-svg-core
yarn add @fortawesome/free-solid-svg-icons
yarn add @fortawesome/free-brands-svg-icons
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To install everything at once:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;yarn add @fortawesome/angular-fontawesome@0.12 @fortawesome/fontawesome-svg-core @fortawesome/free-solid-svg-icons @fortawesome/free-brands-svg-icons
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And that's it. You have &lt;strong&gt;successfully installed Font Awesome&lt;/strong&gt; with &lt;code&gt;yarn&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to add fontawesome to Angular versions 5 to 14?
&lt;/h2&gt;

&lt;p&gt;If you are on a lower version than Angular 15, you have to check the compatibility table to see which version of &lt;code&gt;@fortawesome/angular-fontawesome&lt;/code&gt; you can use. Installation with the official package is supported from Angular 9 ongoing.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;@fortawesome/angular-fontawesome&lt;/th&gt;
&lt;th&gt;Angular&lt;/th&gt;
&lt;th&gt;Font Awesome&lt;/th&gt;
&lt;th&gt;ng-add&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;0.1.x&lt;/td&gt;
&lt;td&gt;5.x&lt;/td&gt;
&lt;td&gt;5.x&lt;/td&gt;
&lt;td&gt;not supported&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0.2.x&lt;/td&gt;
&lt;td&gt;6.x&lt;/td&gt;
&lt;td&gt;5.x&lt;/td&gt;
&lt;td&gt;not supported&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0.3.x&lt;/td&gt;
&lt;td&gt;6.x &amp;amp;&amp;amp; 7.x&lt;/td&gt;
&lt;td&gt;5.x&lt;/td&gt;
&lt;td&gt;not supported&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0.4.x, 0.5.x&lt;/td&gt;
&lt;td&gt;8.x&lt;/td&gt;
&lt;td&gt;5.x&lt;/td&gt;
&lt;td&gt;not supported&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0.6.x&lt;/td&gt;
&lt;td&gt;9.x&lt;/td&gt;
&lt;td&gt;5.x&lt;/td&gt;
&lt;td&gt;supported&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0.7.x&lt;/td&gt;
&lt;td&gt;10.x&lt;/td&gt;
&lt;td&gt;5.x&lt;/td&gt;
&lt;td&gt;supported&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0.8.x&lt;/td&gt;
&lt;td&gt;11.x&lt;/td&gt;
&lt;td&gt;5.x&lt;/td&gt;
&lt;td&gt;supported&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0.9.x&lt;/td&gt;
&lt;td&gt;12.x&lt;/td&gt;
&lt;td&gt;5.x&lt;/td&gt;
&lt;td&gt;supported&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0.10.x&lt;/td&gt;
&lt;td&gt;13.x&lt;/td&gt;
&lt;td&gt;5.x &amp;amp;&amp;amp; 6.x&lt;/td&gt;
&lt;td&gt;supported&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0.11.x&lt;/td&gt;
&lt;td&gt;14.x&lt;/td&gt;
&lt;td&gt;5 .x &amp;amp;&amp;amp; 6.x&lt;/td&gt;
&lt;td&gt;supported&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;0.12.x&lt;/td&gt;
&lt;td&gt;15.x&lt;/td&gt;
&lt;td&gt;5.x &amp;amp;&amp;amp; 6.x&lt;/td&gt;
&lt;td&gt;supported&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Starting from Angular 9 you can use &lt;code&gt;ng add&lt;/code&gt; to install the package. Otherwise, you have to use &lt;code&gt;npm&lt;/code&gt; or &lt;code&gt;yarn&lt;/code&gt; to add the packages.&lt;/p&gt;

&lt;h2&gt;
  
  
  Install Font Awesome without the official package
&lt;/h2&gt;

&lt;p&gt;If you don't want to use the official package, which I don't recommend, you can install Font Awesome directly and update your styles in &lt;code&gt;angular.json&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;There is a catch. There are two limitations with this approach. The first is the version of Font Awesome - the maximum version is &lt;a href="https://www.npmjs.com/package/font-awesome" rel="noopener noreferrer"&gt;Font Awesome 4.7&lt;/a&gt;. And, the second is the usage of font-awesome in Angular. You have to use css classes like &lt;code&gt;&amp;lt;i class="fa fa-dashboard"&amp;gt;&amp;lt;/i&amp;gt;&lt;/code&gt; to render icons.&lt;/p&gt;

&lt;h3&gt;
  
  
  Three steps to install Font Awesome 4.7 in Angular
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Install via npm or yarn&lt;/li&gt;
&lt;li&gt;Update angular.json&lt;/li&gt;
&lt;li&gt;And that's it.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Install the package. Go to project root and run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm i font-awesome
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add the styles &lt;code&gt;font-awesome.css&lt;/code&gt; from the fontawesome package to your &lt;code&gt;angular.json&lt;/code&gt; by updating the &lt;code&gt;styles&lt;/code&gt; import:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "styles": [
    "node_modules/font-awesome/css/font-awesome.css",
    "src/styles.css"
  ]
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And that's it. You have &lt;strong&gt;successfully installed Font Awesome 4.7&lt;/strong&gt;.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;The preferred way to add Font Awesome to Angular is &lt;a href="https://www.npmjs.com/package/@fortawesome/angular-fontawesome" rel="noopener noreferrer"&gt;Angular Component for Font Awesome 5+&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Use &lt;code&gt;ng add&lt;/code&gt; for interactive prompts in Angular CLI.&lt;/li&gt;
&lt;li&gt;If the version of Font Awesome should be smaller than 5, install directly via npm or yarn and update styles import in &lt;code&gt;angular.json&lt;/code&gt;. There are downsides to this approach. The maximum version of Font Awesome is 4.7, and you have to apply CSS classes in Angular to display icons.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thanks for reading and if you have any &lt;strong&gt;questions&lt;/strong&gt; , use the &lt;strong&gt;comment&lt;/strong&gt; function or &lt;strong&gt;send me a message&lt;/strong&gt; &lt;strong&gt;&lt;a href="https://www.twitter.com/mariokandut" rel="noopener noreferrer"&gt;@mariokandut&lt;/a&gt;&lt;/strong&gt;. If you want to know more about &lt;strong&gt;&lt;a href="https://www.mariokandut.com/tags/angular" rel="noopener noreferrer"&gt;Angular&lt;/a&gt;&lt;/strong&gt;, have a look at these &lt;a href="https://www.mariokandut.com/tags/angular" rel="noopener noreferrer"&gt;Angular Tutorials&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;References (and Big thanks):&lt;/strong&gt;&lt;a href="https://angular.io/docs" rel="noopener noreferrer"&gt;Angular&lt;/a&gt;,&lt;a href="https://fontawesome.com/" rel="noopener noreferrer"&gt;fontawesome&lt;/a&gt;&lt;a href="https://www.npmjs.com/package/@fortawesome/angular-fontawesome" rel="noopener noreferrer"&gt;Angular Component for Font Awesome&lt;/a&gt;&lt;/p&gt;

</description>
      <category>angular</category>
      <category>javascript</category>
      <category>typescript</category>
    </item>
    <item>
      <title>Introduction to routing in Angular</title>
      <dc:creator>Mario</dc:creator>
      <pubDate>Fri, 03 Feb 2023 00:00:00 +0000</pubDate>
      <link>https://dev.to/mariokandut/introduction-to-routing-in-angular-1ol2</link>
      <guid>https://dev.to/mariokandut/introduction-to-routing-in-angular-1ol2</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;This article is based on Angular CLI 15.1.4, Node 18.13.0, npm 8.19.3&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;Routing in Angular is used to navigate from one view to another as users perform actions.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In an SPA (Single-Page-Application) you can conditionally show or hide components depending on user actions, at some point users will perform an action which requires to move to a different view in the application. To handle the navigation from one view to another you have to use &lt;strong&gt;routing&lt;/strong&gt; , most commonly the &lt;strong&gt;@angular/router&lt;/strong&gt; , see &lt;a href="https://angular.io/api/router/Router" rel="noopener noreferrer"&gt;Router API&lt;/a&gt;. Routing plays a crucial role in making an SPA dynamic and user-friendly. It's what makes your application feel like a native app instead of a loose collection of separate pages (think of internet of the 90ies).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;The &lt;code&gt;Router&lt;/code&gt; enables navigation by interpreting a browser URL as an instruction to change the view.&lt;/strong&gt; Also, additional parameters can be passed to be handled in the view component.&lt;/p&gt;

&lt;p&gt;Some examples of actions, which involve routing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Entering a URL in the address bar and the browser navigates to a corresponding page within the Angular application&lt;/li&gt;
&lt;li&gt;Clicking on a link, which navigates to a new page&lt;/li&gt;
&lt;li&gt;Clicking on a product image to go to the product details page&lt;/li&gt;
&lt;li&gt;Clicking the back or forward button in the browser to trigger browser navigation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The Angular router is the package &lt;code&gt;@angular/router&lt;/code&gt;, when scaffolding an application with the Angular CLI &lt;code&gt;ng new YOUR_TEST_APP&lt;/code&gt;, you will get prompted if you want to use the angular router. This tutorial is based on &lt;code&gt;@angular/router&lt;/code&gt;. If you don't want to use &lt;code&gt;@angular/router&lt;/code&gt;, there are some other options, for example &lt;a href="https://github.com/ngrx/router" rel="noopener noreferrer"&gt;ngrx/router&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Let's take a look at some code examples.&lt;/p&gt;

&lt;h2&gt;
  
  
  Basic routing
&lt;/h2&gt;

&lt;p&gt;We are going to create a basic application with two components and two routes.&lt;/p&gt;

&lt;p&gt;The steps are:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create basic application with routing module&lt;/li&gt;
&lt;li&gt;Import &lt;code&gt;Routermodule&lt;/code&gt; and &lt;code&gt;Routes&lt;/code&gt; into routing module&lt;/li&gt;
&lt;li&gt;Define and add application routes&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  1. Create basic application with routing module
&lt;/h3&gt;

&lt;p&gt;Let's create a new Angular app, and we call it &lt;code&gt;my-routing&lt;/code&gt; in a folder &lt;code&gt;angular-routing&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;mkdir angular-routing
cd angular routing
ng new my-routing --routing --defaults
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The command &lt;code&gt;ng new ...&lt;/code&gt; uses the Angular CLI to generate a basic Angular application with an &lt;code&gt;AppRoutingModule&lt;/code&gt; (application routing module). The &lt;code&gt;AppRoutingModule&lt;/code&gt; is an NgModule where you can configure your routes.&lt;/p&gt;

&lt;p&gt;Now let's add two components, so we can route to them. In the same folder generate two components via CLI.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ng generate component first
ng generate component second
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Open the &lt;code&gt;AppRoutingModule&lt;/code&gt; (file: &lt;code&gt;app-routing.module.ts&lt;/code&gt;) and import the two components.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { FirstComponent } from './first/first.component';
import { SecondComponent } from './second/second.component';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Import &lt;code&gt;Routermodule&lt;/code&gt; and &lt;code&gt;Routes&lt;/code&gt; into routing module
&lt;/h3&gt;

&lt;p&gt;The importing of the &lt;code&gt;Routermodule&lt;/code&gt; into the Angular &lt;code&gt;AppModule&lt;/code&gt; was already done by the Angular CLI. If you are creating your application manually, or you don't have the Angular CLI, you have to add the imports.&lt;/p&gt;

&lt;p&gt;Your &lt;code&gt;app-routing.module.ts&lt;/code&gt; should look something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { FirstComponent } from './first/first.component';
import { SecondComponent } from './second/second.component';

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule],
})
export class AppRoutingModule {}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now add your routes array, which will contain all the valid routes for your app:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { FirstComponent } from './first/first.component';
import { SecondComponent } from './second/second.component';

const routes: Routes = [];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule],
})
export class AppRoutingModule {}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Define and add application routes
&lt;/h3&gt;

&lt;p&gt;Let's define our routes. We have two components &lt;code&gt;first&lt;/code&gt; and &lt;code&gt;second&lt;/code&gt;, so we are adding two routes.&lt;/p&gt;

&lt;p&gt;Replace the &lt;code&gt;routes&lt;/code&gt; with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const routes: Routes = [
  { path: 'first-component', component: FirstComponent },
  { path: 'second-component', component: SecondComponent },
];
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We have now defined our application routes. Start the application &lt;code&gt;ng serve&lt;/code&gt; and go to &lt;code&gt;http://localhost:4200/first-component&lt;/code&gt;. The first component should render.&lt;/p&gt;

&lt;p&gt;Let's remove the Angular welcome screen and add a navigation for the two components.&lt;/p&gt;

&lt;p&gt;To do so, open &lt;code&gt;app.component.html&lt;/code&gt; and remove everything. We are going to add the navigation and the &lt;strong&gt;router-outlet&lt;/strong&gt;. The &lt;code&gt;router-outlet&lt;/code&gt; is a placeholder that Angular dynamically fills based on the current router state. Basically, Angular uses this to insert the component matched by the route.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;h1&amp;gt;My Angular Routing App&amp;lt;/h1&amp;gt;
&amp;lt;nav&amp;gt;
  &amp;lt;ul&amp;gt;
    &amp;lt;li&amp;gt;
      &amp;lt;a
        routerLink="/first-component"
        routerLinkActive="active"
        ariaCurrentWhenActive="page"
      &amp;gt;
        First Component
      &amp;lt;/a&amp;gt;
    &amp;lt;/li&amp;gt;
    &amp;lt;li&amp;gt;
      &amp;lt;a
        routerLink="/second-component"
        routerLinkActive="active"
        ariaCurrentWhenActive="page"
      &amp;gt;
        Second Component
      &amp;lt;/a&amp;gt;
    &amp;lt;/li&amp;gt;
  &amp;lt;/ul&amp;gt;
&amp;lt;/nav&amp;gt;

&amp;lt;router-outlet&amp;gt;&amp;lt;/router-outlet&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now start your Angular app again, and you should see a headline with two buttons. Click the buttons and see how the component gets rendered and your URL changes.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Routing is the mechanism that allows you to create different pages within your Angular application without reloading the entire page.&lt;/li&gt;
&lt;li&gt;A router array in &lt;code&gt;AppRoutingModule&lt;/code&gt; holds all the routes.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;router-outlet&lt;/code&gt; is used by Angular to insert the component matched by the route.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thanks for reading and if you have any &lt;strong&gt;questions&lt;/strong&gt; , use the &lt;strong&gt;comment&lt;/strong&gt; function or &lt;strong&gt;send me a message&lt;/strong&gt; &lt;strong&gt;&lt;a href="https://www.twitter.com/mariokandut" rel="noopener noreferrer"&gt;@mariokandut&lt;/a&gt;&lt;/strong&gt;. If you want to know more about &lt;strong&gt;&lt;a href="https://www.mariokandut.com/tags/angular" rel="noopener noreferrer"&gt;Angular&lt;/a&gt;&lt;/strong&gt;, have a look at these &lt;a href="https://www.mariokandut.com/tags/angular" rel="noopener noreferrer"&gt;Angular Tutorials&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;References (and Big thanks):&lt;/strong&gt;&lt;a href="https://angular.io/docs" rel="noopener noreferrer"&gt;Angular - Docs&lt;/a&gt;, &lt;a href="https://angular.io/guide/router" rel="noopener noreferrer"&gt;Angular Routing Guide&lt;/a&gt;, &lt;a href="https://coryrylan.com/blog/introduction-to-angular-routing" rel="noopener noreferrer"&gt;Cory Rylan&lt;/a&gt;&lt;/p&gt;

</description>
      <category>angular</category>
      <category>typescript</category>
    </item>
    <item>
      <title>How to write a custom ESLint rule</title>
      <dc:creator>Mario</dc:creator>
      <pubDate>Sun, 20 Nov 2022 00:00:00 +0000</pubDate>
      <link>https://dev.to/mariokandut/how-to-write-a-custom-eslint-rule-14k1</link>
      <guid>https://dev.to/mariokandut/how-to-write-a-custom-eslint-rule-14k1</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;This article is based on &lt;a href="https://www.npmjs.com/package/eslint" rel="noopener noreferrer"&gt;ESLint v8.28.0&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;ESLint is the default linting tool in the JavaScript/TypeScript ecosystem. ESLint runs continuously a set of rules to detect issues, and, depending on the rule, it allows you to automatically fix the issue. These rules can be imported from other projects or extended to your needs. At some point you might have a case which is not covered with one of the already existing ESLint plugins, then you have to write your own plugin.&lt;/p&gt;

&lt;p&gt;This article is about how you can write your own custom plugin for ESLint. Before you start, check out the quick refresher - &lt;a href="https://www.mariokandut.com/what-is-linting-and-how-can-it-help-you/" rel="noopener noreferrer"&gt;what is linting&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Writing a custom ESLint rule
&lt;/h2&gt;

&lt;p&gt;To use a custom rule in ESLint, you have to write an ESLint plugin. Before you start writing your own plugin, check the already existing ones &lt;a href="https://eslint.org/docs/latest/rules/" rel="noopener noreferrer"&gt;here&lt;/a&gt;. ESLint offers a flexible architecture for plugins and is completely pluggable. The parser and the rules are all pluggable, this means, that you can adjust it to your needs. If you want to use TypeScript or JavaScript or use different plugins for naming functions, etc. The possibilities are endless.&lt;/p&gt;

&lt;p&gt;Before starting to write the custom rule, we have to understand how ESLint works and how we can check if the rule is working. Any linter, TSLint or ESLint is basically a &lt;strong&gt;basic static code analyzer&lt;/strong&gt; , it checks your source code for programmatic and stylistic errors (wrong indentation, variable naming, ...).&lt;strong&gt;ESLint uses an AST (Abstract Syntax Tree)&lt;/strong&gt; to evaluate patterns in code. AST (Abstract Syntax Tree) is used for describing a particular syntax pattern in your code, see the example &lt;a href="https://astexplorer.net/" rel="noopener noreferrer"&gt;AST&lt;/a&gt; below.&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%2Fwww.mariokandut.com%2Fstatic%2F761b9d6a8666787a6f6a38d6ec92a9fa%2Ffcda8%2Fabstract-syntax-tree-example.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%2Fwww.mariokandut.com%2Fstatic%2F761b9d6a8666787a6f6a38d6ec92a9fa%2Ffcda8%2Fabstract-syntax-tree-example.png" title="Abstract syntax tree example" alt="Abstract syntax tree example" width="590" height="254"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So, basically, we have to find the node of our code we want to check in the AST and return it to ESLint. Hence, we have a plan.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Three steps to create a custom ESLint rule&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create rule definition in AST explorer&lt;/li&gt;
&lt;li&gt;Create module with custom rule&lt;/li&gt;
&lt;li&gt;Import custom module into ESLint&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  1. Create custom rule in AST explorer
&lt;/h3&gt;

&lt;p&gt;For demonstration purposes, we are going to write a simple rule. We want to forbid a variable named &lt;code&gt;pizza&lt;/code&gt;, &lt;code&gt;isPizza&lt;/code&gt; or any other combination is okay.&lt;/p&gt;

&lt;p&gt;We open a browser tab and go to &lt;a href="https://astexplorer.net/" rel="noopener noreferrer"&gt;AST&lt;/a&gt;. Now we have to configure the &lt;strong&gt;parser&lt;/strong&gt; and &lt;strong&gt;transformer&lt;/strong&gt;. Depending on your projects ESLint configuration, you have to select the parser, for example &lt;code&gt;@typescript-eslint/parser&lt;/code&gt;, if you are using typescript and are using this parser. Use the &lt;code&gt;ESLint v8&lt;/code&gt; option in the &lt;strong&gt;transform&lt;/strong&gt; , since we don't want to use TypeScript in our ESLint rule. Now you will have four windows, instead of two.&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%2Fwww.mariokandut.com%2Fstatic%2F17332fa4b262471c33b2281f4aa927c2%2Ffcda8%2Fcustom-eslint-rule-ast.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%2Fwww.mariokandut.com%2Fstatic%2F17332fa4b262471c33b2281f4aa927c2%2Ffcda8%2Fcustom-eslint-rule-ast.png" title="Abstract syntax tree" alt="Abstract syntax tree" width="590" height="399"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The top left one is the code to lint, the top right one is the abstract syntax tree, the bottom left is your rule definition and the bottom right is the rule output.&lt;/p&gt;

&lt;p&gt;Now, let's explore the AST to find &lt;code&gt;name: "pizza"&lt;/code&gt;. This is the property we want to check. Let's console log it.&lt;/p&gt;

&lt;p&gt;Copy the code in the bottom left rule definition and open dev tools console. The output should be &lt;strong&gt;pizza&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;module.exports = {
  create(context) {
    return {
      Identifier(node) {
        console.log(node.name);
      },
    };
  },
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we just have to check if the name is pizza.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;module.exports = {
  create(context) {
    return {
      Identifier(node) {
        if (node.name.toLowerCase() === 'pizza') {
          console.log(
            `Nope, the variable name '${node.name}' is reserved`,
          );
        } else {
          console.log(`'${node.name}' is an amazing variable name`);
        }
      },
    };
  },
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now, let's add more test cases to verify our code is correct. Copy and paste the code into the top left window.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const pizza = 'yummy';
const isPizza = true;
const pizzaSize = 'large';
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The output in the console should be &lt;code&gt;... is an amazing variable name&lt;/code&gt; for &lt;code&gt;isPizza&lt;/code&gt; and &lt;code&gt;pizzaSize&lt;/code&gt;. That is Great. We have identified the pattern, which violates our custom rule.&lt;/p&gt;

&lt;p&gt;To report the violation of the rule we have to use &lt;code&gt;context.report()&lt;/code&gt;, see &lt;a href="https://eslint.org/docs/latest/developer-guide/working-with-rules#contextreport" rel="noopener noreferrer"&gt;ESLint docs&lt;/a&gt;. It publishes a warning or error depending on the configuration being used. The object accepted by &lt;code&gt;context.report()&lt;/code&gt;, has a required &lt;code&gt;message&lt;/code&gt; property, which contains the message that will be reported.&lt;/p&gt;

&lt;p&gt;Now,let's extend the code.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;module.exports = {
  create(context) {
    return {
      Identifier(node) {
        if (node.name.toLowerCase() === 'pizza') {
          return context.report({
            node,
            message: 'Nope, the variable name "pizza" is reserved',
          });
        }
        return null;
      },
    };
  },
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The output (bottom right) should be something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;// Nope, the variable name "pizza" is reserved (at 1:7)
const pizza = 'yummy';
// ------^
// ...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Our rule definition is now done. Additionally, the method &lt;code&gt;context.report()&lt;/code&gt; also has an optional property &lt;code&gt;fix&lt;/code&gt;, which would allow us to define a function which applies a fix for the rule violation. Though, this will be covered in another blog post. 😀&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Create module with custom rule
&lt;/h3&gt;

&lt;p&gt;Create a project with corresponding folders and files, and initialize with &lt;code&gt;npm init -y&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;mkdir eslint-custom-rules
cd eslint-custom-rules
npm init -y
touch index.js
mkdir rules
cd rules
touch pizza-reserved.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We will need this later to upload the module or import it into our project.&lt;/p&gt;

&lt;p&gt;Add the rule definition in the file &lt;code&gt;pizza-reserved.js&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;module.exports = {
  create(context) {
    return {
      Identifier(node) {
        if (node.name.toLowerCase() === 'pizza') {
          return context.report({
            node,
            message: 'Nope, the variable name "pizza" is reserved',
          });
        }
        return null;
      },
    };
  },
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There are naming restrictions for creating custom eslint rules. Following formats are allowed, where &lt;code&gt;plugin-name&lt;/code&gt; and &lt;code&gt;scope&lt;/code&gt; can be customized:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;eslint-plugin-&lt;code&gt;plugin-name&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;@&lt;code&gt;scope&lt;/code&gt;/eslint-plugin-&lt;code&gt;plugin-name&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;@&lt;code&gt;scope&lt;/code&gt;/eslint-plugin&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For this example we choose &lt;code&gt;eslint-plugin-pizza-reserved&lt;/code&gt; for the npm module.&lt;/p&gt;

&lt;p&gt;We have to update the &lt;code&gt;package.json&lt;/code&gt; in our &lt;code&gt;index.js&lt;/code&gt; file with the name &lt;code&gt;eslint-plugin-pizza-reserved&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The package.json should look like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "name": "eslint-plugin-pizza-reserved",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" &amp;amp;&amp;amp; exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we update our &lt;code&gt;index.js&lt;/code&gt; files to export the rules.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;module.exports = {
  rules: {
    'pizza-reserved': require('./rules/pizza-reserved'),
  },
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we have a working custom eslint rule. We can now publish is to npm or only use it locally in our project.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Import custom module into ESLint
&lt;/h3&gt;

&lt;p&gt;The import of the custom rule into your ESLint configuration depends on if you have published the rule or if you want to use it locally.&lt;/p&gt;

&lt;p&gt;If you use the ESLint rule locally in your project, you can simply extend your package.json devDependencies with &lt;code&gt;"&amp;lt;plugin-name&amp;gt;": "file:path/to/entrypoint"&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The folder structure in this example is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;.
├── eslint-custom-rules # Custom ESLint rules
| ├── rules
| | └── pizza-reserved.js
| └── index.js
|
└── my-project # Project folder, where we want to use custom rules
    ├── src # Source files
    ├── test # Automated tests
    ├── .eslintrc.js # Automated tests
    ├── ... # Automated tests
    └── README.md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Hence, use &lt;code&gt;"eslint-plugin-custom-rules": "file:eslint-custom-rules"&lt;/code&gt; to add your custom eslint plugin to package.json and run &lt;code&gt;npm i&lt;/code&gt; to install it.&lt;/p&gt;

&lt;p&gt;The final step would be to extend the ESLint configuration.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;module.exports = {
  plugins: [
    'custom-rules',
    // other plugins
  ],
  rules: {
    // other configs
    'custom-rules/pizza-reserved': 'warn',
  },
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it. You have written a custom ESLint rule. Congratulations.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;To create a custom ESLint rule you have to create a custom ESLint plugin.&lt;/li&gt;
&lt;li&gt;First you have to define the rule definition with the AST explorer.&lt;/li&gt;
&lt;li&gt;Then you have to create an NPM module with the custom rule&lt;/li&gt;
&lt;li&gt;Finally, you have to install the custom module in your project and add it into your ESLint configuration.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thanks for reading and if you have any &lt;strong&gt;questions&lt;/strong&gt; , use the &lt;strong&gt;comment&lt;/strong&gt; function or &lt;strong&gt;send me a message&lt;/strong&gt; &lt;strong&gt;&lt;a href="https://www.twitter.com/mariokandut" rel="noopener noreferrer"&gt;@mariokandut&lt;/a&gt;&lt;/strong&gt;. If you want to know more about &lt;strong&gt;&lt;a href="https://www.mariokandut.com/tags/typescript" rel="noopener noreferrer"&gt;typescript&lt;/a&gt;&lt;/strong&gt;, have a look at these &lt;a href="https://www.mariokandut.com/tags/typescript" rel="noopener noreferrer"&gt;Typescript Tutorials&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;References (and Big thanks):&lt;/strong&gt;&lt;a href="https://eslint.org/docs/latest/" rel="noopener noreferrer"&gt;ESLint&lt;/a&gt;,&lt;a href="https://www.darraghoriordan.com/2021/11/06/how-to-write-an-eslint-plugin-typescript/" rel="noopener noreferrer"&gt;Darragh ORiordan&lt;/a&gt;,&lt;a href="https://tech.devoted.com/" rel="noopener noreferrer"&gt;Carrie Reid-Knox&lt;/a&gt;,&lt;a href="https://developers.mews.com/how-to-write-custom-eslint-rules/" rel="noopener noreferrer"&gt;MEWS - Daria&lt;/a&gt;&lt;/p&gt;

</description>
      <category>typescript</category>
      <category>javascript</category>
      <category>eslint</category>
    </item>
    <item>
      <title>How to add husky to Angular</title>
      <dc:creator>Mario</dc:creator>
      <pubDate>Mon, 31 Oct 2022 00:00:00 +0000</pubDate>
      <link>https://dev.to/mariokandut/how-to-add-husky-to-angular-420g</link>
      <guid>https://dev.to/mariokandut/how-to-add-husky-to-angular-420g</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;This article is based on &lt;a href="https://github.com/typicode/husky/releases/tag/v8.0.1" rel="noopener noreferrer"&gt;Husky v8.0.1&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Husky makes modern native Git hooks easy to use in an Angular project. You can use it to lint your commit messages, run tests, lint code, or many more when you commit or push.&lt;/p&gt;

&lt;p&gt;But what are Git hooks and how can you add husky to any Angular project?&lt;/p&gt;

&lt;h2&gt;
  
  
  What are Git hooks?
&lt;/h2&gt;

&lt;p&gt;Git hooks are scripts/programs that you can set up to run at certain points in git's execution (git lifecycle). These points include different stages of a commit, like &lt;strong&gt;before a commit (pre-commit)&lt;/strong&gt; or &lt;strong&gt;after a commit (post-commit)&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Git hooks allow developers to enforce standards by automating other scripts to run those tasks, like run &lt;code&gt;npm test&lt;/code&gt; before a commit, or run &lt;code&gt;eslint&lt;/code&gt; to avoid eslint errors and warnings.&lt;/p&gt;

&lt;p&gt;Husky supports all Git hooks. You can find a list with all available Git hooks &lt;a href="https://git-scm.com/docs/githooks" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Add husky to your Angular project
&lt;/h2&gt;

&lt;p&gt;There are two ways to install husky in your project:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Automatic (recommended)&lt;/li&gt;
&lt;li&gt;Manual&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Automatic installation (recommended)
&lt;/h3&gt;

&lt;p&gt;The package &lt;a href="https://www.npmjs.com/package/husky-init" rel="noopener noreferrer"&gt;husky-init&lt;/a&gt; is used to quickly install and initialize a project with husky.&lt;/p&gt;

&lt;p&gt;From your project root, type the following commands (depending on your package manager) to install &lt;code&gt;husky&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Important:&lt;/strong&gt; If your &lt;code&gt;package.json&lt;/code&gt; is in a subdirectory, see how to set up a &lt;a href="https://typicode.github.io/husky/#/?id=custom-directory" rel="noopener noreferrer"&gt;custom directory&lt;/a&gt; with husky.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx husky-init &amp;amp;&amp;amp; npm install # npm
npx husky-init &amp;amp;&amp;amp; yarn # Yarn 1
yarn dlx husky-init --yarn2 &amp;amp;&amp;amp; yarn # Yarn 2+
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After successful execution of this script several things did happen:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A folder named &lt;code&gt;.husky&lt;/code&gt; in your project root has been added. It contains a file called &lt;code&gt;pre-commit&lt;/code&gt;, which is the initial pre-commit hook. And a folder &lt;code&gt;_&lt;/code&gt; which contains the automatically generated shell script for husky. (Do not commit this, see &lt;code&gt;.gitignore&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;package.json&lt;/code&gt; was modified, with a &lt;code&gt;prepare&lt;/code&gt; script and &lt;code&gt;husky&lt;/code&gt; was added as a devDependency.&lt;/li&gt;
&lt;li&gt;And your &lt;code&gt;package-lock.json&lt;/code&gt; was updated.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That's it, you are ready to use husky in your Angular project. 😀&lt;/p&gt;

&lt;h3&gt;
  
  
  Manually installation
&lt;/h3&gt;

&lt;p&gt;Three steps, though the outcome should be the same as with automatic installation.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Install husky
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install husky --save-dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Enable Git hooks
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx husky install
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;To automatically have Git hooks enabled after install, edit package.json
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm pkg set scripts.prepare="husky install"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Using hooks
&lt;/h2&gt;

&lt;p&gt;After a successful installation you should already have a &lt;code&gt;pre-commit&lt;/code&gt; hook installed.&lt;/p&gt;

&lt;p&gt;The content of the generated &lt;code&gt;pre-commit&lt;/code&gt; hook are:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

npm test
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This means that before every commit, the script &lt;code&gt;npm test&lt;/code&gt; is running. If the tests fail, you will get an error and, you can`t commit, unless you fix the tests. I think you see already how useful this can be in any size of project.&lt;/p&gt;

&lt;h3&gt;
  
  
  Create a hook
&lt;/h3&gt;

&lt;p&gt;The syntax to add a command to a hook or to create a new hook is:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;&lt;br&gt;
husky add &amp;lt;file&amp;gt; [cmd]&lt;br&gt;
&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;For example, you want to run &lt;code&gt;ng lint&lt;/code&gt; after &lt;code&gt;npm test&lt;/code&gt; in your &lt;code&gt;pre-commit&lt;/code&gt; hook.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;&lt;code&gt;&lt;br&gt;
husky add .husky/pre-commit ng lint&lt;br&gt;
&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The pre-commit hook has been updated:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;&lt;/code&gt;`&lt;/p&gt;

&lt;h1&gt;
  
  
  !/usr/bin/env sh
&lt;/h1&gt;

&lt;p&gt;. "$(dirname -- "$0")/_/husky.sh"&lt;/p&gt;

&lt;p&gt;npm test&lt;br&gt;
ng lint&lt;br&gt;
`&lt;code&gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;🌟Congratulations🌟You have husky successfully installed and setup &lt;strong&gt;husky&lt;/strong&gt; in your Angular project.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Husky is a tool to use git hooks easily to automatically run scripts on git lifecycle events.&lt;/li&gt;
&lt;li&gt;For example: If you want to run a npm script, before code is committed use a &lt;code&gt;pre-commit&lt;/code&gt; hook.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thanks for reading and if you have any &lt;strong&gt;questions&lt;/strong&gt; , use the &lt;strong&gt;comment&lt;/strong&gt; function or &lt;strong&gt;send me a message&lt;/strong&gt; &lt;strong&gt;&lt;a href="https://www.twitter.com/mariokandut" rel="noopener noreferrer"&gt;@mariokandut&lt;/a&gt;&lt;/strong&gt;. If you want to know more about &lt;strong&gt;&lt;a href="https://www.mariokandut.com/tags/angular" rel="noopener noreferrer"&gt;Angular&lt;/a&gt;&lt;/strong&gt;, have a look at these &lt;a href="https://www.mariokandut.com/tags/angular" rel="noopener noreferrer"&gt;Angular Tutorials&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;References (and Big thanks):&lt;/strong&gt;&lt;a href="https://git-scm.com/docs/githooks" rel="noopener noreferrer"&gt;Git hooks&lt;/a&gt;,&lt;a href="https://angular.io/docs" rel="noopener noreferrer"&gt;Angular&lt;/a&gt;,&lt;a href="https://typicode.github.io/husky/#/" rel="noopener noreferrer"&gt;Husky&lt;/a&gt;,&lt;a href="https://www.npmjs.com/package/husky" rel="noopener noreferrer"&gt;NPM - husky&lt;/a&gt;,&lt;a href="https://itnext.io/angular-with-eslint-prettier-husky-6581ecd66fbb" rel="noopener noreferrer"&gt;itnext - Stavros Droutsas&lt;/a&gt;&lt;/p&gt;

</description>
      <category>angular</category>
    </item>
    <item>
      <title>How to create a web server in Node.js</title>
      <dc:creator>Mario</dc:creator>
      <pubDate>Sat, 18 Jun 2022 00:00:00 +0000</pubDate>
      <link>https://dev.to/mariokandut/how-to-create-a-web-server-in-nodejs-4lle</link>
      <guid>https://dev.to/mariokandut/how-to-create-a-web-server-in-nodejs-4lle</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;This article is based on &lt;strong&gt;Node v16.15.1&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This article shows how to create a web server in Node.js with the core APIs. We are going to use the &lt;strong&gt;http&lt;/strong&gt; module. In a real world scenario this is not recommended, and a web framework should be used. This article is only demonstrating that this is possible without a framework.&lt;/p&gt;

&lt;h2&gt;
  
  
  Create a minimal web server
&lt;/h2&gt;

&lt;p&gt;A minimum viable web server would have the following requirements:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Responds to HTTP requests based on a HTTP verb (for example. GET)&lt;/li&gt;
&lt;li&gt;Responds to request based on a given route&lt;/li&gt;
&lt;li&gt;Responds with 404 status code, if route isn't found.&lt;/li&gt;
&lt;li&gt;Sets applicable headers (for example: &lt;code&gt;Content-Type:&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Next steps&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Basic Setup&lt;/li&gt;
&lt;li&gt;Create a basic web server&lt;/li&gt;
&lt;li&gt;Add routes and status codes&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  1. Basic Setup
&lt;/h3&gt;

&lt;p&gt;Node.js has to be installed. Use the node version manager &lt;code&gt;nvm&lt;/code&gt; to install Node.&lt;/p&gt;

&lt;p&gt;Create a folder &lt;code&gt;http-web-server&lt;/code&gt; and cd into it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir http-web-server
cd http-web-server
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  2. Create a basic web server
&lt;/h3&gt;

&lt;p&gt;Now, create a file &lt;code&gt;server.js&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;touch server.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And then copy the following code into it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;'use strict';
const http = require('http');
const PORT = process.env.PORT || 3000;

const helloWorld = `&amp;lt;html&amp;gt;
  &amp;lt;head&amp;gt;
    &amp;lt;style&amp;gt;
     body { background: white; margin: 1.5rem }
     h1 { color: red; font-family: sans-serif }
    &amp;lt;/style&amp;gt;
  &amp;lt;/head&amp;gt;
  &amp;lt;body&amp;gt;
    &amp;lt;h1&amp;gt;Hello World&amp;lt;/h1&amp;gt;
  &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;`;

const server = http.createServer((req, res) =&amp;gt; {
  res.setHeader('Content-Type', 'text/html');
  res.end(helloWorld);
});

server.listen(PORT);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the code above, we have used the &lt;code&gt;http&lt;/code&gt; module to create a server with the &lt;code&gt;createServer&lt;/code&gt; method. The &lt;code&gt;createServer&lt;/code&gt; method is passed a function with two objects in, the request object and the response object. This function is called every time the server receives a request and the objects are created for every request. In the function we set the header to &lt;code&gt;Content-Type: text/html&lt;/code&gt; and return the constant &lt;code&gt;helloWorld&lt;/code&gt; to return the HTML string. The response object is a &lt;strong&gt;writable stream&lt;/strong&gt; , because in the node core it inherits from &lt;code&gt;stream.Stream&lt;/code&gt;), and calling &lt;code&gt;end&lt;/code&gt; writes the content and closes the connection. The &lt;code&gt;listen&lt;/code&gt; method binds the defined &lt;code&gt;PORT&lt;/code&gt; to the object created from &lt;code&gt;createServer&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Now execute the code with &lt;code&gt;node server.js&lt;/code&gt; and open a browser tab with &lt;code&gt;http://localhost:3000&lt;/code&gt;. You should see a &lt;code&gt;Hello World&lt;/code&gt; in red on a white background.&lt;/p&gt;

&lt;p&gt;The Node process will not exit by itself, because the created server keeps the process open.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. Add routes and status codes
&lt;/h3&gt;

&lt;p&gt;Our example is not meeting the criteria. Currently, for any route the same response is given, we don't return any status codes and have no error handling.&lt;/p&gt;

&lt;p&gt;Let's update our &lt;code&gt;server.js&lt;/code&gt; with a response based on route.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;'use strict';
const http = require('http');
const url = require('url');

const PORT = process.env.PORT || 3000;

const helloWorld = `&amp;lt;html&amp;gt;
  &amp;lt;head&amp;gt;
    &amp;lt;style&amp;gt;
     body { background: white; margin: 1.5rem }
     h1 { color: red; font-family: sans-serif }
    &amp;lt;/style&amp;gt;
  &amp;lt;/head&amp;gt;
  &amp;lt;body&amp;gt;
    &amp;lt;h1&amp;gt;Hello World&amp;lt;/h1&amp;gt;
  &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;`;

const root = `&amp;lt;html&amp;gt;
  &amp;lt;head&amp;gt;
    &amp;lt;style&amp;gt;
     body { background: white; margin: 1.5rem }
     h1 { color: black; font-family: sans-serif }
     a { color: green; text-decoration: underline; }
    &amp;lt;/style&amp;gt;
  &amp;lt;/head&amp;gt;
  &amp;lt;body&amp;gt;
    &amp;lt;h1&amp;gt;ROOT&amp;lt;/h1&amp;gt;
    &amp;lt;a href='/hello'&amp;gt;Hello&amp;lt;/a&amp;gt;
  &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;`;

const server = http.createServer((req, res) =&amp;gt; {
  res.setHeader('Content-Type', 'text/html');
  const { pathname } = url.parse(req.url);

  if (pathname === '/') {
    res.end(root);
    return;
  }

  if (pathname === '/hello') {
    res.end(helloWorld);
    return;
  }
});

server.listen(PORT);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now with the help of the &lt;code&gt;url&lt;/code&gt; module we are parsing the request url and returning a different HTML string based on the route. The &lt;code&gt;parse&lt;/code&gt; method in the &lt;code&gt;url&lt;/code&gt; module turns a URL string into an object containing various segments of the URL.&lt;/p&gt;

&lt;p&gt;Restart your node server. When you navigate to &lt;code&gt;http://localhost:3000/hello&lt;/code&gt; you should see in black &lt;code&gt;ROOT&lt;/code&gt; and if you go to &lt;code&gt;http://localhost:3000/hello&lt;/code&gt; you should see &lt;code&gt;hello world&lt;/code&gt; red.&lt;/p&gt;

&lt;p&gt;Now let's add the status codes and error handling for route not found and wrong HTTP verb.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;'use strict';
const http = require('http');
const url = require('url');

const PORT = process.env.PORT || 3000;
const { STATUS_CODES } = http;

const helloWorld = `&amp;lt;html&amp;gt;
  &amp;lt;head&amp;gt;
    &amp;lt;style&amp;gt;
     body { background: white; margin: 1.5rem }
     h1 { color: red; font-family: sans-serif }
    &amp;lt;/style&amp;gt;
  &amp;lt;/head&amp;gt;
  &amp;lt;body&amp;gt;
    &amp;lt;h1&amp;gt;Hello World&amp;lt;/h1&amp;gt;
  &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;`;

const root = `&amp;lt;html&amp;gt;
  &amp;lt;head&amp;gt;
    &amp;lt;style&amp;gt;
     body { background: white; margin: 1.5rem }
     h1 { color: black; font-family: sans-serif }
     a { color: green; text-decoration: underline; }
    &amp;lt;/style&amp;gt;
  &amp;lt;/head&amp;gt;
  &amp;lt;body&amp;gt;
    &amp;lt;h1&amp;gt;ROOT&amp;lt;/h1&amp;gt;
    &amp;lt;a href='/hello'&amp;gt;Hello&amp;lt;/a&amp;gt;
  &amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;`;

const server = http.createServer((req, res) =&amp;gt; {
  res.setHeader('Content-Type', 'text/html');
  const { pathname } = url.parse(req.url);

  // check http method
  if (req.method !== 'GET') {
    res.statusCode = 405;
    res.end(STATUS_CODES[res.statusCode] + '\r\n');
    return;
  }

  if (pathname === '/') {
    res.end(root);
    return;
  }

  if (pathname === '/hello') {
    res.end(helloWorld);
    return;
  }

  // no route found
  res.statusCode = 404;
  res.end(STATUS_CODES[res.statusCode] + '\r\n');
});

server.listen(PORT);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We have destructured the &lt;code&gt;STATUS_CODES&lt;/code&gt; object, which contains the status codes from the &lt;code&gt;http&lt;/code&gt; module, see &lt;a href="https://nodejs.org/dist/latest-v16.x/docs/api/http.html#httpstatus_codes" rel="noopener noreferrer"&gt;docs&lt;/a&gt;. If the request method is not GET, we are returning the status code 405 (Method not allowed) and end the response with the status message from the key-values of &lt;code&gt;STATUS_CODES&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If the route is not &lt;code&gt;/&lt;/code&gt; or &lt;code&gt;/hello&lt;/code&gt;, we return status code 404 (Page not found) and end the response with the applicable message from &lt;code&gt;STATUS_CODES&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Restart your node server and check if the routes are handled correctly. For testing the wrong http verb, only GET is supported in our server, open postman or insomnia or use the following code to make a POST request with the http module&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;node -e "http.request('http://localhost:3000', {method: 'POST'}, (res) =&amp;gt; res.pipe(process.stdout)).end()"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In any case the response should be &lt;code&gt;Method not allowed&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The status code 200 (OK) is the default status code, hence, there is no need to set it for the routes &lt;code&gt;/&lt;/code&gt; and &lt;code&gt;/hello&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;We have now met all criteria and have created a basic web server.&lt;/p&gt;

&lt;p&gt;This approach is very rigid and cumbersome, especially when you try to add more functionality. Node.js frameworks like &lt;strong&gt;Express&lt;/strong&gt; or &lt;strong&gt;Fastify&lt;/strong&gt; enables us to write a more flexible, maintainable and declarative way.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;It is possible to create a web server with the core modules of Node.js, but the code becomes rigid and unmanageable. &lt;/li&gt;
&lt;li&gt;In a real-world scenario you would write web servers with Node.js frameworks.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thanks for reading and if you have any &lt;strong&gt;questions&lt;/strong&gt; , use the &lt;strong&gt;comment&lt;/strong&gt; function or &lt;strong&gt;send me a message&lt;/strong&gt; &lt;strong&gt;&lt;a href="https://www.twitter.com/mariokandut" rel="noopener noreferrer"&gt;@mariokandut&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;If you want to know more about &lt;strong&gt;&lt;a href="https://www.mariokandut.com/tags/node" rel="noopener noreferrer"&gt;Node&lt;/a&gt;&lt;/strong&gt;, have a look at these &lt;a href="https://www.mariokandut.com/tags/node" rel="noopener noreferrer"&gt;Node Tutorials&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  References (and Big thanks):
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://nodejs.org" rel="noopener noreferrer"&gt;NodeJS&lt;/a&gt;,&lt;a href="https://nodejs.org/dist/latest-v16.x/docs/api/http.html" rel="noopener noreferrer"&gt;NodeJS - http&lt;/a&gt;,&lt;a href="https://trainingportal.linuxfoundation.org/" rel="noopener noreferrer"&gt;JSNAD&lt;/a&gt;,&lt;/p&gt;

</description>
    </item>
    <item>
      <title>How to dynamically load ESM in CJS</title>
      <dc:creator>Mario</dc:creator>
      <pubDate>Mon, 21 Feb 2022 00:00:00 +0000</pubDate>
      <link>https://dev.to/mariokandut/how-to-dynamically-load-esm-in-cjs-309p</link>
      <guid>https://dev.to/mariokandut/how-to-dynamically-load-esm-in-cjs-309p</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;This article is based on &lt;strong&gt;Node v16.14.0&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The main distinction between ESM and CJS is the loading of modules. ESM loads asynchronous and CJS loads synchronous. There are limitations in interoperability, while ESM can import CJS, CJS cannot require ESM, because it would break the synchronous constraint.&lt;/p&gt;

&lt;p&gt;For modules to work in both worlds (ESM and CJS), they would have to expose a CJS interface, but &lt;strong&gt;ESM is JavaScripts native module system&lt;/strong&gt;. As you can see, this is quite a tension point in the node ecosystem.&lt;/p&gt;

&lt;p&gt;There is a workaround to asynchronously load an ESM module for use in a CJS module, it is based on &lt;strong&gt;dynamic import&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Dynamic &lt;code&gt;import()&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Dynamic import() introduces a new function-like form of &lt;code&gt;import&lt;/code&gt;. &lt;code&gt;import(moduleSpecifier)&lt;/code&gt; returns a promise for the module namespace object, which is created after fetching, instantiating, and evaluating all the module’s dependencies, as well as the module itself. Read more about it on &lt;a href="https://v8.dev/features/dynamic-import#dynamic" rel="noopener noreferrer"&gt;v8.dev&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The sample code below (from the v8 docs), shows how to dynamically load the module &lt;code&gt;utils.mjs&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;&amp;lt;script type="module"&amp;gt;
  const moduleSpecifier = './utils.mjs';
  import(moduleSpecifier).then(module =&amp;gt; {
    module.default();
    // → logs 'Hi from the default export!'
    module.doStuff();
    // → logs 'Doing stuff…'
  });
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the previous article &lt;a href="https://www.mariokandut.com/how-to-convert-a-cjs-module-to-an-esm-module-in-node/" rel="noopener noreferrer"&gt;How to convert a CJS module to an ESM&lt;/a&gt;, we were converting a CJS to an ESM and were not able to load it, because of the synchronous constraint. Let's fix this.&lt;/p&gt;

&lt;p&gt;Open the &lt;code&gt;index.js&lt;/code&gt; file and load the module &lt;code&gt;format.mjs&lt;/code&gt; dynamically, since &lt;code&gt;import&lt;/code&gt; returns a promise we can use &lt;code&gt;then&lt;/code&gt;, though&lt;code&gt;async/await&lt;/code&gt; can be used as well.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import('./format.mjs').then(format =&amp;gt; {
  console.log(format.toUpper('this will be uppercase'));
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Try to run it with &lt;code&gt;node index.js&lt;/code&gt;. You should not get an error and the output should be &lt;code&gt;THIS WILL BE UPPERCASE&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Using dynamic import to load an ESM module into CJS can force a change to the application API, a synchronous function becomes asynchronous. In some cases it might be worth to consider changing the entire project to an ESM package.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Dynamic import enables loading of ESM into CJS.&lt;/li&gt;
&lt;li&gt;Using dynamic import can change the application API (sync to async).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thanks for reading and if you have any &lt;strong&gt;questions&lt;/strong&gt; , use the &lt;strong&gt;comment&lt;/strong&gt; function or &lt;strong&gt;send me a message&lt;/strong&gt; &lt;strong&gt;&lt;a href="https://www.twitter.com/mariokandut" rel="noopener noreferrer"&gt;@mariokandut&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;If you want to know more about &lt;strong&gt;&lt;a href="https://www.mariokandut.com/tags/node" rel="noopener noreferrer"&gt;Node&lt;/a&gt;&lt;/strong&gt;, have a look at these &lt;a href="https://www.mariokandut.com/tags/node" rel="noopener noreferrer"&gt;Node Tutorials&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  References (and Big thanks):
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://nodejs.org/api/esm.html" rel="noopener noreferrer"&gt;NodeJS&lt;/a&gt;,&lt;a href="https://v8.dev/features/dynamic-import#dynamic" rel="noopener noreferrer"&gt;v8.dev&lt;/a&gt;,&lt;a href="https://github.com/tc39/proposal-dynamic-import" rel="noopener noreferrer"&gt;TC39&lt;/a&gt;,&lt;a href="https://trainingportal.linuxfoundation.org/" rel="noopener noreferrer"&gt;JSNAD&lt;/a&gt;,&lt;a href="https://requirejs.org/docs/commonjs.html" rel="noopener noreferrer"&gt;CommonJS&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>How to convert a CJS module to an ESM</title>
      <dc:creator>Mario</dc:creator>
      <pubDate>Mon, 07 Feb 2022 00:00:00 +0000</pubDate>
      <link>https://dev.to/mariokandut/how-to-convert-a-cjs-module-to-an-esm-4if7</link>
      <guid>https://dev.to/mariokandut/how-to-convert-a-cjs-module-to-an-esm-4if7</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;This article is based on &lt;strong&gt;Node v16.14.0&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Since &lt;strong&gt;Node v14&lt;/strong&gt; , there are two kinds of modules, &lt;strong&gt;CommonJS Modules (CJS)&lt;/strong&gt; and &lt;strong&gt;EcmaScript Modules (ESM)&lt;/strong&gt;. EcmaScript Modules (ESM) were introduced as part of ES6 (EcmaScript 2015). The main goal was for module includes to be statically analyzable, so browsers would be able to pre-parse out imports. This behaviour is similar to collecting all &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; tags as the web page loads.&lt;/p&gt;

&lt;p&gt;It took more than three years for major browsers to implement this retrofitting of a static module system into a dynamic language. And even longer for ESM to be implemented in NodeJS, because of interoperability with the existing CJS module system, though there are still some issues.&lt;/p&gt;

&lt;p&gt;The main difference between CJS and ESM is that &lt;strong&gt;CJS loads every module synchronously&lt;/strong&gt; , and &lt;strong&gt;ESM loads every module asynchronously&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;There are also two types of ESM: native ESM and "transpiled ESM". Transpiled ESM is ESM-like syntax that would be typically be transpiled with Babel. The syntax looks similar, but the behaviour can vary. "Transpiled ESM" compiles to CommonJS in Node and will be compiled in the browser using a bundled synchronous loader. This means, that "transpiled ESM" loads modules synchronously, native ESM loads modules asynchronously.&lt;strong&gt;A Node application (or module) can contain CJS and ESM files.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Let's convert the module created in &lt;a href="https://www.mariokandut.com/how-to-create-a-csj-module/" rel="noopener noreferrer"&gt;How to create a CSJ module&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The CSJ module contains this code:&lt;br&gt;
&lt;/p&gt;

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

const toUpper = str =&amp;gt; {
  if (typeof str === 'symbol') str = str.toString(); // convert to string if symbol is used as input
  str += '';
  return str.toUpperCase();
};

module.exports = { toUpper };
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To convert it to an ESM module, the only we have to do change the file extension from &lt;code&gt;.js&lt;/code&gt; to &lt;code&gt;.mjs&lt;/code&gt;. If you are on linux you can use the &lt;code&gt;mv&lt;/code&gt; command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mv format.js format.mjs
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;CJS modules modify the &lt;code&gt;module.exports&lt;/code&gt; object, in ESM its native syntax. Hence, to create a named export, we can just use the &lt;code&gt;export&lt;/code&gt; keyword.&lt;/p&gt;

&lt;p&gt;Let's update our module:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export const toUpper = str =&amp;gt; {
  if (typeof str === 'symbol') str = str.toString(); // convert to string if symbol is used as input
  str += '';
  return str.toUpperCase();
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;'use strict'&lt;/code&gt; pragma to enforce strict mode is also not needed anymore, since ESM executes in strict-mode.&lt;/p&gt;

&lt;p&gt;That's it for converting CSJ to ESM. There is only one thing, try to run the node application with &lt;code&gt;node index&lt;/code&gt;. You will see an error.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;internal/modules/cjs/loader.js:948
    throw new ERR_REQUIRE_ESM(filename);
    ^
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This error occurs because the &lt;code&gt;require&lt;/code&gt; function will not automatically resolve a filename without an extension &lt;code&gt;('./format')&lt;/code&gt; to an &lt;code&gt;.mjs&lt;/code&gt; extension.&lt;/p&gt;

&lt;p&gt;Ok, so let's fix this and try again.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;node -p "require('./format.mjs')"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We will get an error again.&lt;code&gt;Error [ERR_REQUIRE_ESM]: Must use import to load ES Module.&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The major difference between CSJ and ESM, is that CJS is synchronous. CJS cannot require ESM since that would break the synchronous constraint, but ESM can import CJS.&lt;/p&gt;

&lt;p&gt;There is a way around this constraint with dynamic import. Have a look at this article &lt;a href="https://www.mariokandut.com/how-to-dynamically-load-an-esm-module-in-cjs/" rel="noopener noreferrer"&gt;How to dynamically load an ESM Module in CJS&lt;/a&gt;.&lt;/p&gt;

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

&lt;ul&gt;
&lt;li&gt;Since &lt;strong&gt;Node v14&lt;/strong&gt; , there are two kinds of modules, &lt;strong&gt;CommonJS Modules (CJS)&lt;/strong&gt; and &lt;strong&gt;EcmaScript Modules (ESM)&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;The main difference between CJS and ESM is that &lt;strong&gt;CJS loads every module synchronously&lt;/strong&gt; , and &lt;strong&gt;ESM loads every module asynchronously&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;To convert a CSJ module to ESM, change the file ending to &lt;code&gt;.mjs&lt;/code&gt; and use the &lt;code&gt;export&lt;/code&gt; keyword instead of &lt;code&gt;module.exports&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;CJS cannot require ESM since that would break the synchronous constraint, but ESM can import CJS.&lt;/li&gt;
&lt;li&gt;Use dynamic import for importing ESM in CSJ.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thanks for reading and if you have any &lt;strong&gt;questions&lt;/strong&gt; , use the &lt;strong&gt;comment&lt;/strong&gt; function or &lt;strong&gt;send me a message&lt;/strong&gt; &lt;strong&gt;&lt;a href="https://www.twitter.com/mariokandut" rel="noopener noreferrer"&gt;@mariokandut&lt;/a&gt;&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;If you want to know more about &lt;strong&gt;&lt;a href="https://www.mariokandut.com/tags/node" rel="noopener noreferrer"&gt;Node&lt;/a&gt;&lt;/strong&gt;, have a look at these &lt;a href="https://www.mariokandut.com/tags/node" rel="noopener noreferrer"&gt;Node Tutorials&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  References (and Big thanks):
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://nodejs.org/api/esm.html" rel="noopener noreferrer"&gt;NodeJS&lt;/a&gt;,&lt;a href="https://trainingportal.linuxfoundation.org/" rel="noopener noreferrer"&gt;JSNAD&lt;/a&gt;,&lt;a href="https://requirejs.org/docs/commonjs.html" rel="noopener noreferrer"&gt;CommonJS&lt;/a&gt;&lt;/p&gt;

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