<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Fabian Andres Cano</title>
    <description>The latest articles on Forem by Fabian Andres Cano (@fabian0007).</description>
    <link>https://forem.com/fabian0007</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%2F384021%2F1e42b156-42b7-4223-b3d9-f223153ee58e.jpeg</url>
      <title>Forem: Fabian Andres Cano</title>
      <link>https://forem.com/fabian0007</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/fabian0007"/>
    <language>en</language>
    <item>
      <title>Working with Nx.dev using React, Angular and native web components (Part 2 of 9)</title>
      <dc:creator>Fabian Andres Cano</dc:creator>
      <pubDate>Mon, 11 May 2020 15:35:22 +0000</pubDate>
      <link>https://forem.com/fabian0007/working-with-nx-dev-using-react-angular-and-native-web-components-part-2-of-9-2hbc</link>
      <guid>https://forem.com/fabian0007/working-with-nx-dev-using-react-angular-and-native-web-components-part-2-of-9-2hbc</guid>
      <description>&lt;p&gt;A complementary tutorial on how to work with Nx.dev using web components and not die trying.&lt;/p&gt;

&lt;p&gt;Code available in &lt;a href="https://github.com/Fabian0007/tutorial-nx"&gt;GitHub&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Find me on Twitter as &lt;a href="https://twitter.com/Fabian0007"&gt;@Fabian0007&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Angular App and web components libraries created with React— Part #2 of 9
&lt;/h3&gt;

&lt;p&gt;In this second part of the tutorial, we will work with the Angular application&lt;br&gt;
created in the first part and this time we will create a web component library&lt;br&gt;
using React. The first part of this tutorial is &lt;a href="https://medium.com/@fabianandrescano/working-with-nx-dev-9761da40566a"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--W-N1g8PI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/800/1%2ASCLWMEa91wQ-Td7NFF-lbA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--W-N1g8PI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/800/1%2ASCLWMEa91wQ-Td7NFF-lbA.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Creating a web component library using React
&lt;/h3&gt;

&lt;p&gt;We will start by adding the React capabilities, then we will create the first&lt;br&gt;
web component library using React in our project:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm i @nrwl/react

npm run nx g @nrwl/react:lib header-lib
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;h3&gt;
  
  
  Adding to the Angular app
&lt;/h3&gt;

&lt;p&gt;The first thing that comes to mind is to add the import in&lt;br&gt;
/apps/angularapp/src/main.ts:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import '@tutorial/header-lib';
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now we will run:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm start angular app --watch
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;An error will appear on our console:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ERROR in libs/header-lib/src/index.ts:1:15 — error TS6142: Module ‘./lib/header-lib’ was resolved to ‘C:/Users/FCano/Documents/personal-tutorials/test-continuing/tutorial/libs/header-lib/src/lib/header-lib.tsx’, but ‘ — jsx’ is not set.

1 export * from ‘./lib/header-lib’;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;We need to enable the jsx option. TypeScript ships with three JSX modes:&lt;br&gt;
&lt;code&gt;preserve&lt;/code&gt;, &lt;code&gt;react&lt;/code&gt;, and &lt;code&gt;react-native&lt;/code&gt;. These modes only affect the emit stage - type checking is unaffected. The &lt;code&gt;preserve&lt;/code&gt; mode will keep the JSX as part of the output to be further consumed by another transform step (e.g.&lt;br&gt;
&lt;a href="https://babeljs.io/"&gt;Babel&lt;/a&gt;). Additionally the output will have a &lt;code&gt;.jsx&lt;/code&gt; file&lt;br&gt;
extension. The &lt;code&gt;react&lt;/code&gt; mode will emit &lt;code&gt;React.createElement&lt;/code&gt;, does not need to go through a JSX transformation before use, and the output will have a &lt;code&gt;.js&lt;/code&gt; file extension. The &lt;code&gt;react-native&lt;/code&gt; mode is the equivalent of &lt;code&gt;preserve&lt;/code&gt; in that it keeps all JSX, but the output will instead have a &lt;code&gt;.js&lt;/code&gt; file extension[1]. For our case we will use the &lt;code&gt;react&lt;/code&gt;option. you must add the code marked in bold to /apps/angularapp/src/tsconfig.json:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{

