3.40.28 • Published 3 days ago

@tramvai/module-child-app v3.40.28

Weekly downloads
-
License
Apache-2.0
Repository
github
Last release
3 days ago

ChildApp

Module for child app

Installation

First, install @tramvai/module-child-app

yarn add @tramvai/module-child-app

And then add module to your app

import { createApp } from '@tramvai/core';
import { ChildAppModule } from '@tramvai/module-child-app';

createApp({
  name: 'tincoin',
  modules: [ChildAppModule],
});

Explanation

Terms

  • root-app - basic tramvai-app constructed with createApp from @tramvai/core. It can connect with many child-app
  • child-app - external microfrontend constructed with createChildApp from @tramvai/child-app-core. It is loaded by root-app and provides some external functionality
  • SingletonDI - DI-container which is exist in single instance for app and exists as long as app itself
  • RequestDI - DI-Container which is created for every request and represents specific data for single client. RequestDI inherits providers from SingletonDI and it is independent from other RequestDIs
  • CommandLineRunner - instance of CommandModule

DI

Every child-app has its own DI-hierarchy which is isolated from other child app and partially from root-app. The only way communicate fpr DIs it's getting providers from root-app di inside child-app.

Next picture shows connection between DI-containers in root-app and child-apps

di

How does it work when we trying to get provider from DI in child-app:

  1. First check that provider is exist in the current DI-container. If it is then return it.
  2. If current DI is RequestDI then go to SingletonDI of child-app and look for provider.
    1. If it exists in SingletonDI then return it
    2. Go to RequestDI of root-app and if provider exists in it return it
    3. Go to SingletonDI of root-app and if provider exists in it return it
    4. Throw error otherwise
  3. If current DI is SingletonDI then go to SingletonDI of root-app and check for provider there
    1. If it exists then return it
    2. Throw error otherwise

CommandLineRunner

Each child-app has its own CommandLineRunner instance which allows to child-app make some preparations before the actual page render. This CommandLineRunner has almost identical lines as root-app to simplicity, but it is actually completely other line which are independent from lines in root-app

command-line-runner

All of the accepted line tokens:

const command = {
  customer: [
    commandLineListTokens.customerStart,
    commandLineListTokens.resolveUserDeps,
    commandLineListTokens.resolvePageDeps,
  ],
  clear: [commandLineListTokens.clear],
  spa: [
    commandLineListTokens.resolveUserDeps,
    commandLineListTokens.resolvePageDeps,
    commandLineListTokens.spaTransition,
  ],
};

Child-app must be preloaded first to allow to execute commandline runner. In case of late preloading CommandLineRunner will be executed anyway but it will be out of sync with root-app CommandLineRunner (it will be called as soon as child-app code was loaded).

Server

  • If child-app was preloaded before root-app resolvePageDeps then customer line list is executed on root-app resolvePageDeps line
  • If child-app was preloaded on root-app resolvePageDeps then customer line list is executed as soon as child-app was loaded. preload call must be awaited in order to prevent root-app CommandLineRunner to passing to next line. That still counts as executing on resolvePageDeps line.
  • Child-app clear line list is executed on root-app clear line for every child-app that was preloaded on previous lines

Client

First Page load
  • If child-app was preloaded on server customer line list is executed on root-app resolvePageDeps line
  • If child-app was not preloaded on server but was preloaded on client then customer line list is executed on root-app clear line
  • Child-app clear line list is executed on root-app clear line for every child-app that was preloaded on previous lines
Spa-transitions
  • If child-app was not preloaded on any previous pages before but was preloaded on next page then customer line list is executed as soon as child-app is loaded
  • If child-app was preloaded on next page then child-app spa line list is executed on root-app spaTransition line

Loading Child App

Loading of child-app is happens only after preloading child-app with CHILD_APP_PRELOAD_MANAGER. This preloading loads code for a child-app and marks it to execution using CommandLineRunner.

loading

Server

  • Calling PreloadManager.preload(...) loads a child-app code, executes and marks it as executable to CommandLineRunner
  • Result of PreloadManager.preload(...) must be awaited as it is important to synchronize child-app commands lines execution with a root-app CommandLinerRunner
  • Preloads after root-app resolvePageDeps are useless as they wont change page render and wont be used by root-app.

Client

  • Calling PreloadManager.preload(...) loads a child-app code, executes and marks it as executable to CommandLineRunner
  • Result of PreloadManager.preload(...) must be awaited as it is important to synchronize child-app commands lines execution with a root-app CommandLinerRunner
  • If child-app was preloaded on server then child-app customer line list is executed on resolvePageDeps on first page render
  • If child-app was not preloaded on server then actual loading and command-line execution are happens on root-app clear line as executing child-app before page render may break React hydration and should be executed only after it.
  • On spa transition when previously child-app is preloaded it will be reused
  • On spa transition if preloaded child-app was not loaded before it will be loaded and executed as soon as possible.

