<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Shankar Morwal on Medium]]></title>
        <description><![CDATA[Stories by Shankar Morwal on Medium]]></description>
        <link>https://medium.com/@shankarmorwal?source=rss-e56820be390b------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/2*2-GvmFQU8oB6ULHcfNyEsw.jpeg</url>
            <title>Stories by Shankar Morwal on Medium</title>
            <link>https://medium.com/@shankarmorwal?source=rss-e56820be390b------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sun, 15 Nov 2026 01:42:36 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@shankarmorwal/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com/" rel="hub"/>
        <item>
            <title><![CDATA[Salesforce: Export to Excel with Lightning Web Component]]></title>
            <link>https://learn.habilelabs.io/salesforce-export-to-excel-with-lightning-web-component-875b3f4b7e53?source=rss-e56820be390b------2</link>
            <guid isPermaLink="false">https://medium.com/p/875b3f4b7e53</guid>
            <category><![CDATA[user-interface]]></category>
            <category><![CDATA[lightning-web-component]]></category>
            <category><![CDATA[javascript]]></category>
            <category><![CDATA[salesforce]]></category>
            <category><![CDATA[web-development]]></category>
            <dc:creator><![CDATA[Shankar Morwal]]></dc:creator>
            <pubDate>Thu, 16 Sep 2021 11:42:32 GMT</pubDate>
            <atom:updated>2021-09-16T12:38:50.307Z</atom:updated>
            <content:encoded><![CDATA[<h3>Salesforce- Export to Excel with Lightning Web Component</h3><h4>With color formatting, alignment and borders.</h4><figure><img alt="salesforce- export to excel with lightning web component" src="https://cdn-images-1.medium.com/max/950/1*-qvIljlsYuuoEGc1fGAaEA.jpeg" /><figcaption>Salesforce- Export to Excel with Lightning Web Component</figcaption></figure><p>Lightening web component (LWC) framework is helping JavaScript developers big time in creating good features and innovative user interfaces on <a href="https://www.habilelabs.io/salesforce-testing-a-beginners-guide/"><strong>Salesforce</strong></a>.</p><p>Recently, we had a requirement to make a feature to export an Excel document from LWC component. There were a few options through which I could even export a plain Excel document, but there was almost nothing, no support at all, for styling like colors, borders, alignment, wrap, border colors, etc.</p><p>This got me thinking how could technology fail in such a common arena, so I did some internal research and came out with a solution.</p><p>Let’s move further to discuss the solution at length-</p><h3>Integrating JavaScript Library with LWC</h3><p>In precise words, I decided to use a JavaScript library <a href="https://www.npmjs.com/package/write-excel-file">write-excel-file</a>, which is available on npm. I integrated this library on <a href="https://www.habilelabs.io/salesforce-decorators-in-lightning-web-components/"><strong>Lightening Web Components</strong></a> and found out that it was throwing exception due to locker service.</p><h4><strong>Let’s build an example based on Excel export-</strong></h4><p>Thereafter, I decided to customize the library <a href="https://www.npmjs.com/package/write-excel-file">write-excel-file</a>to make it compatible with LWC. You can download this version from here.</p><ul><li><strong>First, download the </strong><a href="https://gist.github.com/morwalz/55138b6cf6400589a14ad719e7382292"><strong>write-excel-file.min.js</strong></a><strong>-</strong></li></ul><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/9282653ce3c68849b626a2e2fed88cca/href">https://medium.com/media/9282653ce3c68849b626a2e2fed88cca/href</a></iframe><ul><li><strong>Now, make a folder </strong>writeExcel<strong> in static resources and put the downloaded file </strong><a href="https://gist.github.com/morwalz/55138b6cf6400589a14ad719e7382292"><strong>write-excel-file.min.js</strong></a><strong> in it.</strong></li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*KFL1fdSEIWkSHue4rI9qKA.png" /><figcaption>writeExcel static resource</figcaption></figure><ul><li><strong>Create lightening component </strong><strong>excelJSDemo</strong></li></ul><p>Create a LWC with name excelJSDemo and add the following code to the excelJSDemo.js file.</p><pre><strong>import </strong>{ LightningElement } <strong>from &#39;lwc&#39;</strong>;<br><strong>import </strong>{ loadScript } <strong>from &quot;lightning/platformResourceLoader&quot;</strong>;<br><strong>import </strong>workbook <strong>from &quot;@salesforce/resourceUrl/excelDemo&quot;</strong>;<br><strong>export default class </strong>ExcelJSDemo <strong>extends </strong>LightningElement {<br>    <strong>librariesLoaded </strong>= <strong>false</strong>;<br>    <strong>objectsData </strong>= [<br>        <em>// Object #1<br>        </em>{<br>            <strong>name</strong>: <strong>&#39;John Smith&#39;</strong>,<br>            <strong>dateOfBirth</strong>: <strong>new <em>Date</em></strong>(),<br>            <strong>cost</strong>: 1800,<br>            <strong>paid</strong>: <strong>true<br>        </strong>},<br>        <em>// Object #2<br>        </em>{<br>            <strong>name</strong>: <strong>&#39;Alice Brown Alice Brown Alice Brown Alice Brown Alice Brown Alice Brown&#39;</strong>,<br>            <strong>dateOfBirth</strong>: <strong>new <em>Date</em></strong>(),<br>            <strong>cost</strong>: 2600,<br>            <strong>paid</strong>: <strong>false<br>        </strong>}<br>    ]<br>    <strong>schemaObj </strong>= [<br>        <em>// Column #1<br>        </em>{<br>            <strong>column</strong>: <strong>&#39;Name&#39;</strong>,<br>            <strong>type</strong>: <strong><em>String</em></strong>,<br>            <strong>wrap</strong>: <strong>&#39;true&#39;</strong>,<br>            <strong>color</strong>: <strong>&#39;#ccaaaa&#39;</strong>,<br>            value: student =&gt; student.<strong>name<br>        </strong>},<br>        <em>// Column #2<br>        </em>{<br>            <strong>column</strong>: <strong>&#39;Date of Birth&#39;</strong>,<br>            <strong>type</strong>: <strong><em>Date</em></strong>,<br>            <strong>format</strong>: <strong>&#39;mm/dd/yyyy&#39;</strong>,<br>            value: student =&gt; student.<strong>dateOfBirth<br>        </strong>},<br>        <em>// Column #3<br>        </em>{<br>            <strong>column</strong>: <strong>&#39;Cost&#39;</strong>,<br>            <strong>type</strong>: <strong><em>Number</em></strong>,<br>            <strong>format</strong>: <strong>&#39;#,##0.00&#39;</strong>,<br>            value: student =&gt; student.<strong>cost<br>        </strong>},<br>        <em>// Column #4<br>        </em>{<br>            <strong>column</strong>: <strong>&#39;Paid&#39;</strong>,<br>            <strong>type</strong>: <strong><em>Boolean</em></strong>,<br>            value: student =&gt; student.<strong>paid<br>        </strong>}<br>    ]<br>    renderedCallback() {<br>        <strong><em>console</em></strong>.log(<strong>&quot;renderedCallback xlsx&quot;</strong>);<br>        <strong>if </strong>(<strong>this</strong>.<strong>librariesLoaded</strong>) <strong>return</strong>;<br>        <strong>this</strong>.<strong>librariesLoaded </strong>= <strong>true</strong>;<br>        loadScript(<strong>this</strong>, workbook + <strong>&quot;/writeExcel/write-excel-file.min.js&quot;</strong>)<br>            .then(<strong>async </strong>(data) =&gt; {<br>                <strong><em>console</em></strong>.log(<strong>&quot;success------&gt;&gt;&gt;&quot;</strong>, data);<br>            })<br>            .catch(error =&gt; {<br>                <strong><em>console</em></strong>.log(<strong>&quot;failure--------&gt;&gt;&gt;&gt;&quot;</strong>, error);<br>            });<br>    }<br>    <em>// calling the download function from xlsxMain.js<br>    </em><strong>async </strong>download() {<br>        <strong>let </strong>_self = <strong>this</strong>;<br>        <em>// When passing `objects` and `schema`.<br>        </em><strong>await writeXlsxFile</strong>(_self.<strong>objectsData</strong>, {<br>            <strong>schema</strong>: _self.<strong>schemaObj</strong>,<br>            <strong>fileName</strong>: <strong>&#39;file.xlsx&#39;<br>        </strong>})<br>    }<br>}</pre><ul><li><strong>Update </strong><strong>excelJSDemo.html to add a button to start download -</strong></li></ul><pre>&lt;<strong>template</strong>&gt;<br>    &lt;<strong>lightning-card title=&quot;Exceljs file export demo&quot; icon-name=&quot;custom:custom14&quot;</strong>&gt;<br>        &lt;<strong>button onclick=</strong>{<strong>download</strong>} <strong>class=&quot;btn success&quot;</strong>&gt;Download&lt;/<strong>button</strong>&gt;<br>    &lt;/<strong>lightning-card</strong>&gt;<br>&lt;/<strong>template</strong>&gt;</pre><ul><li><strong>Update </strong><strong>excelJSDemo.js-meta.xml-</strong></li></ul><pre><em>&lt;?</em><strong>xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;</strong><em>?&gt;<br></em>&lt;<strong>LightningComponentBundle xmlns=&quot;http://soap.sforce.com/2006/04/metadata&quot; fqn=&quot;xlsxDemo&quot;</strong>&gt;<br>    &lt;<strong>apiVersion</strong>&gt;46.0&lt;/<strong>apiVersion</strong>&gt;<br>    &lt;<strong>isExposed</strong>&gt;true&lt;/<strong>isExposed</strong>&gt;<br>    &lt;<strong>targets</strong>&gt;<br>        &lt;<strong>target</strong>&gt;lightning__AppPage&lt;/<strong>target</strong>&gt;<br>        &lt;<strong>target</strong>&gt;lightning__RecordPage&lt;/<strong>target</strong>&gt;<br>        &lt;<strong>target</strong>&gt;lightning__HomePage&lt;/<strong>target</strong>&gt;<br>    &lt;/<strong>targets</strong>&gt;<br>&lt;/<strong>LightningComponentBundle</strong>&gt;</pre><ul><li><strong>Deploy and run your code</strong></li></ul><p>Now, you can deploy your code and drag this component to any layout you like. Once you add it to the layout, you will see a download button. I for one, added it as a tab to opportunity layout.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*t5UktDdjVbw9N8bzaJfIAg.png" /><figcaption>Download button</figcaption></figure><p>Once you click the download button, you will be able to download a beautiful Excel sheet with styles and formatting.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/960/1*gyIrJnOZ0WODDT7C27OUAQ.png" /></figure><p>This library has many options for styling, <a href="https://www.npmjs.com/package/write-excel-file">check this link to learn more</a>. Mainly, it supports the following styles-</p><ul><li>align: string - Horizontal alignment of cell content.</li></ul><p><strong>Available values</strong>: &quot;left&quot;, &quot;center&quot;, &quot;right&quot;.</p><ul><li>alignVertical: string - Vertical alignment of cell content.</li></ul><p><strong>Available values</strong>: &quot;top&quot;, &quot;center&quot;, &quot;bottom&quot;.</p><ul><li>height: number - Row height, in &quot;points&quot;.</li><li>span: number - Column span.</li></ul><p>Even if a cell spans several columns, you still have to provide a value for every cell in every row and column.</p><ul><li>rowSpan: number - Row span.</li></ul><p>Even if a cell spans several rows, you still have to provide a value for every cell in every row and column.</p><ul><li>wrap: boolean - Set to true to <a href="https://www.excel-easy.com/examples/wrap-text.html">&quot;wrap&quot;</a> text when it overflows the cell.</li><li>fontWeight: string - Can be used to print text in bold.</li></ul><p><strong>Available values</strong>: &quot;bold&quot;.</p><ul><li>color: string - Cell text color (in Hexadecimal format).</li></ul><p><strong>Example</strong>: &quot;#aabbcc&quot;.</p><ul><li>backgroundColor: string - Cell background color (in Hexadecimal format).</li></ul><p><strong>Example</strong>: &quot;#aabbcc&quot;.</p><ul><li>borderColor: string - Cell border color.</li></ul><p><strong>Example</strong>: &quot;#aabbcc&quot;.</p><ul><li>borderStyle: string - Cell border style.</li></ul><p><strong>Example</strong>: &quot;thick&quot;.</p><ul><li>leftBorderColor</li><li>leftBorderStyle</li><li>rightBorderColor</li><li>rightBorderStyle</li><li>topBorderColor</li><li>topBorderStyle</li><li>bottomBorderColor</li><li>bottomBorderStyle</li></ul><p>That was all, folks! Hope this article was useful for you. Share your queries in the comment box and hit claps 👏 if you liked the blog.</p><h4><strong>Tired of hearing ‘No’ from so-called Salesforce exports with LWC?</strong></h4><p>We, at <a href="https://www.habilelabs.io/">Habilelabs</a>, make every complex user interface with LWC ease and user friendly way. <a href="https://www.habilelabs.io/hire-us/">Contact us</a> to discuss your LWC migration project with us.</p><h3>Also Read-</h3><ul><li><a href="https://medium.com/habilelabs/promises-in-javascript-an-introductory-guide-cabef4837f8b">Promises in JavaScript- An Introductory Guide</a></li><li><a href="https://medium.com/habilelabs/google-flutter-from-the-perspective-of-a-react-native-developer-40794883e242">Google Flutter- From the Perspective of a React Native Developer</a></li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=875b3f4b7e53" width="1" height="1" alt=""><hr><p><a href="https://learn.habilelabs.io/salesforce-export-to-excel-with-lightning-web-component-875b3f4b7e53">Salesforce: Export to Excel with Lightning Web Component</a> was originally published in <a href="https://learn.habilelabs.io/">Minds Verse | HabileLabs</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Async Hooks in Node.js- Features & Use Cases]]></title>
            <link>https://learn.habilelabs.io/async-hooks-in-node-js-features-use-cases-c8cd8372ba6b?source=rss-e56820be390b------2</link>
            <guid isPermaLink="false">https://medium.com/p/c8cd8372ba6b</guid>
            <category><![CDATA[javascript]]></category>
            <category><![CDATA[asynchooks]]></category>
            <category><![CDATA[nodejs]]></category>
            <category><![CDATA[promises]]></category>
            <category><![CDATA[hooks]]></category>
            <dc:creator><![CDATA[Shankar Morwal]]></dc:creator>
            <pubDate>Thu, 09 Sep 2021 09:36:16 GMT</pubDate>
            <atom:updated>2021-09-09T09:53:26.672Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="async hooks in node.js- features &amp; use cases" src="https://cdn-images-1.medium.com/max/950/1*dAwj4HXlstZufEQbj153fA.jpeg" /><figcaption>Async Hooks in Node.js- Features &amp; Use Cases</figcaption></figure><p>Node.js 8 version released a new module called async_hooks. It provides an easy-to-use API to track the lifetime of async resources in Node.js applications.</p><p>It was introduced by the Node team in 2017 and is still in the experimental state.</p><p>The asynchronous resources mentioned here are the objects created by Node.JS that have associated callback and can be called multiple times. Some examples of asynchronous resources are Timeouts, <a href="https://medium.com/habilelabs/promises-in-javascript-an-introductory-guide-cabef4837f8b?source=collection_home---4------19-----------------------">Promises</a>, TCPWRAP, Immediates, etc.</p><p>We’ll learn more about Async hooks and their use cases in this blog. Let’s get going then-</p><h3><strong>Why Do We Need Async Hooks?</strong></h3><p>Async resources are created by async process for example file read, database read operation, external API call. So naturally async resources keep track of callback which will be called once the process is completed. But, if we need to track the async resource like what is happening in the middle of an async resource execution, we don’t have any way to do that.</p><p>The typical lifecycle of such an async resource is similar to this:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/950/1*YRNwUnva2meOezmXh9rmyQ.jpeg" /><figcaption>Lifecycle of an async resource</figcaption></figure><p>To solve this concern, Nodejs provided async hooks to spy on the lifecycle of async resources.</p><p>Enough talking, show me the code!</p><h4><strong>Hello word to async hooks-</strong></h4><pre><strong>const </strong>fs = require(<strong>&#39;fs&#39;</strong>);<br><strong>const </strong>{ fd } = process.stdout;<br><strong>const </strong>async_hooks = require(<strong>&#39;async_hooks&#39;</strong>)<br><strong>function </strong>init(asyncId, type, triggerAsyncId, resource) {<br>    fs.writeSync(fd, <strong>`Init callback async id --&gt; </strong>${asyncId} <strong>\n`</strong>);<br>}<br><strong>function </strong>destroy(asyncId) {<br>    fs.writeSync(fd, <strong>`Destroy callback async id --&gt;</strong>${asyncId} <strong>\n`</strong>);<br>}<br><strong>const </strong>asyncHook = async_hooks.createHook({ init: init, destroy: destroy });<br>asyncHook.enable();<br><br><em>setTimeout</em>(()=&gt;{<br>    <em>//do nothing<br></em>}, 1000);</pre><pre>//output<br>/*<br>Init callback async id --&gt; 4<br>Destroy callback async id --&gt;4<br>*/</pre><p>In the example above, we have setTimeout is making an async operation. We have created two async hooks init and destroy. When we execute the code, we can see that it is calling init first, and then callsdestroy function. You might be wondering why we are using fs.writeSync to print on console rather than using console.log.</p><p>Console.log is async function itself, so this will cause async hooks again, and will cause infinite recursion. So we can not use any async code inside async hooks. It will be discussed later on again in later in this article.</p><h3><strong>Async Hooks APIs</strong></h3><p>Essentially, the async hooks API provides these five key event functions that are called during different time and instances of the resource’s lifecycle, to track the async resources.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/950/1*pmx4ygte5W9EhTjOT8ymzw.jpeg" /><figcaption>Key Asynchronous Hooks</figcaption></figure><p>You have to specify the event that you want to trigger out of the following while creating an instance.</p><p>All the callbacks are optional. Let’s make this statement a little more obvious- It means if the cleanup data of the resource is to be tracked, then you only need to pass the destroy callback.</p><h4><strong>init</strong></h4><p>The init callback is called whenever a call is created that has the possibility of triggering an asynchronous event. Just for the record, at this point, we’ve already associated the hook with an async resource.</p><p>init callback receives these parameters when called-</p><ul><li><strong>asyncId</strong>: Each async resource, when identified, is allotted with a unique ID.</li><li><strong>type</strong>: It depicts the type of the async resource in string form that triggered init callback.</li><li><strong>triggerAsyncId</strong>: asyncId of the resource for whose context the async resource was created. It shows why a specific resource was created.</li><li><strong>resource</strong>: It represents the reference to the async operation that is released during destroy.</li></ul><p>All the other callbacks get only one parameter- asyncId.</p><h4><strong>Before</strong></h4><p>Whenever an async operation initiates or completes, a callback notifies the user of its status. The before callback is called right before this mentioned callback is executed, and the relevant resource will be assigned with a unique asyncId identifier.</p><p>The before callback can be called any times from 0 to n. For instance, when the asynchronous operation gets cancelled, it will be called 0 times, on the other hand, the persistent type resources can call it multiple times.</p><h4><strong>After</strong></h4><p>Similar to before, it is called post-execution of the relevant asynchronous resource or right after when the specified callback in before callback finishes its execution.</p><h4><strong>Destroy</strong></h4><p>It’s quite easy to guess, isn’t it? Yes, you guessed it right!</p><p>It is called every time the asynchronous resource, corresponding to the unique asyncId, is destroyed regardless of whatever happened to its callback function.</p><p>However, in some cases, the resource depend upon the garbage collection for its cleanup which might cause a memory leak in the application, which results in avoid calling destroy. If the resource does not rely upon the garbage, then it won’t be a problem and destroy will do the cleaning.</p><h4><strong>promiseResolve</strong></h4><p>This callback is triggered when the Promise gets its resolve function, which is invoked either directly or by some external means to resolve a promise.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/950/1*-Z2yjUB-R8nmF6sMuRcD3w.jpeg" /><figcaption>Promise Resolve</figcaption></figure><h3><strong>Use Cases of Async Hooks</strong></h3><p>Listed below are some major features and use cases of async hooks-</p><h4><strong>- Promise Execution Tracking</strong></h4><p>Async hooks are preferably used to track the lifecycle of promises and their execution, as promises are also asynchronous resources.</p><p>Whenever a new promise is created, the init callback runs. The before and after hooks run pre- and post-completion of a PromiseReactionJob and the resolve hook is called when a promise is resolved.</p><p><a href="https://medium.com/habilelabs/promises-in-javascript-an-introductory-guide-cabef4837f8b">Promises in JavaScript- An Introductory Guide</a></p><h4><strong>- Web Request Context Handling</strong></h4><p>This is another major use case of Async Hooks, where it stores relevant information in context to the request during its lifetime. This feature becomes highly useful to track the user’s behavior in a server.</p><p>With async hooks, you can easily store the context data and access it anywhere and anytime in the code.</p><p>The process starts with a new request to the server, which initiates calling createRequestContext function to get data to store in a Map. Every async operation initiated as part of this request will be saved in the Map along with the context data (Here init plays an important part).</p><p>Next, destroy keeps the size of the Map under control and do the cleaning. This is how you can get the current execution context by calling getContextData anytime.</p><h4><strong>- Error Handling with Async Hooks</strong></h4><p>Whenever an async hook callback throws an error, the application follows the stack trace and exits due to an uncaught exception. Unless you run the application with-abort-on-uncaught-exception, which will print the stack trace exiting the application, the exit callbacks will still be called.</p><p>This error handling behavior is due to the fact that all these callbacks run at potentially unstable points, for instance during construction or destruction of a class. This process prevents any unintentional and potential abort to the process by closing it quickly.</p><h4><strong>- Printing in Async Hooks</strong></h4><p>Printing is an asynchronous operation and console.log() triggers calling async callbacks. However, using such asynchronous operations inside async callbacks causes infinite recursion.</p><p>For instance, when init runs, the console.log() will trigger another init callback causing endless recursion and increasing stack size.</p><p>To avoid this, you should use a synchronous operation like fs.writeFileSync(file, msg, flag) while debugging as it will print to the file without invoking AsyncHooks recursively.</p><p>If the logging requires an asynchronous operation, you can track what caused the async operation to initiate using AsyncHooks. As it was logging itself that invoked the AsyncHooks callback, you can skip it which will break the infinite recursion cycle.</p><h4><strong>- Enhanced Stack Traces</strong></h4><p>The creator of Node.js, Ryan Dahl, talked about debugging problems in node.js due to event loops, which kills the stack trace. As the async hooks facilitate better tracing of async resources, it allows developers to improve and enrich the stack trace.</p><h3><strong>Bottom Line</strong></h3><p>Do you know that you can also measure the duration of an asynchronous operation in real-time? Yes you can, but by integrating Async hooks module with Performance API module.</p><p>Well, this was all about async hooks. I would suggest you to refer to the below link if you are interested to learn more about async hooks-ink-</p><p><a href="https://nodejs.org/api/async_hooks.html">Async hooks | Node.js v22.8.0 Documentation</a></p><p>If you liked this blog, don’t forget to hit the clap icon (multiple times 😉).</p><p>Looking to hire nodejs experts or outsource the project, connect with us <a href="https://www.habilelabs.io/hire-us/">here</a>.</p><p><em>Originally published at </em><a href="https://www.habilelabs.io/async-hooks-in-node-js-features-and-use-cases/"><em>https://www.habilelabs.io</em></a><em> on September 09, 2021.</em></p><h3>Read More-</h3><ul><li><a href="https://medium.com/habilelabs/data-fetching-in-next-js-pre-rendering-types-140441959c8a">Data Fetching in Next.js — Pre-rendering Types</a></li><li><a href="https://medium.com/habilelabs/why-choose-nest-js-over-other-node-frameworks-68a13fa1e2c8">Why Choose Nest.js over Other Node Frameworks?</a></li><li><a href="https://medium.com/habilelabs/hydra-a-node-js-microservice-library-fcf47b3e5555">Hydra — A Node.js Microservice Library</a></li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=c8cd8372ba6b" width="1" height="1" alt=""><hr><p><a href="https://learn.habilelabs.io/async-hooks-in-node-js-features-use-cases-c8cd8372ba6b">Async Hooks in Node.js- Features &amp; Use Cases</a> was originally published in <a href="https://learn.habilelabs.io/">Minds Verse | HabileLabs</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[How to Set Up Cloud Infrastructure for Video-On-Demand (VOD) Using AWS and Node.Js]]></title>
            <link>https://learn.habilelabs.io/how-to-set-up-cloud-infrastructure-for-video-on-demand-vod-using-aws-and-node-js-f8822b7fd4d7?source=rss-e56820be390b------2</link>
            <guid isPermaLink="false">https://medium.com/p/f8822b7fd4d7</guid>
            <category><![CDATA[nodejs]]></category>
            <category><![CDATA[vod]]></category>
            <category><![CDATA[aws]]></category>
            <category><![CDATA[video-on-demand]]></category>
            <dc:creator><![CDATA[Shankar Morwal]]></dc:creator>
            <pubDate>Mon, 27 Apr 2020 17:23:39 GMT</pubDate>
            <atom:updated>2020-05-14T04:42:09.567Z</atom:updated>
            <content:encoded><![CDATA[<p>In these corona-times when the whole country or let’s say ‘almost the whole world’ is under lockdown, VOD (Video-on-demand) and live videos are getting a great deal of attention.</p><p>I am currently working on a mobile app that allows schools and teachers to get connected with the students with their premium content, which only allows the registered students to watch the video content.</p><p>In this article, I’m going to share my experience about how did I set up cloud infrastructure for video on demand (VOD) using AWS and node.js.</p><h3>What’s the Need For this Special Infrastructure??</h3><p>For someone beginner, who does not have any experience with VOD might wonder why not just MP4? Why do we need a special infrastructure? You can just store the MP4 file and everyone can access and play it. This sounds just fine but limited to the only convention uses of a video, for instance where the video size is small, it will play fine with video players. But when the large video files are concerned, it becomes extremely difficult for a video player to play them as they need to be downloaded first and then played on.</p><p>Now imagine having two users, one of them having extremely good internet speed while another one with poor network speed. Now, when both users try to stream the same-quality video on their devices, there is no doubt that the first use will rather enjoy the video of wonderful speed but the other user will face video-buffering. <br>All these scenarios will lead to poor user experience. That’s why we need more reliable and practical methods to stream videos over the internet. There are various popular formats for video streaming.</p><h3>Most Popular Video Format Options</h3><p>To solve the above-mentioned problem, there are four popular video formats. Let’s see what are they and how can they offer more productive outputs-</p><ol><li><a href="https://developer.apple.com/documentation/http_live_streaming"><strong>HLS (HTTP live streaming)</strong></a><strong>: </strong>It is a media streaming protocol for delivering visual and audio media to viewers over the internet. It was first launched by Apple company back in 2009.</li></ol><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*PAzLKs_cuMNTq11rRDMmHw.png" /></figure><p>In this format, the whole video is broken into multiple small files of 10 seconds each and stored in a special format with .<strong>ts</strong> extension and there will be an m3u8 file that will work like the manifest file to keep track of these small files.</p><p>So, while we play the m3u8 file, it dynamically loads the chunks and video start playing as soon as the first chunk gets loaded in the player.</p><p>It uses an adaptive bit rate which helps video players decide based on network speed, what quality of the video to load.</p><p>I recommend this format as it is fully supported by all famous browsers, apple devices, android devices. Read more about HLS <a href="https://en.wikipedia.org/wiki/HTTP_Live_Streaming">here</a></p><p><strong>2. DASH </strong>(<strong>Dynamic Adaptive Streaming</strong>): It is the newest format, which has several advantages. However, I will not go into more detail. It is not yet supported on apple devices.</p><p><strong>3. CMAF (Common Media Application Format)</strong>: It was proposed by Apple and Microsoft combined. Before this format, there was no common standard, so broadcasters have to store the same media in multiple formats, which was costly.</p><p>Many media companies and CDNs are moving to this format. Read more <a href="https://developer.apple.com/documentation/http_live_streaming/about_the_common_media_application_format_with_http_live_streaming">here</a>.</p><p><strong>4. MSS (Microsoft Smooth Streaming)</strong>: This format was launched in the year 2008 and helped to stream the Summer Olympics 2008. It is used in Xbox One devices. It’s not a very famous format.</p><p>So now, we are aware that we need other formats than mp4 to stream video content. But we need to produce mp4 files first and then we can convert them to the above-mentioned formats.</p><p>From now on, I will prefer the HLS format in this article.</p><h3>Convert Files from MP4 to HLS Format</h3><p>Though there are many great tools that can do this, I prefer using <a href="https://www.ffmpeg.org/">FFmpeg</a>. It is a great tool to convert your files from one format to another. Also, it has a node.js library that can be used with node.js.</p><p>But to have a quick turnaround and save development cost, I was looking for a ready-made infrastructure and came across AWS media services, only to discover that it was the perfect choice for this task.</p><h3>Setting Up AWS Cloud Infrastructure for Video-On-Demand</h3><p>To get started quickly, I found this <a href="https://aws.amazon.com/solutions/implementations/video-on-demand-on-aws/">AWS ready-made cloud formation</a> template. All tools and architecture of this solution have been shown in the below-given image-</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*qi6VNRH1VtgcTILDUEZ1AQ.png" /></figure><p>Source of reference article image <a href="https://aws.amazon.com/solutions/implementations/video-on-demand-on-aws/">here</a>.</p><p>This solution uses s3 buckets, AWS step functions, Media Convert, media package, AWS lambda functions, DynamoDB, cloud watch, CloudFront, and SNS service.</p><p>The cloud formation template I mentioned above, comes with HLS, CMAF, MSS, DASH formats. So when you pass on one Mp4 file, media convert will convert in all formats listed above. If you read about the pricing of media convert then you will find that it costs you a fixed rate per minute multiplied by the number of formats.</p><p>So if you keep more formats then cost will be high. Thus, to customize the template as per your requirements, you need to clone the following repository-</p><p><a href="https://github.com/awslabs/video-on-demand-on-aws">awslabs/video-on-demand-on-aws</a></p><p>To customize this template, you will need to have basic knowledge of node.js and python and some knowledge of how to list the tools of AWS. By the way, sometimes the template does not work in other regions then default. To fix this problem you can follow this <a href="https://github.com/awslabs/video-on-demand-on-aws/issues/67">link</a>.</p><p>So now you can go to cloud formation and select either the default template or the customized template and launch the stack after filling the questionnaire.</p><p>You will now get two s3 buckets. One will be a source bucket and another will be the destination bucket. In source bucket, you will be uploading source video (mp4), once the uploading gets completed, step function will trigger media convert and it will convert your file into the decided format.</p><p>Once the conversion is done, it will store the converted file into the destination s3 bucket and the file will be ready for ingest by media package and CloudFront. You will be notified by SNS with the converted ready URL. Now, you can play this URL with any popular player.</p><h3>Integrate this Stack With Backend</h3><p>Your backend stack does not need to be aware of this whole stack. For the backend, there is a black box that has a bucket where we drop files which further converts the file and we get URLs to ingest.</p><p>So make a connection with the source bucket, upload the file to the s3 bucket. Once conversion completed, to get to know the file status, you will need to make a Webhook that will be triggered and notified with conversion status.</p><p>There can be another way by updating the lambda function which can directly call the Webhook without involving SNS. I am not writing the actual code to upload the file on s3 as there are 100s of good articles to demonstrate how to upload a file on s3. Rather I preferred to upload directly via frontend, for that you can generate a signed URL from backend and send it to frontend and upload from there.</p><h3>Summary</h3><p>This sort of ready-made solution gives an edge over the tools that we need to set up ourselves. It saves a lot of development costs as well as time and scales well as per demand. If an urgent need does arise then it makes sense to spend more in terms of development cost to save infrastructure cost.</p><p>In case you are looking for a team to develop Video-on-demand or live video streaming solutions, you are ever-welcomed to <a href="https://www.habilelabs.io/hire-us/">our company</a>.</p><p>For any questions or feedback about the article, please write a comment below. If you liked the article then clap for it. Do you know you can clap more than 50 times??</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=f8822b7fd4d7" width="1" height="1" alt=""><hr><p><a href="https://learn.habilelabs.io/how-to-set-up-cloud-infrastructure-for-video-on-demand-vod-using-aws-and-node-js-f8822b7fd4d7">How to Set Up Cloud Infrastructure for Video-On-Demand (VOD) Using AWS and Node.Js</a> was originally published in <a href="https://learn.habilelabs.io/">Minds Verse | HabileLabs</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[React Native, React Web and Expo-Together in One Monorepo]]></title>
            <link>https://medium.com/@shankarmorwal/react-native-react-web-and-expo-together-in-one-monorepo-593c1d083727?source=rss-e56820be390b------2</link>
            <guid isPermaLink="false">https://medium.com/p/593c1d083727</guid>
            <category><![CDATA[javascript]]></category>
            <category><![CDATA[react]]></category>
            <category><![CDATA[expo]]></category>
            <category><![CDATA[react-native]]></category>
            <category><![CDATA[monorepo]]></category>
            <dc:creator><![CDATA[Shankar Morwal]]></dc:creator>
            <pubDate>Wed, 11 Mar 2020 07:59:52 GMT</pubDate>
            <atom:updated>2020-03-11T08:00:41.259Z</atom:updated>
            <content:encoded><![CDATA[<p>By <a href="https://www.linkedin.com/in/shankarmorwal/"><strong><em>Shankar Morwal</em></strong></a></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/950/1*OP9Y-xE7zCLQIqpnEAR4QQ.jpeg" /></figure><p>I am working on a project where we have a React web app, React Native app and another React Native app which is built using expo. All these three projects share a common backend, service layer and share redux logic.</p><p>There are some other common components as well that can be used across react native and expo app.</p><p>So, we needed an architecture to avoid duplicate code across the projects. I stopped for a moment and thought, what could be better than the monorepo architecture? It will also solve the problem stated above.</p><p>The Monorepo architecture provides the leverage to reuse much of the service layer, redux related code, and other shareable pieces of code across the components.</p><p>In the tutorial below, I will show step by step how can you use react web, react native and react native Expo project in one monorepo.</p><p>Let’s check out what exactly is a Monorepo??</p><h3><strong>Monorepo??</strong></h3><p>As stated by <a href="https://en.wikipedia.org/wiki/Monorepo">Wikipedia</a>-</p><blockquote>A <strong>monorepo,</strong> syllabic abbreviation of <em>monolithic repository,</em> is a software development strategy where code for many projects is stored in the same repository.</blockquote><figure><img alt="" src="https://cdn-images-1.medium.com/max/777/1*7TzARrdTuzxkwMxDTf0ZBA.png" /><figcaption>Monorepo</figcaption></figure><p>In simple words, monorepo contains more than one project code, which allows us to share code between many projects. Each project can have its own build and deployment system or can share build systems.</p><p>Many companies, including Google, Twitter, Facebook, etc. follow this process.</p><p>Now, I will discuss all the things that we used, the challenges we faced and resolved during this journey.</p><p>You can also take the help of the demo repository I created. (Link is given at the end of this tutorial)</p><h3>Getting Started with Monorepo for React and React-Native</h3><p>We decided to use <a href="https://classic.yarnpkg.com/en/docs/workspaces/">yarn-workspaces</a> for our use-case. <a href="https://lerna.js.org/">Lerna</a> is an excellent tool to manage yarn workspaces.</p><p>As described on the Lerna website about itself -</p><blockquote>Lerna is a tool that optimize the workflow around managing multi-package repositories with git and npm.</blockquote><p>To use Lerna, we will first need to install it. I am assuming you’ve already had Node.js and npm installed in your system.</p><pre><strong>#Installing Lerna 2.x</strong></pre><pre>$ npm install --global lerna</pre><pre><strong>#Creating project repository</strong></pre><pre>$ git init lerna-repo &amp;&amp; cd lerna-repo</pre><pre><strong>#Turning folder into Lerna workspace</strong></pre><pre>$ lerna init</pre><p>Your repository will look like</p><pre>lerna-repo/<br>  packages/<br>  package.json<br>  lerna.json</pre><p>Now, you are ready with Lerna Workspace. Here, the packages, as per the name dictates, will contain different modules.</p><p>Let’s start adding a React js project into packages-</p><h3>Create React App into Monorepo</h3><pre><strong>#Creating app in packages folder</strong></pre><pre>$ npx create-react-app &lt;app-name&gt;</pre><pre><strong>#Example</strong></pre><pre>$ npx create-react-app web-app</pre><p>Please note that <em>NPX supports only npm 5.2+ and higher versions, so if you have a lower version then you definitely need to upgrade it.</em></p><p>Once it is completed, go to the root folder of your repository and run-</p><pre>$ yarn install</pre><p>All the required modules will be installed and hoisted to the root folder by this command.</p><p>To start the web application-</p><pre>$ lerna --scope=web-app run start</pre><p>Congrats!! You are done with your first package.</p><h3>Add React Native App Package</h3><p>Go to the packages folder and run the following command-</p><pre>$ npx react-native init &lt;App name&gt;</pre><p>That is,</p><pre>$ npx react-native init NativeApp</pre><p>It will create all the folders and files required for the native app.</p><p>Once the process gets completed, go to the root folder and install packages again-</p><pre>$ yarn</pre><p>It will create React Native and other dependencies to root in <em>npm_modules</em> of monorepo. However, <em>create-react-native-cli</em> command expects react-native to be inside the package. If we still try to run it, there will be an error.</p><p>To fix this issue, we will use the yarn-workspaces <a href="https://classic.yarnpkg.com/blog/2018/02/15/nohoist/">nohoist</a> feature.</p><p>In workspaces key of JSON package, we will add-</p><pre>&quot;nohoist&quot;: [&quot;**/react-native&quot;, &quot;**/react-native/**&quot;]</pre><p>Now, we’re gonna install packages again using yarn command.</p><pre>$ yarn</pre><p>Then we can start the apps using the following commands.</p><pre><strong>#Starting the android app</strong></pre><pre>lerna --scope=NativeApp run android</pre><pre><strong>#Start iOS app</strong></pre><pre>lerna --scope=NativeApp run ios</pre><p>Please note that <em>an iOS app will work in MacBook only.</em></p><p>Well, now you have a repository that has both React web app and React Native mobile apps.</p><p>As we move further, we will try to add a React-Native expo project in this Monorepo as another package. If you don’t need an expo project, then you’re done here. You can stop right here!</p><h3>Add Expo App Package</h3><p>Let’s start by creating an <a href="https://expo.io/">expo project</a> in the ‘packages’ folder.</p><p>Inside the folder, run the following command.</p><pre>$ expo init &lt;project-name&gt;</pre><p>That is,</p><pre>$ expo init ExpoApp</pre><p>It will create the project structure and will install the packages. Once completed, you have a working expo project in hand. But for now, we need to make it work as a monorepo.</p><p>First, delete the npm modules, then, go to the root folder and install packages again-</p><pre>$ yarn</pre><p>It will install <em>npm_modules</em> in the root folder and link them to the expo package.</p><p>But expo projects do not work on Monorepos. In order to finesse the expo project to make them work together with yarn workspaces, we will use <a href="https://github.com/expo/expo/tree/master/packages/expo-yarn-workspaces">expo-yarn-workspaces</a> package.</p><h3>How to Make Expo Work with Monorepos??</h3><ol><li>Add <em>expo-yarn workspaces</em> as devDependency to the expo project, inside the ExpoApp folder.</li></ol><pre>$ yarn add --dev expo-yarn-workspaces</pre><p>2. Add a postinstall script to <em>package.json</em>.</p><p>3. Add &quot;postinstall&quot;: &quot;expo-yarn-workspaces postinstall&quot; under the &quot;scripts&quot; object in the app&#39;s <em>package.json</em> file.</p><blockquote><strong><em>As per the documentation, </em></strong><strong><em>expo-yarn-workspaces work only on macOS and UNIX based systems, Windows is not supported.</em></strong></blockquote><p>If we want it to work on Windows as well, then we need to make slight modifications to it.</p><p>Firstly, remove the postinstallscript from <em>package.json</em> and move it to the main <em>package.json-</em></p><pre><strong>&quot;postinstall&quot;</strong>: <strong>&quot;cd ./packages/ExpoApp &amp;&amp; expo-yarn-workspaces postinstall&quot;</strong></pre><p>I tested the above workaround on macOS &amp; Windows, and guess what?? It works like charm.</p><p>4. Now, define the entry module in the &quot;main&quot; field of package.json.</p><p>5. Specify &quot;__generated__/AppEntry.js&quot; as the value of the &quot;main&quot; field in package.json</p><p>Here is how the final <a href="https://raw.githubusercontent.com/habilelabs/expo-react-react-native-monorepo-example/master/package.json">package.json</a> will look like-</p><pre>{<br>  <strong>&quot;name&quot;</strong>: <strong>&quot;root&quot;</strong>,<br>  <strong>&quot;private&quot;</strong>: <strong>true</strong>,<br>  <strong>&quot;devDependencies&quot;</strong>: {<br>    <strong>&quot;lerna&quot;</strong>: <strong>&quot;^3.20.2&quot;<br>  </strong>},<br>  <strong>&quot;dependencies&quot;</strong>: {<br>    <strong>&quot;metro-config&quot;</strong>: <strong>&quot;^0.56.0&quot;<br>  </strong>},<br>  <strong>&quot;scripts&quot;</strong>: {<br>    <strong>&quot;android&quot;</strong>: <strong>&quot;lerna --scope=NativeApp run android --stream --&quot;</strong>,<br>    <strong>&quot;ios&quot;</strong>: <strong>&quot;lerna --scope=NativeApp run ios --stream --&quot;</strong>,<br>    <strong>&quot;web&quot;</strong>: <strong>&quot;lerna --scope=web-app run start --stream --&quot;</strong>,<br>    <strong>&quot;expo&quot;</strong>: <strong>&quot;lerna --scope=ExpoApp run start --stream --&quot;</strong>,<br>    <strong>&quot;postinstall&quot;</strong>: <strong>&quot;cd ./packages/ExpoApp &amp;&amp; expo-yarn-workspaces postinstall&quot;<br>  </strong>},<br>  <strong>&quot;workspaces&quot;</strong>: {<br>    <strong>&quot;packages&quot;</strong>: [<br>      <strong>&quot;packages/*&quot;<br>    </strong>],<br>    <strong>&quot;nohoist&quot;</strong>: [<strong>&quot;**/react-native&quot;</strong>, <strong>&quot;**/react-native/**&quot;</strong>, <strong>&quot;**/expo&quot;</strong>, <strong>&quot;**/expo/**&quot;</strong>]<br>  }<br>}</pre><p>6. Create metro.config.js in ExpoApp root folder with the following content-</p><pre>const { createMetroConfiguration } = require(&#39;expo-yarn-workspaces&#39;);<br><br>module.exports = createMetroConfiguration(__dirname);</pre><p>5. Reference metro.config.js in the <em>app.json</em> file inside the expo key.</p><pre>&quot;packagerOpts&quot;: {<br>  &quot;config&quot;: &quot;metro.config.js&quot;<br>}</pre><p>Now, go to the root folder and install packages again, using $ yarn .</p><pre><strong>#Start expo app</strong></pre><pre>$ lerna --scope=ExpoApp run start</pre><p>It will successfully start the expo app. But when you scan the app code on it, you will get an error as ‘react-native not found’.</p><p>As we said earlier that React Native should not be hoisted but the expo package is still hoisted. As a result, expo cannot find React-Native.</p><p>So, we need to update the hoisting of packages inside the <em>package.json</em> file.</p><pre><strong>&quot;nohoist&quot;</strong>: [<strong>&quot;**/react-native&quot;</strong>, <strong>&quot;**/react-native/**&quot;</strong>, <strong>&quot;**/expo&quot;</strong>, <strong>&quot;**/expo/**&quot;</strong>]</pre><p>After updating the <a href="https://github.com/habilelabs/expo-react-react-native-monorepo-example/blob/master/package.json"><em>package.json</em></a> file with proper hoisting, we need to install the packages again using $ yarn .</p><p>Now try starting the expo project again-</p><pre>$ lerna --scope=ExpoApp run start</pre><p>Wow!! You’ll see that the Expo app has started working inside the monorepo environment.</p><p>Together with the expo project, you can run the React web app and React Native projects as well.</p><p>Here is the full folder structure-</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/367/1*LTX8NA-PdZ7cFTcCrYyQGQ.png" /></figure><p>You will find the full code <a href="https://github.com/habilelabs/expo-react-react-native-monorepo-example">example here</a>.</p><p><a href="https://github.com/habilelabs/expo-react-react-native-monorepo-example">habilelabs/expo-react-react-native-monorepo-example</a></p><p>All the code is quite simple and straightforward. I hope I’ve made every step very clear. Furthermore, if you have got any queries, feel free to reach me out. Stay tuned with us for more similar <a href="https://www.habilelabs.io/blog/">Tech Blogs</a>.</p><p>Your feedback, suggestions, and comments are most welcome.</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=593c1d083727" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[How To Install Node.js on Ubuntu 16.04 and on 18.04]]></title>
            <link>https://learn.habilelabs.io/how-to-install-node-js-on-ubuntu-16-04-and-on-18-04-4037b797a1c4?source=rss-e56820be390b------2</link>
            <guid isPermaLink="false">https://medium.com/p/4037b797a1c4</guid>
            <dc:creator><![CDATA[Shankar Morwal]]></dc:creator>
            <pubDate>Tue, 17 Jan 2017 08:07:27 GMT</pubDate>
            <atom:updated>2020-04-26T16:44:18.984Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/424/0*PCLN2bs4-FkpQAy-.png" /></figure><h3>Introduction</h3><p>Node.js is a JavaScript platform for general-purpose programming that allows users to build network applications quickly. By leveraging JavaScript on both the front-end and the back-end, development can be more consistent and be designed within the same system.</p><p>There are 100s of articles which showcase to install specific version of nodejs on ubuntu machines, but it hard to find if you are willing to install one specific version at one place</p><h3>Prerequisites</h3><p>This guide assumes that you are using Ubuntu 16.04. Before you begin, you should have a non-root user account with sudo privileges set up on your system.</p><p>Please follow following steps to install node.js on server.</p><pre>$sudo apt-get update</pre><pre># for Node.js v4 <br>$curl -sL <a href="https://deb.nodesource.com/setup_4.x">https://deb.nodesource.com/setup_4.x</a> | sudo -E bash - </pre><pre># OR for Node.js v5 <br>$curl -sL <a href="https://deb.nodesource.com/setup_5.x">https://deb.nodesource.com/setup_5.x</a> | sudo -E bash - </pre><pre># OR for Node.js v6 <br>$curl -sL <a href="https://deb.nodesource.com/setup_6.x">https://deb.nodesource.com/setup_6.x</a> | sudo -E bash - </pre><pre># OR for Node.js v7 <br>$curl -sL <a href="https://deb.nodesource.com/setup_7.x">https://deb.nodesource.com/setup_7.x</a> | sudo -E bash -</pre><pre># OR for Node.js v8 <br>$curl -sL <a href="https://deb.nodesource.com/setup_7.x">https://deb.nodesource.com/setup_8.x</a> | sudo -E bash -</pre><pre># OR for Node.js v9 <br>$curl -sL <a href="https://deb.nodesource.com/setup_7.x">https://deb.nodesource.com/setup_9.x</a> | sudo -E bash -</pre><pre># OR for Node.js v10 <br>$curl -sL <a href="https://deb.nodesource.com/setup_7.x">https://deb.nodesource.com/setup_10.x</a> | sudo -E bash -</pre><pre># OR for Node.js v11 <br>$curl -sL <a href="https://deb.nodesource.com/setup_7.x">https://deb.nodesource.com/setup_11.x</a> | sudo -E bash -</pre><pre># OR for Node.js v12 <br>$curl -sL <a href="https://deb.nodesource.com/setup_7.x">https://deb.nodesource.com/setup_12.x</a> | sudo -E bash -</pre><pre>$sudo ln -s /opt/node/bin/node /usr/local/bin/node <br>$sudo ln -s /opt/node/bin/npm /usr/local/bin/npm</pre><pre>$sudo apt-get install -y build-essential</pre><p>You can check your installation via node -v command. This will return you version of node.js you just installed.</p><p>Please note if you which ever you major version number you choose it will install the stable LTS version of that range.</p><p><em>Originally published at </em><a href="http://www.morwalz.com/install-node-js-ubuntu-16-04-14-04/"><em>http://www.morwalz.com</em></a><em> .</em></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=4037b797a1c4" width="1" height="1" alt=""><hr><p><a href="https://learn.habilelabs.io/how-to-install-node-js-on-ubuntu-16-04-and-on-18-04-4037b797a1c4">How To Install Node.js on Ubuntu 16.04 and on 18.04</a> was originally published in <a href="https://learn.habilelabs.io/">Minds Verse | HabileLabs</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
    </channel>
</rss>