    "extends": "../../tsconfig.json",

    "compilerOptions": {

        "types": ["node", "jest"],



    }

}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;An new error will appear on our console:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ERROR in libs/header-lib/src/lib/header-lib.tsx:1:19 — error TS2307: Cannot find module ‘react’.

1 import React from ‘react’;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This is very simple, without having React installed, how are we going to work&lt;br&gt;
with a React application? An alternative to not having to install it would be to&lt;br&gt;
compile our library from the outside and add it as a resource, but that would&lt;br&gt;
complicate updating this library and that is not the idea of ​​a monorepo. We&lt;br&gt;
will install React and react-dom(Since we are working with a web application, we need to install the glue between react and the DOM) by executing the following command:&lt;/p&gt;

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

&lt;p&gt;And of course we need to install the types for these packages since we are using Typecript.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install — save-dev @types/react @types/react-dom
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The error will disapper and we will replace the file&lt;br&gt;
/apps/angularapp/src/app/app.component.html with:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;header-lib&amp;gt;&amp;lt;/header-lib&amp;gt;

&amp;lt;main&amp;gt;&amp;lt;/main&amp;gt;

&amp;lt;template id="template-test" [innerHTML]="template"&amp;gt; &amp;lt;/template&amp;gt;

&amp;lt;footer-lib [attr.creator]="creator"&amp;gt;&amp;lt;/footer-lib&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--hMGfHS8k--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/800/1%2Aojy9CESPgcVQUCY0nFgB-Q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--hMGfHS8k--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/800/1%2Aojy9CESPgcVQUCY0nFgB-Q.png" alt=""&gt;&lt;/a&gt;&lt;br&gt;
&lt;span class="figcaption_hack"&gt;Expected result&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;Our header library will not be shown, and it is obvious, we are calling a web&lt;br&gt;
component that does not exist, what we have for now is a React library, to make it a web component we have two options each with its own advantages and disadvantages.&lt;/p&gt;

&lt;h3&gt;
  
  
  Do it yourself
&lt;/h3&gt;

&lt;p&gt;React and &lt;a href="https://developer.mozilla.org/en-US/docs/Web/Web_Components"&gt;Web&lt;br&gt;
Components&lt;/a&gt; are built to solve different problems. Web Components provide strong encapsulation for reusable components, while React provides a declarative library that keeps the DOM in sync with your data. The two goals are complementary. As a developer, you are free to use React in your Web Components, or to use Web Components in React, or both[2]. Our need at the moment is to encapsulate the react library that we already have in a web component.&lt;/p&gt;

&lt;p&gt;First we will change the name of /libs/footer-lib /src/lib/header-lib.tsx to&lt;br&gt;
ReactHeader.tsx and we will replace the content with:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import * as React from ‘react’;

import ‘./header-lib.css’;

/* eslint-disable-next-line */

export interface ReactHeaderProps {}

  export const ReactHeader = (props: ReactHeaderProps) =&amp;gt; {

    return (

      &amp;lt;div&amp;gt;

        &amp;lt;h1&amp;gt;Welcome to header-lib component!&amp;lt;/h1&amp;gt;

      &amp;lt;/div&amp;gt;

    );

};

export default ReactHeader;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now we will create on the same folder the file header-lib.tsx and will replace&lt;br&gt;
with:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import * as React from 'react';

import * as ReactDOM from 'react-dom';

import { ReactHeader } from './ReactHeader';

export class HeaderLib extends HTMLElement {

  public mountPoint: HTMLDivElement;

  connectedCallback() {

    this.mountReactApp();

  }

  disconnectedCallback() {

    ReactDOM.unmountComponentAtNode(this.mountPoint);

  }

  mountReactApp() {

    if (!this.mountPoint) {

      this.mountPoint = document.createElement('div');

      this.appendChild(this.mountPoint);

    }

    ReactDOM.render(&amp;lt;ReactHeader /&amp;gt;, this.mountPoint);

  }

}

