#
Create a local module
Use an existing template
We highly recommend going through the entire getting started guide. However, if you prefer to scaffold the application we'll be building, a template is available with degit:
npx degit https://github.com/gsoft-inc/wl-squide/templates/getting-started
Local modules are regular modules that are part of the host application build. They are independent modules that expose a registration function to the host application's bootstrapping code. A local module can be a standalone package, a sibling project (in a monorepo setup), or even a local folder within the host application.
Local modules have many uses but are especially useful when migrating from a monolithic application to a distributed application or when launching a new product with an unrefined business domain.
Let's add a local module to demonstrate how it's done!
#
Install the packages
Create a new application (we'll refer to ours as local-module), then open a terminal at the root of the new solution and install the following packages:
pnpm add -D @workleap/tsup-configs tsup typescript @types/react @types/react-dom
pnpm add @squide/firefly react react-dom react-router-dom react-error-boundary
yarn add -D @workleap/tsup-configs tsup typescript @types/react @types/react-dom
yarn add @squide/firefly react @squide/firefly react-dom react-router-dom react-error-boundary
npm add -D @workleap/tsup-configs tsup typescript @types/react @types/react-dom
npm install @squide/firefly react react-dom react-router-dom react-error-boundary
While you can use any package manager to develop an application with Squide, it is highly recommend that you use PNPM as the guides has been developed and tested with PNPM.
#
Setup the application
First, create the following files:
local-modules
├── src
├──── register.tsx
├──── Page.tsx
├── tsup.dev.ts
├── tsup.build.ts
├── package.json
Then, ensure that you are developing your module using ESM syntax by specifying type: module in your package.json file:
{
"type": "module"
}
Finally, configure the package to be shareable by adding the name, version, and export fields to the package.json file:
{
"name": "@getting-started/local-module",
"version": "0.0.1",
"exports": {
".": {
"types": "./dist/register.d.ts",
"import": "./dist/register.js",
"default": "./dist/register.js"
}
}
}
#
Routes registration
Next, register the local module routes and navigation items with registerRoute and registerNavigationItem functions:
import type { ModuleRegisterFunction, FireflyRuntime } from "@squide/firefly";
import { Page } from "./Page.tsx";
export const register: ModuleRegisterFunction<FireflyRuntime> = runtime => {
runtime.registerRoute({
path: "/local/page",
element: <Page />
});
runtime.registerNavigationItem({
$label: "Local/Page",
to: "/local/page"
});
}
Then, create the Page component:
export function Page() {
return (
<div>Hello from Local/Page!</div>
);
}
#
Register the local module
Go back to the host application and add a dependency to the @getting-started/local-module package in the host application package.json file:
{
"dependencies": {
"@getting-started/local-module": "0.0.1"
}
}
Then, register the local module with the registerLocalModules function:
import { createRoot } from "react-dom/client";
import { ConsoleLogger, RuntimeContext, FireflyRuntime, registerRemoteModules, registerLocalModules, type RemoteDefinition } from "@squide/firefly";
import { register as registerMyLocalModule } from "@getting-started/local-module";
import { App } from "./App.tsx";
import { registerHost } from "./register.tsx";
// Define the remote modules.
const Remotes: RemoteDefinition[] = [
{ name: "remote1" }
];
// Create the shell runtime.
const runtime = new FireflyRuntime({
loggers: [new ConsoleLogger()]
});
// Register the remote module.
await registerRemoteModules(Remotes, runtime);
// Register the local module.
registerLocalModules([registerHost, registerMyLocalModule], runtime);
const root = createRoot(document.getElementById("root")!);
root.render(
<RuntimeContext.Provider value={runtime}>
<App />
</RuntimeContext.Provider>
);
#
Configure tsup
If you are having issues with the tsup configuration, refer to the @workleap/tsup-configs documentation.
#
Development configuration
To configure tsup for a development environment, open the tsup.dev.ts file and copy/paste the following code:
import { defineDevConfig } from "@workleap/tsup-configs";
export default defineDevConfig();
#
Build configuration
To configure tsup for a build environment, open the tsup.build.ts file and copy/paste the following code:
import { defineBuildConfig } from "@workleap/tsup-configs";
export default defineBuildConfig();
#
Add CLI scripts
To initiate the development server, add the following script to the application package.json file:
{
"dev": "tsup --config ./tsup.dev.ts"
}
To build the module, add the following script to the application package.json file:
{
"build": "tsup --config ./tsup.build.ts"
}
#
Try it 🚀
Start the host, remote-module and local-module applications in development mode using the dev script. You should notice an additional link labelled Local/Page in the navigation menu. Click on the link to navigate to the page of your new local module!
#
Troubleshoot issues
If you are experiencing issues with this guide:
- Open the DevTools console. You'll find a log entry for each registration that occurs and error messages if something went wrong:
[squide] The following route has been registered. Newly registered item: ...[squide] The following navigation item has been registered to the "root" menu for a total of 2 items. Newly registered item: ...
- Refer to a working example on GitHub.
- Refer to the troubleshooting page.