@unily/angular-sdk

16.0.1 • Public • Published

Unily - Angular SDK

This SDK provides the tools needed to support Angular Module Federation development within Unily. It includes a schematics package that automatically sets up the scaffolding for a new micro frontend module build, it generates the essential files and configurations needed to make Angular Module Federation facilities available within the set workspace.

Prerequisites

This project requires NodeJS and NPM to be installed. To make sure you have them available on your machine, try running the following commands:

npm -v
node -v

Installation

To run the schematics collection, first you'll need to install the following Angular development packages globally on your machine so they will provide you with the schematics command line tools:

npm install -g @angular-devkit/schematics
npm install -g @angular-devkit/schematics-cli

Next, install this SDK globally on your machine:

npm install -g @unily/angular-sdk

Usage

Target the workspace folder you wish to generate the micro frontend module in, then run the new-mfe schematic with the following command:

cd {path}
schematics @unily/angular-sdk:new-mfe

This will prompt you to input some configuration settings for the new project:

  • Project name - This will set the workspace directory name accordingly
  • Angular directive selector prefix - This will enforce a linting rule across the project requiring the set value as a prefix for the 'selector' property
  • Webpack server port number - This will set the port number for the module to run on

After running the schematic, the workspace will be populated with the associated file structure. Package dependencies will also be downloaded and installed automatically to prepare the newly generated module for development.

Configuration

Environment configuration details can be fetched from the CMS.

Run MFE

To start a module on your local environment, run the following command:

Note - This will serve the module on the configured port number.

npm run start

Deploy MFE

To deploy a module, run the following commands:

npm run build
npm run deploy

This will prompt you to choose from different deployment options:

  • Lazy Loaded - Choose whether the module should be lazily or eagerly loaded
  • Starts enabled - Choose whether the module should be immediately enabled after being deployed

The module will then be added to the 'Application Federated Modules' page in the CMS once it's been successfully deployed.

Functionality

The public surface of a newly generated module is defined by what we expose in webpack.config.js file. Anything that needs to be exposed publicly by the module needs to be defined in public.module.metadata.ts file:

Note: If you do not wish to export a component and prefer to keep it as internal, you just need to exclude it from the exports array.

public.module.metadata.ts

...
export const metadata = {
    imports: [
        BrowserModule
    ],
    declarations: [
        ButtonComponent,
    ],
    exports: [
        // On bootstrap, custom HTML elements are created for the components listed here.
        // These components will be immediately available when a module is imported.
        ButtonComponent,
    ],
    providers: [
        // These are the services that will be publicly exposed by this module.
        // The string token allows us to have a reference to the injector without requiring any reference to a specific construct inside this module.
        // Specified dependencies do not need to be exported, but they need to be specified here for the services that require them.
        {
            provide: 'ButtonService',
            useClass: ButtonService,
            deps: [IncrementService]
        }
    ],
    // We specify this to allow custom elements to be used within HTML templates.
    // It suppresses Angular warnings about non-existent selectors at compile time.
    schemas: [CUSTOM_ELEMENTS_SCHEMA]
} as NgModule;
...

Module loading

These are the capabilities of loading a remote module:

  • Can be side-loaded through CMS config ✔
  • Can be imported ✔
  • Can be lazy loaded ✔
  • Can be deployed to a blob ✔
  • Requires environment redeployment on change ❌
  • Can side-load modules through CMS config ❌

Note: Remote modules do not import side-loaded modules explicitly, but inherit any side-loaded module configurations. When running stand-alone, the side-loaded modules will not be available to the remote module.

Dynamically importing modules

A remote module can import myFederatedModules, applicationFederatedModules and unilyFederatedModules modules. Each remote module is configured separately and can import other modules' type definitions when their name is added inside module-federation/mf.config.js file.

mf.config.js

module.exports = {
    projectName: 'my-project',
    dependencies: {
        // Load types from the client's blob storage.
        applicationFederatedModules: [
            /* 
                'app-state',
                'ui-library'
                ...
            */
        ],
        // Load types from Unily's package manager.
        unilyFederatedModules: [
            /* 
                'unily-ui-library'
                ...
            */
        ],
        // Load types AND remote modules from the local environment. 
        // This is useful for testing and development without having to side-load modules through the CMS.
        myFederatedModules: [
            /*
                'app-state',
                'counter'
                ...
            */
        ]
    },
    // Authentication token needed to load types for `applicationFederatedModules` and `unilyFederatedModules`
    // OR to deploy the current module.
    /**
     * Fetch your endpoint and auth token from
     * 'My Federated Modules' or 'Application Federated Modules' pages in CMS
     * by clicking on 'Get PAT Token' and copying the values provided
     * in the overlay.
     */ 
    endpoint: '',
    authToken: ''
}

Lazy loading

Modules can be either lazily or eagerly loaded. Eagerly loaded modules are imported and bootstrapped before the module importing those modules is bootstrapped. This is useful when a module specifies some global state or runs an app initialisation script. Lazily loaded modules need to be manually imported wherever they are first needed using a dynamic import as follows:

...
import { RemoteNgModule, importRemote } from '@unily/remote-service';
...
// Dynamically import the module - this lazily loads the module when the importing module is bootstrapped.
// By this point, we can already use any exported components.
const uiLibrary = await importRemote<RemoteNgModule>('ui-library');
const counter = await importRemote<RemoteNgModule>('counter');
...
@NgModule({
    ...
    providers: [
        ...
        // add the service provider for the desired service from the imported module
        uiLibrary.getProviders('ButtonService'),
        ...
    ],
    schemas: [CUSTOM_ELEMENTS_SCHEMA]
})
...
    private readonly counterService: CounterService;

    constructor(
        ...
        // inject the service using the provided injection token...
        @Inject('ButtonService') private readonly buttonService: ButtonService,
        ...
    ) {
        // ...or get the service directly without providing or injecting it.
        this.counterService = counter.getService('CounterService');
    }
 ...   

More information about Angular Module Federation and its setup can be found in this Wiki page.

Package Sidebar

Install

npm i @unily/angular-sdk

Weekly Downloads

4

Version

16.0.1

License

UNLICENSED

Unpacked Size

81.8 kB

Total Files

60

Last publish

Collaborators

  • mark.galea
  • marlon.calleja
  • developmentaccounts