Skip to content

Instantly share code, notes, and snippets.

@ftischler
Last active January 12, 2022 11:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ftischler/d666fe020432020edcc4a9a27bbdf30e to your computer and use it in GitHub Desktop.
Save ftischler/d666fe020432020edcc4a9a27bbdf30e to your computer and use it in GitHub Desktop.
Module Federation Blank Page
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { resolveRemoteModule } from './resolve-remote-module';
const routes: Routes = [
{
path: 'somepath',
loadChildren: () => resolveRemoteModule({
remoteName: 'somemodule',
remoteEntry: '/remotes/somemodule/remoteEntry.js',
exposedModule: './Module'
}).load((m) => m.SomeModule)
}
];
@NgModule({
imports: [
RouterModule.forRoot(routes, {
initialNavigation: 'enabledBlocking',
onSameUrlNavigation: 'reload'
})
],
exports: [RouterModule]
})
export class AppRoutingModule {}
// Detect whether we are on the server because Node.js has process as global object
export const isServer: () => boolean = () => typeof process === 'object' && process.constructor.name === 'process';
export const isBrowser: () => boolean = () => !isServer();
import { CommonModule } from '@angular/common';
import { Component, NgModule } from '@angular/core';
import { RouterModule } from '@angular/router';
@Component({
template: ''
})
export class BlankComponent {}
/**
* @author Florian Tischler
* This library does some things to ensure ModuleFederation is running with our SSR-Setup.
* As the support of ModuleFederation should evolve we hope the remove this library soon and use official Framework tools.
*/
@NgModule({
declarations: [BlankComponent],
imports: [
CommonModule,
RouterModule.forChild([
{
path: '**',
component: BlankComponent
}
])
]
})
export class RemoteEntryModule {}
import { loadRemoteEntry, loadRemoteModule } from '@angular-architects/module-federation';
import { LoadRemoteModuleOptions } from '@angular-architects/module-federation-runtime/lib/loader/dynamic-federation';
import { isBrowser } from './platform';
export type RemoteModuleOptions = Required<LoadRemoteModuleOptions>;
/**
* @author Florian Tischler
* This functions detect whether Angular is running in the Browser or in Node.js with SSR.
* If we are in the browser, we load the remote module via the ModuleFederation Lib.
* If we are on the server, we resolve a module with a blank component for every route so the server renders a blank page.
*/
export const resolveRemoteModule = (remoteModuleOptions: RemoteModuleOptions) =>
isBrowser()
? getLoader(loadRemoteModule(remoteModuleOptions))
: getNoopLoader(import('./remote-entry.module').then((m) => m.RemoteEntryModule));
export const getLoader = <T>(promise: Promise<T>) => ({
load: (...args: Parameters<Promise<T>['then']>) => promise.then(...args)
});
export const getNoopLoader = <T>(promise: Promise<T>) => ({
load: (..._args: Parameters<Promise<T>['then']>) => promise
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment