<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>nodejs | Nerdpress.org</title>
	<atom:link href="https://nerdpress.org/tag/nodejs/feed/" rel="self" type="application/rss+xml" />
	<link>https://nerdpress.org</link>
	<description>...dev, tech problems and solutions.</description>
	<lastBuildDate>Fri, 12 Apr 2024 08:01:50 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>
	<item>
		<title>Monorepo with NPM workspaces</title>
		<link>https://nerdpress.org/2024/04/12/monorepo-with-npm-workspaces/</link>
		
		<dc:creator><![CDATA[Ivo Bathke]]></dc:creator>
		<pubDate>Fri, 12 Apr 2024 08:01:50 +0000</pubDate>
				<category><![CDATA[JS]]></category>
		<category><![CDATA[node.js]]></category>
		<category><![CDATA[NPM]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Monorepo]]></category>
		<category><![CDATA[nodejs]]></category>
		<guid isPermaLink="false">https://nerdpress.org/?p=3300</guid>

					<description><![CDATA[<p>I recently converted a project into a Monorepo.I had a cli part and an Astro StaticSiteGenerator part. At some point I felt like these parts would be entangled too much so I decided to separate them. Since they were still related they should stay in one repo but have their own dependencies and separate processes. &#8230; </p>
<p class="link-more"><a href="https://nerdpress.org/2024/04/12/monorepo-with-npm-workspaces/" class="more-link">Continue reading<span class="screen-reader-text"> "Monorepo with NPM workspaces"</span></a></p>
The post <a href="https://nerdpress.org/2024/04/12/monorepo-with-npm-workspaces/">Monorepo with NPM workspaces</a> first appeared on <a href="https://nerdpress.org">Nerdpress.org</a>.]]></description>
										<content:encoded><![CDATA[<p>I recently converted a project into a Monorepo.<br />I had a cli part and an Astro StaticSiteGenerator part. <br />At some point I felt like these parts would be entangled too much so I decided to separate them. Since they were still related they should stay in one repo but have their own dependencies and separate processes. I still could have kept this in one Astro project with a cli folder but so it feels cleaner structured.</p>



<p>I chose NPM as my package manager since it comes bundled with node and so I decided to try out <a href="https://docs.npmjs.com/cli/v7/using-npm/workspaces" title="">NPM workspaces</a> as my MonoRepo approach.</p>



<p>So here are my takeaways</p>



<span id="more-3300"></span>



<p><strong>1.  Setup</strong></p>



<ul class="wp-block-list">
<li>The NPM workspaces Monorepo has one root dir with one package.json which defines the workspaces, but besides this it is more or less empty. The package.json defines a workspace directory which contains the sub projects. <br />As of now you can&#8217;t use <code>npm init</code> for this but have to create the main package.json manually.</li>
</ul>


<pre class="wp-block-code"><span><code class="hljs language-javascript">  <span class="hljs-string">"name"</span>: <span class="hljs-string">"workspaces-example"</span>,
  <span class="hljs-string">"workspaces"</span>: &#91;
    <span class="hljs-string">"packages/*"</span>
  ],</code></span></pre>


<figure class="wp-block-image size-full"><a href="https://nerdpress.org/wp-content/uploads/2024/04/npm-workspaces-directories.png"><img fetchpriority="high" decoding="async" width="258" height="210" src="https://nerdpress.org/wp-content/uploads/2024/04/npm-workspaces-directories.png" alt="" class="wp-image-3303"/></a></figure>



<ul class="wp-block-list">
<li>The sub projects each have their own package.json with all necessary dependencies for this specific project. The sub projects can be initialised by <code>npm init -w packages/cli</code></li>



<li>To add dependencies you can add the workspace to the <code>npm add</code> command and the dependency will be added to the respective package.json:<br /><code>npm add commander -w packages/cli</code><br />To install dependencies, run <code>npm i</code> from the root directory. This will install all deps of all workspaces in a node_modules folder in the root directory, but none in the projects in the workspaces folder. This already is a win because it will avoid having dependency duplettes.<br />However if you have conflicting versions of the same dependency in your packages, you will have a separate node_modules directory with the only the specific version for this single package.</li>
</ul>



<figure class="wp-block-image size-full"><a href="https://nerdpress.org/wp-content/uploads/2024/04/npm-workspaces-conflicting-versions-directories-1.png"><img decoding="async" width="272" height="354" src="https://nerdpress.org/wp-content/uploads/2024/04/npm-workspaces-conflicting-versions-directories-1.png" alt="" class="wp-image-3306" srcset="https://nerdpress.org/wp-content/uploads/2024/04/npm-workspaces-conflicting-versions-directories-1.png 272w, https://nerdpress.org/wp-content/uploads/2024/04/npm-workspaces-conflicting-versions-directories-1-231x300.png 231w" sizes="(max-width: 272px) 100vw, 272px" /></a></figure>



<p><br /><strong>2. Development</strong></p>



<ul class="wp-block-list">
<li>Updating dependencies can happen just like adding dependencies:<br /><kbd>npm update commander -w packages/cli</kbd></li>



<li>When you need different versions of a dependency in your workspaces, NPM will create a new node_modules folder in the one divergating workspace with only the dependency where you have the different version.</li>



<li>When you need to share code between workspaces you can import code from one package of the workspaces in another package just as a normal dependency from the NPM registry. <br />For example when you want to share types in a typescript project you can add a types workspace and just import in the other workspaces files. <br /><code>import {Name} from "types";</code></li>



<li>It is probably good practice to add shortcut scripts to your main package.json to run commands of your workspaces. So you don&#8217;t need to change to the workspaces directory, which is of course still possible.</li>
</ul>


<pre class="wp-block-code"><span><code class="hljs language-javascript">  <span class="hljs-string">"scripts"</span>: {
    <span class="hljs-string">"hello-cli"</span>: <span class="hljs-string">"npm --workspace=@workspaces-example/cli run hello"</span>,
    <span class="hljs-string">"hello-web"</span>: <span class="hljs-string">"npm --workspace=@workspaces-example/web run hello"</span>
  }
</code></span></pre>


<p><strong>3. Deploy</strong></p>



<ul class="wp-block-list">
<li>Deploying from a Monrepo needs to take the different packages into account, which need to be deployed separately but from the same CI config. <br />For Github Actions i used a path directive which changes to the package directory and runs instructions there. <br /><code>with: <br />  path: packages/astro</code></li>



<li>Other prefabricated actions like f.e. <kbd>actions/deploy-pages</kbd> have a <br /><kbd>working-directory: ./packages/astro</kbd> <br />directive which have the same effect.</li>
</ul>



<p>You can check out the example project here: <a href="https://github.com/ivoba/npm-workspaces-example" target="_blank" rel="noopener" title="">https://github.com/ivoba/npm-workspaces-example</a></p>



<p>One probably does not necessarily need a Monorepo for this example, but it is good to know that Monorepos are quite simple to achieve just with NPM, in case you need to.</p>The post <a href="https://nerdpress.org/2024/04/12/monorepo-with-npm-workspaces/">Monorepo with NPM workspaces</a> first appeared on <a href="https://nerdpress.org">Nerdpress.org</a>.]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Filter a csv file with nodejs streams</title>
		<link>https://nerdpress.org/2022/01/17/filter-a-csv-file-with-nodejs-streams/</link>
		
		<dc:creator><![CDATA[Ivo Bathke]]></dc:creator>
		<pubDate>Mon, 17 Jan 2022 08:50:22 +0000</pubDate>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[csv]]></category>
		<category><![CDATA[nodejs]]></category>
		<category><![CDATA[streams]]></category>
		<guid isPermaLink="false">https://nerdpress.org/?p=3103</guid>

					<description><![CDATA[<p>So we have a CSV file with a member list and we want to filter all empty emails. FirstName,LastName,Email Max,Mustermann,max@mustermann.de Maxi,Hasnoemail, With nodejs streams this is almost a one liner. We will use the csv package from the CSV project which has some sophisticated packages to parse and transform csv data with nodejs streams. We &#8230; </p>
<p class="link-more"><a href="https://nerdpress.org/2022/01/17/filter-a-csv-file-with-nodejs-streams/" class="more-link">Continue reading<span class="screen-reader-text"> "Filter a csv file with nodejs streams"</span></a></p>
The post <a href="https://nerdpress.org/2022/01/17/filter-a-csv-file-with-nodejs-streams/">Filter a csv file with nodejs streams</a> first appeared on <a href="https://nerdpress.org">Nerdpress.org</a>.]]></description>
										<content:encoded><![CDATA[<p>So we have a CSV file with a member list and we want to filter all empty emails.</p>



<pre class="wp-block-preformatted">FirstName,LastName,Email
Max,Mustermann,max@mustermann.de
Maxi,Hasnoemail,</pre>



<p>With nodejs streams this is almost a one liner.</p>



<p>We will use the <a href="https://csv.js.org/">csv</a> package from the CSV project which has some sophisticated packages to parse and transform csv data with nodejs streams.</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; title: ; notranslate">
npm install csv
</pre></div>


<p>We will further use node as ESM (ECMAScript modules) to be shiningly modern and so lets create a file: <code>index.mjs</code> <br /><em>Note the .mjs extension, which will tell node to interprete this as ESM. (Since nodejs v12.20.0 &amp;&amp; v14.13.0)</em></p>



<p>We import the packages and create the filesystem streams to read the file, then built a pipeline with the streams and the single steps to process the data and write the results into a new file.<br />Ok let&#8217;s go:</p>



<span id="more-3103"></span>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: jscript; title: ; notranslate">
import {pipeline} from &#039;stream&#039;;
import {parse, transform, stringify} from &#039;csv&#039;;
import {createReadStream, createWriteStream} from &#039;fs&#039;;

pipeline(
  createReadStream(`./members.csv`),
  parse(),
  transform(data =&gt; data&#x5B;2] !== &#039;&#039; ? data : null),
  stringify({}),
  createWriteStream(`./members_filtered.csv`),
  err =&gt; err ? console.error(&#039;Pipeline failed.&#039;, err) : console.log(&#039;Pipeline succeeded.&#039;)
);

</pre></div>


<p>That is all, folks! Here is the <a href="https://gist.github.com/ivoba/29fc74ecd8ee6c2344c89d75418836e8">gist</a>.</p>



<p>We now have filtered all rows where the email is empty and saved the remaining rows to members_filtered.csv file.</p>



<p>We also could have done this with only pipes but this is considered unsafe (<a href="https://stackoverflow.com/questions/58875655/whats-the-difference-between-pipe-and-pipeline-on-streams/60459320#60459320">https://stackoverflow.com/questions/58875655/whats-the-difference-between-pipe-and-pipeline-on-streams/60459320#60459320</a>) since pipeline is an optimized stream handling with better cleanups and error handling.<br />Nevertheless for the sake of completeness, the pipes version:</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: jscript; title: ; notranslate">
import {parse, transform, stringify} from &#039;csv&#039;;
import {createReadStream, createWriteStream} from &#039;fs&#039;;

createReadStream(`./members.csv`)
  .pipe(parse())
  .pipe(transform(data =&gt; data&#x5B;2] !== &#039;&#039; ? data : null))
  .pipe(stringify({}))
  .pipe(createWriteStream(`./members_filtered.csv`))
  .on(&#039;finish&#039;, data =&gt; console.log(&#039;Done&#039;));
</pre></div>The post <a href="https://nerdpress.org/2022/01/17/filter-a-csv-file-with-nodejs-streams/">Filter a csv file with nodejs streams</a> first appeared on <a href="https://nerdpress.org">Nerdpress.org</a>.]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Synchronous http request in node.js, that you dont want, probably</title>
		<link>https://nerdpress.org/2011/06/28/synchronous-http-request-in-node-js-that-you-dont-want-probably/</link>
		
		<dc:creator><![CDATA[Ivo Bathke]]></dc:creator>
		<pubDate>Tue, 28 Jun 2011 10:08:37 +0000</pubDate>
				<category><![CDATA[node.js]]></category>
		<category><![CDATA[nodejs]]></category>
		<guid isPermaLink="false">https://nerdpress.org/?p=1536</guid>

					<description><![CDATA[<p>Achtung dummy code! &#8230;and so it goes Asynchronous: fire, fire, fire, fire &#8230; and so it dont, Synchronous then: point &#8211; shoot, point &#8211; shoot, point &#8211; shoot well i didnt know that :)</p>
The post <a href="https://nerdpress.org/2011/06/28/synchronous-http-request-in-node-js-that-you-dont-want-probably/">Synchronous http request in node.js, that you dont want, probably</a> first appeared on <a href="https://nerdpress.org">Nerdpress.org</a>.]]></description>
										<content:encoded><![CDATA[<p>Achtung dummy code!</p>
<p>&#8230;and so it goes Asynchronous:</p>
<pre class="brush: jscript; title: ; notranslate">
 for(var i = 0; i &lt; loop.length; i++)
 {
	var proxy = http.createClient(PORT,SERVER);
	var request = proxy.request('GET', url, 
        {
            &quot;host&quot;: SERVER
        });
	request.end();
	...
 }
</pre>
<p>fire, fire, fire, fire</p>
<p>&#8230; and so it dont, Synchronous then:</p>
<pre class="brush: jscript; title: ; notranslate">
var proxy = http.createClient(PORT,SERVER);
 
for(var i = 0; i &lt; loop.length; i++)
 {
	var request = proxy.request('GET', url, 
        {
            &quot;host&quot;: SERVER
        });
	request.end();
	...
 }
</pre>
<p>point &#8211; shoot, point &#8211; shoot, point &#8211; shoot</p>
<p>well i didnt know that :)</p>The post <a href="https://nerdpress.org/2011/06/28/synchronous-http-request-in-node-js-that-you-dont-want-probably/">Synchronous http request in node.js, that you dont want, probably</a> first appeared on <a href="https://nerdpress.org">Nerdpress.org</a>.]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
