phodal / mooa

Mooa 是一个为 Angular 服务的微前端框架。A independent-deployment micro-frontend Framework for Angular from single-spa.
http://mooa.phodal.com/
Other
850 stars 109 forks source link

mooa implemetation #9

Closed GeoffSeloana closed 5 years ago

GeoffSeloana commented 5 years ago

Hi,

Please assist, trying to use mooa to Orchestrate 3 angular self-contained applications onto one application. Was unable to find clear documentation on the mooa framework. Please assist.

where do i put the following code?

this.mooa = new Mooa({ mode: 'iframe', debug: false, parentElement: 'app-home', urlPrefix: 'app', switchMode: 'coexist' })

from step 4 i'm just lost

  1. Setup apps.json with Mooa CLI ...
phodal commented 5 years ago

Hello,

sorry about the document. The mooa config was setup on the Host app's app.component.ts with constructor, for example

  constructor(private httpClient: HttpClient, private router: Router, myElement: ElementRef) {
    this.http = httpClient;
    this.myElement = myElement;
    this.mooa = new Mooa({
      mode: 'iframe',
      debug: false,
      parentElement: 'app-home',
      urlPrefix: 'app',
      switchMode: 'coexist',
      preload: true,
      includeZone: true
    });
  }

you can also find more information in examples directory.

GeoffSeloana commented 5 years ago

Thank you, happy with that part. Not sure if i am applying it wrong but it does not seem like the framework supports accessing the second app via a link e.g "http://localhost:8080/" where another angular application is deployed, it keeps loading for ever. Do we have to keep the second application files within the same repo? does it allow for independent development and deployment?. It looks like it only allows for relative path to the other applications.

apps.json

  {
    "name": "app1",
    "link": "http://localhost:8080/", <--- would like to have something like this not "/app1/..."
    "sourceType": "link"
  },
  {
    "name": "help",
    "selector": "app-help",
    "baseScriptUrl": "/assets/help",
    "styles": [
      "styles.bundle.css"
    ],
    "prefix": "help",
    "scripts": [
      "inline.bundle.js",
      "polyfills.bundle.js",
      "main.bundle.js"
    ],
    "mode": "iframe"
  }
]
phodal commented 5 years ago

Hello,

For independent development and deployment, the relative path is not a problem. Because when we deploy the apps, we will have a proxy server, such as Nginx. It will help was to route the source base.

for the help app, you can try to use link not baseScriptUrl config.

phodal commented 5 years ago

Hello @GeoffSeloana

I Have run a SimpleHTTPServer for localhost:8080 with Python:

#!/usr/bin/env python3
from http.server import HTTPServer, SimpleHTTPRequestHandler, test
import sys

class CORSRequestHandler (SimpleHTTPRequestHandler):
    def end_headers (self):
        self.send_header('Access-Control-Allow-Origin', '*')
        SimpleHTTPRequestHandler.end_headers(self)

if __name__ == '__main__':
    test(CORSRequestHandler, HTTPServer, port=int(sys.argv[1]) if len(sys.argv) > 1 else 8080)

It can be work. Can you check you local server? I think it will have a CORS issue

GeoffSeloana commented 5 years ago

Hello @phodal

I have set up three self-contained angular applications, each with its own Dockerfile and each of them running in an nginx image container. Using docker-compose i then ran all three application and connected them to a network (so they can see each other). I then created a base-application which also runs on nginx to combine all three applications but the external applications do not seem to load via reverse proxy. Please checkout repo when you have time https://github.com/GeoffSeloana/nginx-micro-frontends

This is how the apps.json file looks like

[
  {
    "name": "app1",
    "link": "/assets/app1",
    "sourceType": "link"
  },
  {
    "name": "help",
    "selector": "app-help",
    "baseScriptUrl": "/assets/help",
    "styles": [
      "styles.bundle.css"
    ],
    "prefix": "help",
    "scripts": [
      "inline.bundle.js",
      "polyfills.bundle.js",
      "main.bundle.js"
    ],
    "mode": "iframe"
  },
  {
    "name": "applicationone",
    "selector": "app-applicationone",
    "baseScriptUrl": "/applicationone",
    "source":"link"
  },
    {
    "name": "applicationtwo",
    "selector": "app-applicatoin-two",
    "link": "/applicationtwo",
    "styles": [
      "styles.bundle.css"
    ],
    "prefix": "help",
    "scripts": [
      "inline.bundle.js",
      "polyfills.bundle.js",
      "main.bundle.js"
    ],
    "mode": "iframe"
  }

]

base-application nginx default.conf file

server {
  listen       80;
  server_name  localhost;

  #charset koi8-r;
  #access_log  /var/log/nginx/host.access.log  main;

  location / {
    root   /usr/share/nginx/html;
    index  index.html index.htm;
  }

  #location /app1 {
  #  proxy_pass http://application-one:8080;
  #}

  location /applicationone {
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_pass http://application-one:8080;
  }

  location /applicationtwo {
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_pass http://application-two:8080;
  }

  #error_page  404              /404.html;

  # redirect server error pages to the static page /50x.html
  #
  error_page   500 502 503 504  /50x.html;
  location = /50x.html {
    root   /usr/share/nginx/html;
  }

  # proxy the PHP scripts to Apache listening on 127.0.0.1:80
  #
  #location ~ \.php$ {
  #    proxy_pass   http://127.0.0.1;
  #}

  # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
  #
  #location ~ \.php$ {
  #    root           html;
  #    fastcgi_pass   127.0.0.1:9000;
  #    fastcgi_index  index.php;
  #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
  #    include        fastcgi_params;
  #}

  # deny access to .htaccess files, if Apache's document root
  # concurs with nginx's one
  #
  #location ~ /\.ht {
  #    deny  all;
  #}
}

applicationone and applicationtwo have a reverse proxy setup but they do not load unfortunately. Both applicationone and applicationtwo have a base-url of "/" <base href="/"> and they expose an internal port 8080.

GeoffSeloana commented 5 years ago

image

GeoffSeloana commented 5 years ago

really battling to get it to work :-(

phodal commented 5 years ago

Hi @GeoffSeloana , as the last comments and the log in Chrome Console, it's a CORS issue. You need to enable CORS in Nginx, for example https://enable-cors.org/server_nginx.html

GeoffSeloana commented 5 years ago

Thank you @phodal really appreciate it.

Do you perhaps know why it does not see root element "app-root" in application when using "link" method in the app.json file. It give the following error.

image

phodal commented 5 years ago

@GeoffSeloana I think you need to change the selector in src/app/app.component.ts. The selector should be unique, every applications should have different selector. If our applications have same selector it will be removed.

GeoffSeloana commented 5 years ago

@phodal I have just tried that but it still gives the same error. Think it might have to do with the base-url of the external app's. How did you build "app1" and "help" app's? did you specify any base-url during build eg ng build --base-href /app1 or ng build --base-href /help.

phodal commented 5 years ago

Hello @GeoffSeloana Here's app1 code https://github.com/phodal/mooa-app-example

It's not specify for base href.

GeoffSeloana commented 5 years ago

Thank you so much @phodal. All is working fine now. You are the best!!!

phodal commented 5 years ago

@GeoffSeloana you're welcome. When you have time, please help us to perfect the README doc.