Skip to content

Latest commit

 

History

History
138 lines (121 loc) · 6.96 KB

develop_at_production.md

File metadata and controls

138 lines (121 loc) · 6.96 KB

Develop right at "production"

ILC gives you ability to develop your Micro Frontends in context of the "production" environment. This means that you can render your new app or changed version of the existing one right at the production website.

This gives you ability to see the final result sooner w/o necessity to mock other Micro Frontends inside your local development environment.

Practical example, how to develop your app within our demo site

Let's imagine that our demo site is your production environment. And let's try to substitute News app with the one that you'll run locally.

  1. Run our demo apps locally. To do so, follow the instruction here ilc-demo-apps#development-process.
  2. If you're behind NAT and don't have "white" IP address on your machine - use ngrok or any another similar tool to create public url for exposing your local apps.
    • Download & install ngrok using instruction from their website.
    • As News app uses 8239 port – run ngrok http 8239 and you will receive your exposed url, e.g. http://c6960219.ngrok.io.
  3. Open demo site and add next cookies:
    const exposedUrl = 'http://c6960219.ngrok.io'; // or if you don't have NAT - http://YOUR_PUBLIC_IP:8239
    const overrideConfig = encodeURIComponent(JSON.stringify({
        apps: {
            '@portal/news': {
                spaBundle: exposedUrl + '/dist/single_spa.js',
                cssBundle: exposedUrl + '/dist/common.css',
                ssr: {
                    src: exposedUrl + '/news/?fragment=1',
                },
                props: {
                    publicPath: exposedUrl + '/dist/',
                },
            },
        },
    }));
    
    document.cookie = `ILC-overrideConfig=${overrideConfig}; path=/;`
  4. Try to refresh http://demo.microfrontends.online/news/ several times & using "Network" tabs in browser dev tools ensure that some requests now go to the URL we specified before in exposedUrl variable.
  5. Now let's try to make some changes in our local News app and see them appeared at our Demo website.
    • Go to cloned ilc-demo-apps repo, open the file /ilc-demo-apps/apps/news-ssr/src/components/Home.vue and replace <h1>Pick a news source</h1> with <h1>Hello world</h1>.
    • Now switch to your browser and refresh page http://demo.microfrontends.online/news/.
    • If everything is ok, you will see h1 with text "Hello world".
  6. Last step is to check that SSR works correctly:
    • Turn off javascript with the help of dev-tools in your browser. e.g. explanation how to do it for Chrome
    • And after reload of the page we still see correct page with h1 - Hello world

Security considerations

The fact that you can override ILC config for particular browser using cookies introduces a risk of having website defacement attack with the help of XSS. To mitigate this risk ILC by default will restrict all domains and all real IPs (only private IPv4 addresses are allowed) specified for all links in configuration.

However you can allow additional origins via property "overrideConfigTrustedOrigins", on "Settings" page of ILC Registry.

  • default - any origin is disallowed, except for private IPv4 addresses
  • all - trust any origins
  • foo.com, bar.com - trust only foo.com and bar.com (recommended)

Creating own MS

  • first of all, you should take adapter for your framework, wrap your app with it and export lifecycle functions.
  • turn off CORS for development environment. e.g. for Webpack just add to config:
    devServer: {
        headers: {
            "Access-Control-Allow-Origin": "*",
        },
    }
"(function(define){\n" + bundle_content + "\n})((window.ILC && window.ILC.define) || window.define);"
  • your MS should be publicly available. e.g. hosted under 0.0.0.0(default for Node http, so for express too) and available under your IP address or any other tools e.g ngrok or smth else.
  • add "ILC-overrideConfig" cookie with config to production:
const overrideConfig = encodeURIComponent(
    JSON.stringify({
        "apps": {
            // rewrite existed MS
            "@portal/NAME1": {
                "spaBundle": "http://10.1.150.85:2273/bundle.js", // url to bundle
                "ssr": {
                    "src": "http://10.1.150.85:2273/", // url to ssr
                },
            },
            // add new MS
            "@portal/NAME2": {
                "spaBundle": "http://10.1.150.85:9892/bundle.js", // url to bundle
                "ssr": {
                    "src": "http://10.1.150.85:9891/", // url to ssr
                    "timeout": 1000,
                },
                "kind": "primary",
            },
        },
        // add new MS slot to certain route
        "routes": [
            {
                "routeId": 103,
                "route": "/example/",
                "next": false,
                "slots": {
                    "body": {
                        "appName": "@portal/NAME2",
                        "kind": null
                    },
                },
            },
        ],
    })
);

document.cookie = `ILC-overrideConfig=${overrideConfig}; path=/;`
  • since you probably run your MS locally via http and if your production site uses https so you will have problems with mixed content when you try to send request to http from https, so the simplest way to resolve it - just turn off checking in your browser. Details link.
  • if you exclude some libs e.g. via "externals" property of webpack config - comment it during developing at production.

Shared libraries

Shared libraries support the same way of developing like MSs. You just need to provide library name (w/o prefix "@sharedLibrary/") and path to spa-bundle:

const overrideConfig = encodeURIComponent(
    JSON.stringify({
        "sharedLibs": {
            "sampleLibrary": {
                "spaBundle": 'http://10.1.150.85:9001/bundle.js',
            },
        },
    })
);

document.cookie = `ILC-overrideConfig=${overrideConfig}; path=/;`