@grasp-labs/ds-web-microfrontends-common-lib
v0.2.0
Published
Standardized Module Federation configuration for remote microfrontend applications. This library provides opinionated defaults and type-safe utilities for building microfrontends with Vite and React.
Downloads
405
Readme
@grasp-labs/ds-web-microfrontends-common-lib
Standardized Module Federation configuration for remote microfrontend applications. This library provides opinionated defaults and type-safe utilities for building microfrontends with Vite and React.
Installation
npm install @grasp-labs/ds-web-microfrontends-common-libPrerequisites
Node.js: >= 22
This library requires compatible peer dependencies. Install them in your microfrontend project, for example:
npm install -D [email protected]Optionally, for Data Platform integration:
npm install -D @grasp-labs/ds-microfrontends-integrationVersion requirements are defined in this package's peerDependencies - check package.json for current version ranges.
Quick Start
1. Configure Vite
Create or update your vite.config.ts:
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import {
createMicrofrontendsBase,
dsFederation,
} from "@grasp-labs/ds-web-microfrontends-common-lib";
import { name } from "./package.json";
const MICROFRONTENDS_BASE = createMicrofrontendsBase(name);
export default defineConfig(({ mode }) => ({
base: mode === "production" ? MICROFRONTENDS_BASE : "/",
plugins: [react(), dsFederation(name)],
}));2. Create Your App Component
Your src/App.tsx should export a React component with Routes (not render it):
// src/App.tsx
import { Routes, Route } from "react-router";
import { HomePage } from "./layouts/HomePage";
import { SettingsPage } from "./layouts/SettingsPage";
import { InternalPage } from "./layouts/InternalPage";
function App() {
return (
<Routes>
<Route path="/" element={<HomePage />} />
<Route path="/settings" element={<SettingsPage />} />
<Route path="/internal" element={<InternalPage />} />
</Routes>
);
}
export default App;3. Define Navigation Configuration
Create src/navigationConfig.ts:
import type { NavigationConfig } from "@grasp-labs/ds-web-microfrontends-common-lib";
export const navigationConfig = {
INDEX: {
label: "Home",
path: "/",
icon: "database",
type: "visible",
},
SETTINGS: {
label: "Settings",
path: "/settings",
icon: "cogWheel",
type: "visible",
},
INTERNAL: {
label: "Internal Page",
path: "/internal",
type: "hidden",
},
} satisfies NavigationConfig;Important: The navigationConfig.ts file must remain a bare TypeScript file with no React imports or dependencies. This is critical because:
- The microfrontend app (src/App.tsx) is lazily loaded by the host application
- The host app needs immediate access to the routing configuration to build the navigation structure before any remote apps are loaded
- If navigationConfig imports React or other heavy dependencies, it would force those dependencies to load before navigation can be rendered, defeating the purpose of lazy loading
Keep this file lightweight - only export the configuration object with no side effects or dependencies.
Default Module Federation Configuration
The dsFederation plugin automatically configures:
Exposes:
"."→"./src/App"- Your main React component"./navigationConfig"→"./src/navigationConfig"- Navigation configuration
Shared Dependencies:
react(singleton)react-dom(singleton)react-router(singleton)
Public Path: microfrontends/${name}/
Advanced Usage
Custom Module Federation Configuration
Override defaults by passing configuration to dsFederation:
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import { dsFederation } from "@grasp-labs/ds-web-microfrontends-common-lib";
export default defineConfig({
plugins: [
react(),
dsFederation("your-microfrontend-name", {
exposes: {
".": "./src/App",
"./navigationConfig": "./src/navigationConfig",
"./CustomComponent": "./src/components/CustomComponent",
},
shared: {
lodash: {
singleton: true,
requiredVersion: "^4.17.21",
},
},
}),
],
});Using DATA_PLATFORM_SHARED_DEPS
For microfrontends that integrate with @grasp-labs/ds-microfrontends-integration:
import {
createModuleFederationConfig,
DATA_PLATFORM_SHARED_DEPS,
} from "@grasp-labs/ds-web-microfrontends-common-lib";
import { federation } from "@module-federation/vite";
export default defineConfig({
plugins: [
react(),
federation({
...createModuleFederationConfig("your-microfrontend-name", {
shared: DATA_PLATFORM_SHARED_DEPS,
}),
}),
],
});API Reference
Functions
dsFederation(name, overrides?)
Creates a configured Vite Module Federation plugin.
Parameters:
name(string): The name of the microfrontend (typically from package.json)overrides(Partial, optional): Override default configuration
Returns: Configured Vite plugin
Example:
dsFederation("my-app", {
exposes: {
".": "./src/App",
"./utils": "./src/utils",
},
});createModuleFederationConfig(name, overrides?)
Generates the Module Federation configuration object without wrapping it in a Vite plugin.
Parameters:
name(string): The name of the microfrontendoverrides(Partial, optional): Override default configuration
Returns: ModuleFederationOptions object
Example:
const config = createModuleFederationConfig("my-app");createMicrofrontendsBase(name)
Generates the standardized public path for a microfrontend.
Parameters:
name(string): The name of the microfrontend
Returns: string - Path in format microfrontends/${name}/
Example:
createMicrofrontendsBase("data-sources"); // "microfrontends/data-sources/"Constants
COMMON_SHARED_DEPS
Standard shared dependencies for Module Federation. Versions are sourced from this package's peerDependencies.
{
react: { singleton: true, requiredVersion: "<version from peerDependencies>" },
"react-dom": { singleton: true, requiredVersion: "<version from peerDependencies>" },
"react-router": { singleton: true, requiredVersion: "<version from peerDependencies>" },
}DATA_PLATFORM_SHARED_DEPS
Extended shared dependencies including Data Platform integration library.
{
...COMMON_SHARED_DEPS,
"@grasp-labs/ds-microfrontends-integration": {
singleton: true,
requiredVersion: "<version from peerDependencies>",
},
}Type Definitions
RouteConfig
Defines a single route in the navigation system.
type RouteConfig = {
label: string; // Display name
path: string; // Route path
icon?: IconName; // Optional icon from @grasp-labs/ds-react-components
type?: "hidden" | "visible"; // Visibility in navigation
};CategoryConfig
Defines a navigation category with nested routes.
type CategoryConfig = {
label: string;
icon?: IconName;
type: "category";
children: Record<string, RouteConfig | CategoryConfig>;
};NavigationItem
Union type for navigation items.
type NavigationItem = RouteConfig | CategoryConfig;NavigationConfig
Type-safe navigation configuration. Requires an INDEX route.
type NavigationConfig<TKeys extends string = string> = {
INDEX: RouteConfig;
} & Record<TKeys, NavigationItem>;Example:
const navigationConfig = {
INDEX: {
label: "Data Sources",
path: "/",
icon: "database",
type: "visible",
},
CATALOG: {
label: "Catalog",
icon: "folder",
type: "category",
children: {
LIST: {
label: "All Sources",
path: "/catalog",
icon: "list",
},
CREATE: {
label: "Create",
path: "/catalog/create",
icon: "plus",
},
},
},
} satisfies NavigationConfig;MicrofrontendExposes
Type for Module Federation exposes configuration.
type MicrofrontendExposes = {
".": string;
"./navigationConfig": string;
} & Record<string, string>;Shared Dependencies
These dependencies are configured as Module Federation singletons, ensuring one instance across all microfrontends:
| Dependency | Purpose |
| ------------------------------------------- | ----------------------------------------------- |
| react | UI library (singleton) |
| react-dom | React DOM renderer (singleton) |
| react-router | Routing library (singleton) |
| @grasp-labs/ds-microfrontends-integration | Data Platform integration (singleton, optional) |
Singleton configuration prevents version conflicts across microfrontends. Version requirements are defined in this package's peerDependencies - check package.json for current requirements.
Development
# Install dependencies
npm install
# Build the package
npm run build
# Watch mode for development
npm run dev
# Format code
npm run format
# Check formatting
npm run format:checkProject Structure
src/
└── index.ts # Module Federation configuration and type definitionsPublishing
This package is published to npm as @grasp-labs/ds-web-microfrontends-common-lib.
Publishing is done via GitHub Actions workflow (publish.yml):
- Go to Actions → "Version and Publish Package"
- Click "Run workflow"
- Select version type:
patch- Bug fixes (0.1.0 → 0.1.1)minor- New features (0.1.0 → 0.2.0)major- Breaking changes (0.1.0 → 1.0.0)beta- Beta release with timestamp
The workflow automatically:
- Builds the package
- Bumps version and creates git tag (for release versions)
- Publishes to npm registry
Contributing
- Create a feature branch
- Ensure
npm run checkpasses (format, lint, typecheck) - Build successfully with
npm run build - Create a pull request with semantic title (e.g.,
feat:,fix:,chore:)
License
Apache-2.0