State

State Management is almost completely isolated from root-app and other of child-apps. Every child-app can register own stores, actions.

State for child-apps will be dehydrated on server as separate variable in the result html and then will be automatically rehydrated on client for every child-app.

:::warning

By default, child-app cannot read data from root-app stores, but the you can specify the set of root-app stores that might be used inside child-app.

It may be done using CHILD_APP_INTERNAL_ROOT_STATE_ALLOWED_STORE_TOKEN token.

This token is considered undesirable to use as it leads to high coupling with stores from root-app and this way stores in root-app might not change their public interface. But, in most cases, changes in stores ignore breaking change tracking and may breaks backward-compatibility. So do not use this token if you can, and if you should - use as little as possible from root-app and provide some fallback in case of wrong data.

See how to do it

:::

API

CHILD_APP_INTERNAL_ROOT_STATE_ALLOWED_STORE_TOKEN

Defines the list of allowed root-app store names that might be used inside child-app.

  1. Specify stores that might be used inside child-app

    provide({
      provide: CHILD_APP_INTERNAL_ROOT_STATE_ALLOWED_STORE_TOKEN,
      multi: true,
      useValue: [MediaStore, AuthenticateStore],
    });
  2. Use the specified root-app stores the same way as usual stores

    import React from 'react';
    import { useSelector } from '@tramvai/state';
    
    export const StateCmp = () => {
      const value = useSelector(['root'], (state) => {
        return state.root.value;
      });
    
      return <div id="child-state">Current Value from Root Store: {value}</div>;
    };

How to

Connect a child app

  1. Place a child-app React component somewhere in your page render

    import React from 'react';
    import { ChildApp } from '@tramvai/module-child-app';
    
    export const Page = () => {
      return (
        <div>
          ...
          <ChildApp name="[name]" />
          ...
        </div>
      );
    };
  2. Add configuration for child-app loading

    providers: [
      provide({
        provide: CHILD_APP_RESOLVE_BASE_URL_TOKEN, // or use `CHILD_APP_EXTERNAL_URL` env
        useValue: 'http://localhost:4040/',
      }),
      provide({
        provide: CHILD_APP_RESOLUTION_CONFIGS_TOKEN,
        useValue: [
          {
            name: '[name]', // name of the child-app
            byTag: {
              latest: {
                version: '[version]', // current version for the child app for tag `latest`
              },
            },
          },
        ],
      }),
    ];
  3. Preload child-app execution in order to improve performance and allow child-app execute its data preparations

    import { commandLineListTokens, Provider, provide } from '@tramvai/core';
    import { CHILD_APP_PRELOAD_MANAGER_TOKEN } from '@tramvai/module-child-app';
    
    const providers: Provider[] = [
      provide({
        provide: commandLineListTokens.customerStart,
        multi: true,
        useFactory: ({ preloadManager }) => {
          return function preloadHeaderChildApp() {
            return preloadManager.preload({ name: '[name]' }); // this call is important
          };
        },
        deps: {
          preloadManager: CHILD_APP_PRELOAD_MANAGER_TOKEN,
        },
      }),
    ];

Preload child-app

Preloading is vital for using child-app without extensive overhead on its loading.

You may preload using next ways:

  1. Preload with CHILD_APP_PRELOAD_MANAGER_TOKEN

    provide({
      provide: commandLineListTokens.customerStart,
      multi: true,
      useFactory: ({ preloadManager }) => {
        return function preloadHeaderChildApp() {
          return preloadManager.preload({ name: '[name]' });
        };
      },
      deps: {
        preloadManager: CHILD_APP_PRELOAD_MANAGER_TOKEN,
      },
    });
  2. Add needed child-apps to the pageComponent or layoutComponent through field childApps

const PageComponent = () => {
  return 'Page';
};

PageComponent.childApps = [{ name: '[name]' }];

Debug child-app

Single child-app

  1. Run child-app using cli

    yarn tramvai start child-app
  2. Run root-app with CHILD_APP_DEBUG environment variable

    CHILD_APP_DEBUG=child-app yarn tramvai start root-app

Multiple child-app

  1. Run somehow multiple child-apps. They should be started on different ports.
  2. And either pass Base Url showed from cli as url to debug every child-app

    CHILD_APP_DEBUG=child-app1=baseUrl1;child-app2=baseUrl2 yarn tramvai start root-app
  3. Or implement proxy on default http:://localhost:4040/ yourself which redirects to concrete server by url

    CHILD_APP_DEBUG=child-app1;child-app2 yarn tramvai start root-app