customElements.define('header-lib', HeaderLib);
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Here we are using the life cycle of the web components (connectedCallback and disconnectedCallback) and ReactDOM for render a React component over a web component.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--sDZYMxSM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/800/1%2Ak_BRmj1f5bdC91r6XjDDRw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--sDZYMxSM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/800/1%2Ak_BRmj1f5bdC91r6XjDDRw.png" alt=""&gt;&lt;/a&gt;&lt;br&gt;
&lt;span class="figcaption_hack"&gt;Expected result&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;Our component not is using the ShadowDOM(see the first part of this tutorial), so the h1 label is centered. To use it we must add the constructor and we will attach a shadow DOM tree to the web component “this.attachShadow({ mode: ‘open’})”, it must be open because we need to access to shadowRoot property of the web component, then we must to append the div element to the shadowRoot property instead of over the web component.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;constructor() {

  super();

  this.attachShadow({ mode: 'open' })

}

this.appendChild(this.mountPoint); -&amp;gt; this.shadowRoot.appendChild(this.mountPoint);
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--HYJcHMck--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/800/1%2AZwR85WJxjlsciEVEo5Tzzw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--HYJcHMck--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/800/1%2AZwR85WJxjlsciEVEo5Tzzw.png" alt=""&gt;&lt;/a&gt;&lt;br&gt;
&lt;span class="figcaption_hack"&gt;Expected result&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;Now if we want to add the style, we need to add it as a inline style, because&lt;br&gt;
the shadowDOM doesnt we permit to use the external css, we can to use&lt;br&gt;
&lt;a href="https://www.npmjs.com/package/style-it"&gt;style-it&lt;/a&gt; for insert the css directly&lt;br&gt;
in the DOM, but we need to be able to export the css as a module, so I invite&lt;br&gt;
you to review this on your own.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import * as React from 'react';

import './header-lib.css';

/* eslint-disable-next-line */

export interface ReactHeaderProps {}

export const ReactHeader = (props: ReactHeaderProps) =&amp;gt; {

  return (









    &amp;lt;/div&amp;gt;

  );

};

export default ReactHeader;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now if we want to pass a parameter, the first is update the React component:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import * as React from 'react';

import './header-lib.css';

/* eslint-disable-next-line */

export interface ReactHeaderProps {

  creator: string

}

export const ReactHeader = ({ creator }: ReactHeaderProps) =&amp;gt; {

  return (

    &amp;lt;div style={display: 'flex', alignItems: 'center', justifyContent: 'center'}&amp;gt;

      &amp;lt;img

        alt="Nx logo"

        width="75"

        src="https://nx.dev/assets/images/nx-logo-white.svg"

      /&amp;gt;

      &amp;lt;h1&amp;gt;Header {creator}&amp;lt;/h1&amp;gt;

    &amp;lt;/div&amp;gt;

  );

};

export default ReactHeader;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;In header-lib.tsx we must add the attributeChangedCallback lifecycle to get the attribute “creator” and pass it to the mountReactApp function where we will pass that value to the React component.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import * as React from 'react';

import * as ReactDOM from 'react-dom';

import { ReactHeader } from './ReactHeader';

export class HeaderLib extends HTMLElement {

  public mountPoint: HTMLDivElement;

  public static observedAttributes = ['creator'];

  constructor() {

    super();

    this.attachShadow({ mode: 'open' })

  }

  connectedCallback() {

    this.mountReactApp('');

  }

  attributeChangedCallback() {

    const creator: string = this.getAttribute('creator');

   this.mountReactApp(creator);

  }

  disconnectedCallback() {

    ReactDOM.unmountComponentAtNode(this.mountPoint);

  }

  mountReactApp(creator: string) {

    if (!this.mountPoint) {

      this.mountPoint = document.createElement('div');

      this.shadowRoot.appendChild(this.mountPoint);

    }

   ReactDOM.render(&amp;lt;ReactHeader creator={creator}/&amp;gt;,   this.mountPoint);

  }
}

