<?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: Pijus</title>
    <description>The latest articles on DEV Community by Pijus (@pijusr).</description>
    <link>https://dev.to/pijusr</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%2F560700%2Fe5d37801-9109-446e-91a3-42c102800eba.jpeg</url>
      <title>DEV Community: Pijus</title>
      <link>https://dev.to/pijusr</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/pijusr"/>
    <language>en</language>
    <item>
      <title>Micro Frontends as Web Components</title>
      <dc:creator>Pijus</dc:creator>
      <pubDate>Mon, 24 Jan 2022 15:19:15 +0000</pubDate>
      <link>https://dev.to/pijusr/micro-frontends-as-web-components-363f</link>
      <guid>https://dev.to/pijusr/micro-frontends-as-web-components-363f</guid>
      <description>&lt;p&gt;Quite recently, I had a task to develop a bunch of reusable components for the blockchain space and compress them into a single NPM package.&lt;/p&gt;

&lt;p&gt;The problem was that we had a lot of different teams with their preferred development stack. Now, my mission was to glide through this obstacle in the most efficient way possible, so what do I choose?&lt;/p&gt;

&lt;p&gt;&lt;em&gt;takes off the hat&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Quite right - &lt;a href="https://micro-frontends.org/"&gt;micro frontend&lt;/a&gt; infrastructure. &lt;/p&gt;

&lt;h2&gt;
  
  
  Structure
&lt;/h2&gt;

&lt;p&gt;The idea is to make a &lt;a href="https://en.wikipedia.org/wiki/Monorepo"&gt;monorepository&lt;/a&gt; which would contain applications that will act as reusable components in a form of IFrames (inline frames) deployed to Vercel and packaged through Stencil.js framework. &lt;/p&gt;

&lt;h3&gt;
  
  
  Monorepository
&lt;/h3&gt;

&lt;p&gt;I think it's wise to reuse UI components, styles, and configuration files where necessary. In other words, let's not make cross-functional teams into cross dysfunctional ones.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;apps/
├─ cool-app-a/
├─ cool-app-b/
common/
├─ config/
├─ ui/
├─ tsconfig/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Deployment
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://vercel.com/blog/monorepos"&gt;Vercel&lt;/a&gt; allows deploying applications from monorepository in a breeze. &lt;/p&gt;

&lt;h3&gt;
  
  
  Components
&lt;/h3&gt;

&lt;p&gt;Now that we have deployment links for each application we can package them into NPM package via &lt;a href="https://stenciljs.com/"&gt;Stencil.js&lt;/a&gt; framework through IFrames.&lt;/p&gt;

&lt;p&gt;First of all, initialize the stencil project and remove all the boilerplate code. Then, create &lt;code&gt;deployments.json&lt;/code&gt; file at the top directory with the structure as so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
    "deployments": [
       {
         "name": "ComponentName",
         "tag": "component-tag-name",
         "deployment": "URL" 
       },
       ....
    ]
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will act as our configuration file for our components. &lt;/p&gt;

&lt;p&gt;In the root directory add the &lt;code&gt;utility&lt;/code&gt; folder with &lt;code&gt;populate.js&lt;/code&gt; script and &lt;code&gt;package.json&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;utility/
├─ populate.js
├─ package.json
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the &lt;code&gt;package.json&lt;/code&gt; add &lt;code&gt;{ "type": "module" }&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;As an advocate of automatization, I made a script to handle the creation of stencil components. This is the &lt;code&gt;populate&lt;/code&gt; script:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import * as fs from 'fs';
import configuration from '../deployments.json';

configuration.deployments.forEach(app =&amp;gt; {
  fs.writeFile(`src/components/${app.tag}.tsx`, getTemplate(app), (err) =&amp;gt; {
    if (err) {
      console.log("🔴 ", error);
    } else {
      console.log(`✅  Component "${app.name}" populated.`)
    }
  });
})


function getTemplate(configuration) {

  return `
    import { Component, h } from '@stencil/core';

    @Component({
      tag: "${configuration.tag}",
      styleUrl: 'global.css'
    })
    export class ${configuration.name} {

      render() {
        return (
          &amp;lt;iframe src="${configuration.deployment}"
                  frameBorder="0"&amp;gt;
          &amp;lt;/iframe&amp;gt;
        );
      }
    }
    `
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So what happened here? We are taking deployment variables, adding them to the boilerplate template, and writing everything into the components folder. Simple and neat. &lt;/p&gt;

&lt;p&gt;Now, to make our work easier, in the root level &lt;code&gt;package.json&lt;/code&gt; add a new script to handle the population of components.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"scripts": {
    "populate": "node --experimental-json-modules  utility/populate.js"
    ...
  },
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run &lt;code&gt;npm run populate &amp;amp;&amp;amp; npm run build&lt;/code&gt; and publish your component library to NPM.&lt;/p&gt;

&lt;p&gt;👋&lt;/p&gt;

</description>
      <category>stencil</category>
      <category>npm</category>
      <category>javascript</category>
      <category>tutorial</category>
    </item>
  </channel>
</rss>