More detailed debug setup

You may specify a full config to debug to a specific child-app:

  1. To token CHILD_APP_RESOLUTION_CONFIGS_TOKEN for needed child-apps add special tag debug:
    ({
      name: 'child-app',
      byTag: {
        latest: {
          version: 'latest',
        },
        debug: {
          baseUrl: '...url',
          version: '...version',
          client: {},
          server: {},
          css: {},
        },
      },
    });
  2. Run root-app with CHILD_APP_DEBUG environment variable with value of child-app names needed to debug
4.9.0

3 days ago

3.40.28

8 days ago

4.8.6

8 days ago

3.40.26

8 days ago

3.40.25

9 days ago

4.8.4

8 days ago

4.8.3

9 days ago

3.40.21

12 days ago

4.7.1

12 days ago

3.40.20

13 days ago

4.7.0

13 days ago

4.4.6

17 days ago

3.40.17

17 days ago

4.4.5

18 days ago

4.4.4

18 days ago

3.40.16

18 days ago

4.4.1

19 days ago

4.4.3

19 days ago

3.40.14

19 days ago

3.40.13

19 days ago

4.3.1

20 days ago

3.40.11

20 days ago

4.3.0

22 days ago

3.40.6

24 days ago

3.40.7

24 days ago

4.2.1

24 days ago

4.2.0

24 days ago

4.1.0

24 days ago

4.0.6

27 days ago

3.40.5

27 days ago

4.0.5

1 month ago

4.0.4

1 month ago

3.40.4

1 month ago

3.38.0

1 month ago

3.37.10

1 month ago

3.37.8

2 months ago

3.37.7

2 months ago

3.37.5

2 months ago

3.37.1

2 months ago

3.34.0

3 months ago

3.33.2

3 months ago

3.33.0

3 months ago

3.32.3

3 months ago

3.31.0

3 months ago

3.31.2

3 months ago

3.31.3

3 months ago

3.30.1

3 months ago

3.27.5

3 months ago

3.27.3

3 months ago

3.27.4

3 months ago

3.27.0

4 months ago

3.26.3

4 months ago

3.26.2

4 months ago

3.25.5

4 months ago

3.25.6

4 months ago

3.25.3

4 months ago

3.25.0

4 months ago

3.25.2

4 months ago

3.24.3

4 months ago

3.24.1

4 months ago

3.24.0

4 months ago

3.23.0

5 months ago

3.21.0

5 months ago

3.19.0

5 months ago

3.19.1

5 months ago

3.17.0

5 months ago

3.12.0

5 months ago

3.14.1

5 months ago

3.14.0

5 months ago

2.160.25

5 months ago

3.13.0

5 months ago

3.10.2

5 months ago

3.11.0

5 months ago

3.15.1

5 months ago

3.16.0

5 months ago

2.142.1

8 months ago

2.142.0

8 months ago

2.139.3

8 months ago

2.139.2

8 months ago

3.2.0

6 months ago

2.154.0

7 months ago

2.149.0

8 months ago

2.149.1

8 months ago

2.141.2

8 months ago

2.141.1

8 months ago

2.130.9

9 months ago

2.130.7

9 months ago

2.130.6

9 months ago

2.153.3

7 months ago

2.160.21

5 months ago

2.130.4

9 months ago

2.153.1

7 months ago

2.153.2

7 months ago

2.153.0

7 months ago

2.160.12

6 months ago

2.160.17

6 months ago

2.160.19

6 months ago

2.160.10

6 months ago

2.121.2

10 months ago

3.9.1

5 months ago

3.9.0

5 months ago

2.118.1

10 months ago

3.0.2

6 months ago

2.133.5

8 months ago

2.133.4

8 months ago

3.10.0

5 months ago

2.133.2

9 months ago

2.156.1

7 months ago

2.133.0

9 months ago

3.0.0

6 months ago

2.143.0

8 months ago

2.143.1

8 months ago

2.120.0

10 months ago

2.130.10

9 months ago

2.117.4

10 months ago

2.130.11

9 months ago

2.117.2

10 months ago

2.117.0

10 months ago

3.7.0

6 months ago

2.132.1

9 months ago

2.155.0

7 months ago

2.132.0

9 months ago

2.123.4

9 months ago

2.146.1

8 months ago

2.123.3

9 months ago

2.123.2

9 months ago

2.123.1

9 months ago

2.146.0

8 months ago

2.150.0

8 months ago

2.150.1

7 months ago

2.145.0

8 months ago

2.145.1

8 months ago

2.160.4

6 months ago

2.122.0

10 months ago

2.160.2

6 months ago

2.160.1

7 months ago

2.119.5

10 months ago

2.119.4

10 months ago

2.119.3

10 months ago

2.119.2

10 months ago

2.119.0

10 months ago

3.5.0

6 months ago

2.134.0

8 months ago

2.125.4

9 months ago

2.148.1

8 months ago

2.125.3

9 months ago

2.125.2

9 months ago

2.148.0

8 months ago

2.125.0

9 months ago

2.137.0

8 months ago

3.4.1

6 months ago

2.152.2

7 months ago

2.152.3

7 months ago

2.152.1

7 months ago

2.147.1

8 months ago

2.124.0

9 months ago

3.4.6

6 months ago

3.4.5

6 months ago

2.159.5

7 months ago

2.159.6

7 months ago

2.159.4

7 months ago

2.159.1

7 months ago

2.159.2

7 months ago

3.3.2

6 months ago

2.151.0

7 months ago

2.112.0

11 months ago

2.111.1

11 months ago

2.111.0

11 months ago

2.95.0

1 year ago

2.95.4

12 months ago

2.103.1

12 months ago

2.94.27

1 year ago

2.94.24

1 year ago

2.94.23

1 year ago

2.94.25

1 year ago

2.104.0

12 months ago

2.104.2

12 months ago

2.104.3

12 months ago

2.104.4

12 months ago

2.106.3

11 months ago

2.106.4

11 months ago

2.106.5

11 months ago

2.105.0

12 months ago

2.110.0

11 months ago

2.106.2

12 months ago

2.108.1

11 months ago

2.109.0

11 months ago

2.109.1

11 months ago

2.98.2

12 months ago

2.98.0

12 months ago

2.100.0

12 months ago

2.108.0

11 months ago

2.97.2

12 months ago

2.97.0

12 months ago

2.101.0

12 months ago

2.101.1

12 months ago

2.102.1

12 months ago

2.94.17

1 year ago

2.94.16

1 year ago

2.94.2

1 year ago

2.94.19

1 year ago

2.94.18

1 year ago

2.94.13

1 year ago

2.94.12

1 year ago

2.94.6

1 year ago

2.94.15

1 year ago

2.94.4

1 year ago

2.94.9

1 year ago

2.94.7

1 year ago

2.94.8

1 year ago

2.94.0

1 year ago

2.79.9

1 year ago

2.79.7

1 year ago

2.79.6

1 year ago

2.79.5

1 year ago

2.79.4

1 year ago

2.82.0

1 year ago

2.93.0

1 year ago

2.78.2

1 year ago

2.78.1

1 year ago

2.89.2

1 year ago

2.92.1

1 year ago

2.77.0

1 year ago

2.92.0

1 year ago

2.76.2

1 year ago

2.91.1

1 year ago

2.87.0

1 year ago

2.90.0

1 year ago

2.85.1

1 year ago

2.84.0

1 year ago

2.84.2

1 year ago

2.75.0

1 year ago

2.74.0

1 year ago

2.73.1

1 year ago

2.73.0

1 year ago

2.72.0

1 year ago

2.72.5

1 year ago

2.72.4

1 year ago

2.72.3

1 year ago

2.67.1

1 year ago

2.70.1

1 year ago

2.70.0

1 year ago

2.67.0

1 year ago

2.66.0

1 year ago

2.66.2

1 year ago

2.66.3

1 year ago

2.65.9

1 year ago

2.64.0

1 year ago

2.49.5

1 year ago

2.49.2

1 year ago

2.49.3

1 year ago

2.49.0

1 year ago

2.56.0

1 year ago

2.56.5

1 year ago

2.56.1

1 year ago

2.56.2

1 year ago

2.63.0

1 year ago

2.48.3

1 year ago

2.48.0

1 year ago

2.51.2

1 year ago

2.51.0

1 year ago

2.51.1

1 year ago

2.59.2

1 year ago

2.59.3

1 year ago

2.59.4

1 year ago

2.59.0

1 year ago

2.50.0

1 year ago

2.61.1

1 year ago

2.61.2

1 year ago

2.34.0

2 years ago

2.45.0

1 year ago

2.45.1

1 year ago

2.33.1

2 years ago

2.37.3

2 years ago

2.33.3

2 years ago

2.33.2

2 years ago

2.37.1

2 years ago

2.37.0

2 years ago

2.40.0

1 year ago

2.44.2

1 year ago

2.32.0

2 years ago