customElements.define('header-lib', HeaderLib);
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Finally we will need to update the app.component.html in angularApp:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;header-lib [attr.creator]="creator"&amp;gt;&amp;lt;/header-lib&amp;gt;

&amp;lt;main&amp;gt;&amp;lt;/main&amp;gt;

&amp;lt;template id="template-test" [innerHTML]="template"&amp;gt; &amp;lt;/template&amp;gt;

&amp;lt;footer-lib [attr.creator]="creator"&amp;gt;&amp;lt;/footer-lib&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4mlAYOTc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/800/1%2ATG-ctvg5kWSSrWvpI6AJjg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4mlAYOTc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/800/1%2ATG-ctvg5kWSSrWvpI6AJjg.png" alt=""&gt;&lt;/a&gt;&lt;br&gt;
&lt;span class="figcaption_hack"&gt;Expect result&lt;/span&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  The fast way
&lt;/h3&gt;

&lt;p&gt;We will create a new library for test this way:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm run nx g @nrwl/react:lib header-fast-lib
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;We will install these dependencies:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm i prop-types
npm i react-to-webcomponent
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;We will create ReactHeader en lib of header-fast-lib:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import * as React from 'react';

import * as PropTypes from 'prop-types';

/* eslint-disable-next-line */

export interface ReactHeaderProps {

  creator: string

}

export const ReactHeader = ({ creator }: ReactHeaderProps) =&amp;gt; {

  return (

    &amp;lt;div style={display: 'flex', alignItems: 'center', justifyContent: 'center'}&amp;gt;

      &amp;lt;img

        alt="Nx logo"

        width="75"

        src="https://nx.dev/assets/images/nx-logo-white.svg"

      /&amp;gt;
      &amp;lt;h1&amp;gt;Header {creator}&amp;lt;/h1&amp;gt;

    &amp;lt;/div&amp;gt;

  );

};

ReactHeader.propTypes = { creator: PropTypes.string };

export default ReactHeader;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;The only change here regarding header-lib is “ReactHeader.propTypes = { creator: PropTypes.string };” because react-to-webcomponent need it. Now inside header-fast-lib.tsx we will write:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import * as ReactDOM from 'react-dom';

import * as React from 'react';

import reactToWebComponent from 'react-to-webcomponent';

import { ReactHeader } from './ReactHeader';

export const webcomponent = reactToWebComponent(ReactHeader, React, ReactDOM);

customElements.define('header-fast-lib', webcomponent);
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Inside main.ts of angularApp we will include the library and in&lt;br&gt;
app.component.html we will use  instead of :&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import '@tutorial/header-fast-lib';

&amp;lt;header-fast-lib [attr.creator]="creator"&amp;gt;&amp;lt;/header-fast-lib&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--4mlAYOTc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/800/1%2ATG-ctvg5kWSSrWvpI6AJjg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--4mlAYOTc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/800/1%2ATG-ctvg5kWSSrWvpI6AJjg.png" alt=""&gt;&lt;/a&gt;&lt;br&gt;
&lt;span class="figcaption_hack"&gt;Expected result&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;As we have seen working web components with React is not complicated, and most of the things we knew from the previous tutorial where we work with native web components are applied, in the next part of this tutorial we will work with web components built with Angular, see you soon.&lt;/p&gt;

&lt;h3&gt;
  
  
  Referencias
&lt;/h3&gt;

&lt;p&gt;[1]&lt;br&gt;
&lt;a href="https://www.typescriptlang.org/docs/handbook/jsx.html"&gt;https://www.typescriptlang.org/docs/handbook/jsx.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;[2]&lt;br&gt;
&lt;a href="https://en.reactjs.org/docs/web-components.html"&gt;https://en.reactjs.org/docs/web-components.html&lt;/a&gt;&lt;/p&gt;

