マイクロフロントエンドのデモ実装

マイクロフロントエンドのデモを実装しました。
方法、問題点などを記載します。

# 構成
## 実際のサイト
![71fbcdc6-77bf-d9e2-d985-e0d3809a80cf.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/483460/743a4542-d44b-f808-2933-162135cb8c68.png)

↑赤枠内はWeb Components 1個目（素のHTMLとJS）
![6c16fdca-ee8f-21d9-3dfb-c9a334a9c6d0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/483460/a109a4a5-41d8-e5d4-4aa0-1e67fd6a3da5.png)


↑黄枠内はWeb Components2個目（React）

赤枠、黄枠以外はASP.NET
## 土台となる部分
- ASP.NET
- Cookieを使ったログイン認証がある
- ログインしていないと開けないページ( /Contact )がある

## Web Components 1個目
- 素のHTMLとJS
- ログインしていないと開けないページの内部に配置している
- hogeのボタンを押すと、このWeb Components側のサーバーにCookieの情報が送られる（URLをRewirteしているため、後述）

## Web Components側 2個目
- React
- ログインしていないと開けないページの内部に配置している
- PropsとしてASP.NETとのデータの受け渡し可能（What is your name?、Say Hello、Consoleの部分）

# 方法

## 素のHTMLとJSのWeb Components

元となるHTML

```template.html
<!DOCTYPE html>
<html lang="ja">
    <head>
        <meta charset="UTF-8">
        <title>HTMLの書き方</title>
    </head>
    <body>
        <h1>HTMLの書き方</h1>
        <p>はじめてのHTMLを作りました</p>
        <img src="/subHtml/images/ryoukai-w.png"/>
        <button id = "hoge" type="button" onclick="onClickHoge()">hoge</button>
        
    </body>
</html>
```

innerHTMLでtemplate.htmlの中身を取得

```disclosure.js

import style from './style.scss';
import html from './template.html';

const axios = require("axios")
const template = document.createElement('template');
//innerHTMLでtemplate.htmlの中身を取得
template.innerHTML = `<style>${style}</style>${html}`;
export class Disclosure extends HTMLElement {
    constructor() {
        super();

        this.attachShadow({mode: 'open'});
        this.shadowRoot.appendChild(template.content.cloneNode(true));

        this.hogebutton = this.shadowRoot.getElementById("hoge")
    }

    connectedCallback() {
        this.hogebutton.addEventListener("click",this.onClickHoge.bind(this))
    }

    onClickHoge(event){
        const cookie = document.cookie.split(";")[1];
        console.log(cookie)
        event.preventDefault();
        console.log('hoge');
        axios.post('/subHtml/hoge',{
            hoge:"hoge",
            cookie
        })
        .then(()=>{
            console.log("completed")
        })

    }
}
```

customElementsでWeb Components化

```index.js
import {Disclosure} from './disclosure/disclosure';
customElements.define('c-disclosure', Disclosure);
```

これらを[webpack](https://www.npmjs.com/package/webpack)で１つの静的なJSファイル(components.js)にする。

expressを使ってAzureに静的JSファイルとしてアップロードして完了
![02e01c3a-1f5f-4ec5-67a1-3433d8b28664.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/483460/eae11936-5b9b-da72-49a2-f14489bf66a1.png)


↑server.jsでexpressを用いてpublicフォルダの中身を静的ファイルとしてあげている


## React のWeb Components
以前の[マイクロフロントエンドでWeb Componentsを使う方法について](https://qiita.com/kei37/items/a9e482e2f37d269cb228)でのReactのWeb Componentsと方法は全く同じ
上と同じくexpressを使ってAzureに静的JSファイルとしてアップロードして完了


## 土台のASP.NET

```Contact.cshtml
<body>

    //HTMLのWeb Componentsを呼び出す
    <c-disclosure> </c-disclosure>

</body>

    <script src="https://cdnjs.cloudflare.com/ajax/libs/zone.js/0.9.1/zone.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/webcomponentsjs/2.2.10/custom-elements-es5-adapter.js"></script>

    //ReactのWeb Componentsを読み込む
    <script src="/main.js"></script>

    //HTMLのWeb Componentsを読み込む
    <script src="subHtml/dist/components.js"></script>
```
```web.config
<?xml version="1.0" encoding="utf-8"?>
<configuration>
  <location path="." inheritInChildApplications="false">
    <system.webServer>
      <handlers>
        <add name="aspNetCore" path="*" verb="*" modules="AspNetCoreModule" resourceType="Unspecified" />
      </handlers>
      <aspNetCore processPath="dotnet" arguments=".\AuthWithCookie.dll" stdoutLogEnabled="false" stdoutLogFile="\\?\%home%\LogFiles\stdout" />
        <rewrite>
      <rules>
        <rule name="Proxy" stopProcessing="true">
          <match url="main.js" />
          <action type="Rewrite" url="https://microfrontendsub.azurewebsites.net/main.js"/>
        </rule>
         <rule name="Proxy2" stopProcessing="true">
          <match url="subHtml/(.*)" />
          <action type="Rewrite" url="https://microfrontendsubhtml.azurewebsites.net/{R:1}"/>
        </rule>
      </rules>
    </rewrite>
    </system.webServer>
  </location>
</configuration>
<!--ProjectGuid: 191a4ece-3076-4b7b-b37a-43f3badbcd44-->
```

Rewriteすることで同ドメインとしてWeb Componentsを取得することができ、Web Components側でCookieが取得できる

# 課題点

## `<script>`タグの内容
innerHtmlでは`<script>`の中身が活性化されない
HTML内の`<script>`の中身はJSファイル内(disclosure.js)、もしくは他のJSファイルに記述しなければならない
Web Components側も独立して動くようにさせたいため、これが少し面倒

## Rewrite
上記のweb.config内では、Rewriteする際に、どのWeb Componentsであるのかを区別するために、subHtmlを頭につけている。
素のHTMLのWeb Componentsのtemplate.htmlでは
       ` <img src="/subHtml/images/ryoukai-w.png"/>`
としている
これもWeb Components側も独立して動くようにさせる際に少し面倒

## Local環境でのRewrite

Local環境でRewriteができない

[Microsoft.AspNetCore.Rewrite](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/url-rewriting?view=aspnetcore-5.0)を使って、試してみたがRewriteしてくれない

Azure上と同じく、web.configにも書いてみたがRewriteしてくれない

とりあえず、Web Componentsを参照する際はフルパスで書く