2.36.0

2 years ago

2.47.3

1 year ago

2.47.0

1 year ago

2.47.2

1 year ago

2.47.1

1 year ago

2.31.0

2 years ago

2.39.0

1 year ago

2.39.3

1 year ago

2.39.2

1 year ago

2.35.0

2 years ago

2.27.0

2 years ago

2.22.0

2 years ago

2.26.2

2 years ago

2.26.0

2 years ago

2.21.0

2 years ago

2.21.1

2 years ago

2.29.0

2 years ago

2.25.1

2 years ago

2.20.0

2 years ago

2.20.1

2 years ago

2.28.0

2 years ago

2.24.1

2 years ago

2.24.0

2 years ago

2.24.3

2 years ago

2.11.0

2 years ago

2.0.2

2 years ago

2.4.0

2 years ago

2.0.7

2 years ago

2.0.0

2 years ago

2.3.0

2 years ago

2.10.2

2 years ago

2.7.0

2 years ago

2.7.1

2 years ago

1.110.2

2 years ago

1.110.0

2 years ago

2.2.3

2 years ago

2.2.2

2 years ago

2.6.2

2 years ago

1.109.0

2 years ago

2.5.0

2 years ago

1.108.1

2 years ago

1.94.5

2 years ago

1.98.0

2 years ago

1.94.2

2 years ago

1.94.1

2 years ago

1.94.0

2 years ago

1.103.0

2 years ago

1.99.1

2 years ago

1.97.0

2 years ago

1.106.0

2 years ago

1.102.1

2 years ago

1.96.0

2 years ago

1.105.3

2 years ago

1.101.8

2 years ago

1.105.2

2 years ago

1.101.6

2 years ago

1.101.3

2 years ago

1.101.4

2 years ago

1.101.2

2 years ago

1.95.2

2 years ago

1.95.1

2 years ago

1.95.0

2 years ago

1.104.2

2 years ago

1.101.9

2 years ago

1.105.6

2 years ago

1.90.6

2 years ago

1.92.3

2 years ago

1.92.2

2 years ago

1.90.4

2 years ago

1.92.0

2 years ago

1.90.2

2 years ago

1.90.1

2 years ago

1.84.0

2 years ago

1.84.2

2 years ago

1.89.1

2 years ago

1.93.1

2 years ago

1.91.1

2 years ago

1.91.0

2 years ago

1.85.0

2 years ago

1.82.1

2 years ago

1.82.2

2 years ago

1.82.3

2 years ago

1.79.0

2 years ago

1.78.0

2 years ago

1.76.2

2 years ago

1.78.1

2 years ago

1.78.2

2 years ago

1.78.3

2 years ago

1.81.0

2 years ago

1.77.0

2 years ago

1.72.1

2 years ago

1.74.0

2 years ago

1.72.2

2 years ago

1.76.0

2 years ago

1.76.1

2 years ago

1.73.0

2 years ago

1.75.0

2 years ago

1.75.1

2 years ago

1.56.0

2 years ago

1.58.1

2 years ago

1.58.0

2 years ago

1.61.0

2 years ago

1.63.1

2 years ago

1.65.0

2 years ago

1.65.1

2 years ago

1.67.0

2 years ago

1.48.3

2 years ago

1.70.0

2 years ago

1.70.2

2 years ago

1.51.0

2 years ago

1.55.0

2 years ago

1.53.2

2 years ago

1.53.1

2 years ago

1.55.2

2 years ago

1.53.4

2 years ago

1.55.1

2 years ago

1.59.0

2 years ago

1.55.4

2 years ago

1.53.6

2 years ago

1.57.1

2 years ago

1.55.3

2 years ago

1.53.5

2 years ago

1.55.5

2 years ago

1.62.0

2 years ago

1.60.2

2 years ago

1.60.1

2 years ago

1.64.0

2 years ago

1.62.1

2 years ago

1.66.0

2 years ago

1.66.1

2 years ago

1.68.0

2 years ago

1.68.1

2 years ago

1.49.1

2 years ago

1.49.0

2 years ago

1.71.0

2 years ago

1.71.1

2 years ago

1.50.1

2 years ago

1.50.0

2 years ago

1.50.3

2 years ago

1.52.0

2 years ago

1.50.2

2 years ago

1.54.0

2 years ago

1.50.4

2 years ago

1.48.2

2 years ago

1.48.1

2 years ago

1.47.0

2 years ago

1.46.11

2 years ago

1.46.10

2 years ago

1.46.9

2 years ago

1.46.8

2 years ago

1.46.7

2 years ago

1.46.6

2 years ago

1.46.5

2 years ago