</description>
      <category>angular</category>
      <category>react</category>
      <category>typescript</category>
      <category>javascript</category>
    </item>
    <item>
      <title>Working with Nx.dev using React, Angular and native web components (Part 1 of 9)</title>
      <dc:creator>Fabian Andres Cano</dc:creator>
      <pubDate>Mon, 11 May 2020 15:30:09 +0000</pubDate>
      <link>https://forem.com/fabian0007/working-with-nx-dev-using-react-angular-and-native-web-components-part-1-of-9-4l3b</link>
      <guid>https://forem.com/fabian0007/working-with-nx-dev-using-react-angular-and-native-web-components-part-1-of-9-4l3b</guid>
      <description>&lt;p&gt;Code available in &lt;a href="https://github.com/Fabian0007/tutorial-nx"&gt;GitHub&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Find me on Twitter as &lt;a href="https://twitter.com/Fabian0007"&gt;@Fabian0007&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Angular App and web components libraries— Part #1 of 9
&lt;/h3&gt;

&lt;p&gt;In this first part of the tutorial, we will start with an Angular application&lt;br&gt;
that uses web component libraries, we will delve a little into what web&lt;br&gt;
components are and the peculiarities of Angular when working with them.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--a13vHdf_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/800/1%2A-WV0ZrNwQVsT0YrEXdlp6A.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--a13vHdf_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/800/1%2A-WV0ZrNwQVsT0YrEXdlp6A.png" alt=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let’s start creating the Nx project:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx create-nx-workspace tutorial
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Then select empty [an empty workspace]&lt;/p&gt;

&lt;p&gt;Now surely, are you wondering what is Nx? (better to look for it as Nx.dev).&lt;br&gt;
This set of extensible development tools for monorepos could help you develop like Google, Facebook and Microsoft[1]. For more information about Nx you can consult their website. What to say about the monorepos strategy, is a subject of much discussion, I recommend that you consult information about its advantages and disadvantages.&lt;/p&gt;

&lt;h3&gt;
  
  
  &lt;strong&gt;Creating Angular App&lt;/strong&gt;
&lt;/h3&gt;

&lt;p&gt;We will start by adding the Angular capabilities, then we will create the first&lt;br&gt;
application in our project, which will use Angular:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm i @nrwl/angular

npm run nx g @nrwl/angular:app angularapp
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Which style sheet format(to use) and if you want to configure routing for the&lt;br&gt;
application is your choice.&lt;/p&gt;

&lt;h3&gt;
  
  
  Creating a web component library
&lt;/h3&gt;

&lt;p&gt;Now, we will add the Web component capabilities and create a footer library&lt;br&gt;
based on web components:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm i @nrwl/web
npm run nx g @nrwl/web:lib footer-lib
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Go to /libs/footer-lib /src/lib/footer-lib.ts and we must to add:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export class Footer extends HTMLElement {

  connectedCallback() {
    this.innerHTML = `&amp;lt;h1&amp;gt;Made by Fabian Cano&amp;lt;/h1&amp;gt;`;
  }
}
customElements.define('footer-lib', Footer);
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Three importants things here:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;HTMLElement&lt;/strong&gt;: this is the prototype of a generic element HTML.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;connectedCallback&lt;/strong&gt;: A lifecycle hook called after the component’s element is&lt;br&gt;
inserted into the document.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;customElements.define&lt;/strong&gt;: is a method that defines a new custom element.&lt;/p&gt;

&lt;p&gt;At this point it is important to talk about what web components are. They are&lt;br&gt;
not a technology per se, they are based on the combined use of four technologies that can be used independently:&lt;/p&gt;

&lt;p&gt;The first is &lt;strong&gt;Custom Elements, **which allows defining new types of elements and is used when we call&lt;/strong&gt; customElements.define(‘footer-lib’, Footer)**.&lt;/p&gt;

&lt;p&gt;The second was &lt;strong&gt;HTML Imports&lt;/strong&gt;, which is intended to be the packaging mechanism for web components, but you can also use HTML Imports by itself. This feature is obsolete. Although it may still work in some browsers, its use is discouraged since it could be removed at any time. Try to avoid using it.&lt;/p&gt;

&lt;p&gt;The previous technology was replaced with the &lt;strong&gt;ES Modules specification&lt;/strong&gt;, which defines the inclusion and reuse of JS documents in a standards based, modular, performant way. This is how we will import our web component.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;We will see the other two technologies later.&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Adding the web component library to the Angular app
&lt;/h3&gt;

&lt;p&gt;Go to /apps/angularapp/src/main.ts and we will add (&lt;strong&gt;here we use ES modules&lt;/strong&gt;):&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import '@tutorial/footer-lib';
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Then in /apps/angularapp/src/app/app.module.ts we will add the code in bold, in order to enable the use of web components in the project.&lt;/p&gt;

&lt;div class="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';

@NgModule({

  declarations: [AppComponent],

  imports: [BrowserModule],

  providers: [],


  bootstrap: [AppComponent]

})
export class AppModule {}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;We will add the next to the end of the file&lt;br&gt;
/apps/angularapp/src/app/app.component.html, in order to call the web component.&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;footer-lib&amp;gt;&amp;lt;/footer-lib&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Then, you can run the app:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm start angularapp
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;If you get the error “Cannot find module&lt;br&gt;
‘&lt;a href="http://twitter.com/angular"&gt;@angular&lt;/a&gt;-devkit/build-angular/package.json’…”, run the command below to reinstall dependencies:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm i
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--8YZAyd9Z--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/800/1%2AosCUaQBzoJjXN5JaDo69GA.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8YZAyd9Z--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/800/1%2AosCUaQBzoJjXN5JaDo69GA.png" alt=""&gt;&lt;/a&gt;&lt;br&gt;
&lt;span class="figcaption_hack"&gt;Expected result&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;You can see that the style defined in app.component.css does not affect the&lt;br&gt;
footer-lib style&lt;/strong&gt;. This occurs because Angular by default uses encapsulation&lt;br&gt;
for components. For deactivate this, you must add the code marked in bold to app.component.ts:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Component, 
 } from '@angular/core';

@Component({

  selector: 'tutorial-root',

  templateUrl: './app.component.html',

  styleUrls: ['./app.component.css'],



})

export class AppComponent {

  title = 'angularapp';

}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now footer-lib will be centered because it uses h1 label.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--hMGfHS8k--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/800/1%2Aojy9CESPgcVQUCY0nFgB-Q.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--hMGfHS8k--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/800/1%2Aojy9CESPgcVQUCY0nFgB-Q.png" alt=""&gt;&lt;/a&gt;&lt;br&gt;
&lt;span class="figcaption_hack"&gt;Expected result&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What if you want to pass a parameter to the web component?&lt;/strong&gt; you can use&lt;br&gt;
observedAttributes and attributeChangedCallback provided by HTMLElement, replace&lt;br&gt;
the file in /libs/footer-lib /src/lib/footer-lib.ts with:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export class Footer extends HTMLElement {

  public static observedAttributes = ['creator'];

  attributeChangedCallback() {

    const creator = this.getAttribute('creator');

    this.innerHTML = `&amp;lt;h1&amp;gt;Made by ${creator}&amp;lt;/h1&amp;gt;`;

  }

}

customElements.define('footer-lib', Footer);
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Now we should pass the parameter to footer-lib and create the variable in&lt;br&gt;
app.component.ts:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;footer-lib [attr.creator]="creator"&amp;gt;&amp;lt;/footer-lib&amp;gt;

...
title = 'angularapp';

...
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;What if you want encapsulate the footer-lib style but without relying on&lt;br&gt;
Angular encapsulation?&lt;/strong&gt; For this you can use the Shadow DOM.&lt;/p&gt;

&lt;h3&gt;
  
  
  Using the Shadow DOM
&lt;/h3&gt;

&lt;p&gt;Shadow DOM is the third technology on which web components are based and is a new DOM feature that helps you build components. You can think of shadow DOM as a &lt;strong&gt;scoped subtree&lt;/strong&gt; inside your element. it was created to allow encapsulation and componentisation natively on the web platform without having to rely on tools like &lt;code&gt;&amp;lt;iframe&amp;gt;&lt;/code&gt;, which really weren’t made for this purpose.&lt;/p&gt;

&lt;p&gt;Go to /libs/footer-lib /src/lib/footer-lib.ts and we must replace it with:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export class Footer extends HTMLElement {

public static observedAttributes = ['creator'];

  constructor() {

    super();

    this.attachShadow({ mode: 'open' });

  }

  attributeChangedCallback() {

    const creator = this.getAttribute('creator');

    const template = document.createElement('template');

    template.innerHTML = `&amp;lt;h1&amp;gt;Made by ${creator}&amp;lt;/h1&amp;gt;`;

    this.shadowRoot.appendChild(template.content);

  }

}

customElements.define('footer-lib', Footer);
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;Now again, you can see that the style defined in app.component.css does not&lt;br&gt;
affect the footer-lib style because it uses shadow DOM&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--S_zkohiT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/800/1%2Ak_amzYtgdXrpdJU0A0T8fw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--S_zkohiT--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/800/1%2Ak_amzYtgdXrpdJU0A0T8fw.png" alt=""&gt;&lt;/a&gt;&lt;br&gt;
&lt;span class="figcaption_hack"&gt;Expected&lt;/span&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Using HTML templates
&lt;/h3&gt;

&lt;p&gt;HTML templates are the fourth technology on which web components are based and they allow you to create pieces of HTML that can be replicated as many times as necessary.&lt;/p&gt;

&lt;p&gt;Go to /libs/footer-lib /src/lib/footer-lib.ts and we must replace it with:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export class FooterLib extends HTMLElement {

  public static observedAttributes = ['creator'];

  constructor() {

    super();

    this.attachShadow({ mode: 'open' });

  }

  attributeChangedCallback() {

    const template = document.getElementById('template-test');

    template.innerHTML =

      `&amp;lt;style&amp;gt;h1 {text-align: center; }&amp;lt;/style&amp;gt;` + template.innerHTML;

    const templateContent = template['content'];

    this.shadowRoot.appendChild(templateContent);

  }

}

customElements.define('footer-lib', FooterLib);
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Here we get the template searching with the id ‘template-test’, then we add the style for center the h1 label in the innerHTML of the template. Finally we add the template[‘content’] as a child of the shaddowRoot.&lt;/p&gt;

&lt;p&gt;Now we need to add the template to /apps/angularapp/src/app/app.component.html:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;template id="template-test" [innerHTML]="template"&amp;gt; &amp;lt;/template&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Then go to /apps/angularapp/src/app/app.component.ts and you must add the code marked in bold:&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Component, ViewEncapsulation } from '@angular/core';

@Component({

selector: 'tutorial-root',

templateUrl: './app.component.html',

styleUrls: ['./app.component.css'],

encapsulation: ViewEncapsulation.None

})

export class AppComponent {

title = 'angularapp';

creator = 'Fabian Cano';


}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--rH0LPXkD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/800/1%2A7cFSklTrXoUPLPjTJ71Abw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--rH0LPXkD--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://cdn-images-1.medium.com/max/800/1%2A7cFSklTrXoUPLPjTJ71Abw.png" alt=""&gt;&lt;/a&gt;&lt;br&gt;
&lt;span class="figcaption_hack"&gt;Expected result&lt;/span&gt;&lt;/p&gt;

&lt;p&gt;In the next part we will see the inclusion of a React library to the Angular&lt;br&gt;
application. See you soon.&lt;/p&gt;

&lt;p&gt;Second part available &lt;a href="https://medium.com/@fabianandrescano/working-with-nx-dev-using-react-angular-and-native-web-components-part-2-of-9-4883c314d217"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  References
&lt;/h3&gt;

&lt;p&gt;[1] Nx web page &lt;a href="https://nx.dev/"&gt;https://nx.dev/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>angular</category>
      <category>react</category>
      <category>webcomponents</category>
      <category>javascript</category>
    </item>
  </channel>
</rss>
