plan/react-rewrite #1

Merged
gnezim merged 138 commits from plan/react-rewrite into main 2026-04-15 12:21:16 +03:00
2 changed files with 131 additions and 0 deletions
Showing only changes of commit 826758f03d - Show all commits
+73
View File
@@ -0,0 +1,73 @@
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
// Mock the runtime package so tests don't need a real remote.
vi.mock("@module-federation/enhanced/runtime", () => {
return {
init: vi.fn(),
loadRemote: vi.fn(),
registerRemotes: vi.fn(),
};
});
import { init, loadRemote, registerRemotes } from "@module-federation/enhanced/runtime";
describe("remote-loader", () => {
beforeEach(async () => {
const mod = await import("./remote-loader.js");
mod.__resetRemoteLoaderForTests();
vi.mocked(init).mockClear();
vi.mocked(loadRemote).mockClear();
vi.mocked(registerRemotes).mockClear();
});
afterEach(() => {
vi.resetModules();
});
it("registerRemote calls init once for the first remote, then registerRemotes for subsequent", async () => {
const { registerRemote } = await import("./remote-loader.js");
registerRemote({ name: "customer-ui", entry: "https://host.example/mf-manifest.json" });
expect(init).toHaveBeenCalledTimes(1);
expect(init).toHaveBeenCalledWith({
name: "aeroflot_flights_host",
remotes: [{ name: "customer-ui", entry: "https://host.example/mf-manifest.json" }],
});
registerRemote({ name: "customer-analytics", entry: "https://host.example/analytics/mf-manifest.json" });
expect(init).toHaveBeenCalledTimes(1); // still only once
expect(registerRemotes).toHaveBeenCalledTimes(1);
expect(registerRemotes).toHaveBeenCalledWith([
{ name: "customer-analytics", entry: "https://host.example/analytics/mf-manifest.json" },
]);
});
it("loadRemoteModule delegates to loadRemote with the concatenated key", async () => {
const fakeModule = { default: "hello" };
vi.mocked(loadRemote).mockResolvedValueOnce(fakeModule);
const { loadRemoteModule } = await import("./remote-loader.js");
const result = await loadRemoteModule<{ default: string }>({
name: "customer-ui",
module: "./Header",
});
expect(loadRemote).toHaveBeenCalledWith("customer-ui/Header");
expect(result).toBe(fakeModule);
});
it("loadRemoteModule rejects with a typed error if the module returns null/undefined", async () => {
vi.mocked(loadRemote).mockResolvedValueOnce(null);
const { loadRemoteModule } = await import("./remote-loader.js");
await expect(
loadRemoteModule({ name: "customer-ui", module: "./NonExistent" }),
).rejects.toThrow(/customer-ui\/NonExistent/);
});
it("loadRemoteModule propagates errors from loadRemote", async () => {
vi.mocked(loadRemote).mockRejectedValueOnce(new Error("boom"));
const { loadRemoteModule } = await import("./remote-loader.js");
await expect(
loadRemoteModule({ name: "customer-ui", module: "./Broken" }),
).rejects.toThrow("boom");
});
});
+58
View File
@@ -0,0 +1,58 @@
import {
init,
loadRemote,
registerRemotes,
} from "@module-federation/enhanced/runtime";
export interface RemoteModuleRef<T = unknown> {
name: string;
module: string;
/** Phantom marker to preserve the generic parameter through the type system. */
readonly __type?: T;
}
export interface RemoteEntry {
name: string;
entry: string;
}
let initialized = false;
const HOST_NAME = "aeroflot_flights_host" as const;
/**
* Registers a remote with the MF runtime. On the first call, this also calls
* `init()` to bootstrap the MF runtime with the host identity. Subsequent
* calls use `registerRemotes()` to add remotes without re-initializing.
*/
export function registerRemote(entry: RemoteEntry): void {
if (!initialized) {
init({
name: HOST_NAME,
remotes: [entry],
});
initialized = true;
return;
}
registerRemotes([entry]);
}
/**
* Loads an exposed module from a previously registered remote. The `name` +
* `module` fields are concatenated into MF's `remote/module` lookup key.
*
* Throws if the runtime returns a null/undefined module, which usually means
* the remote manifest does not actually expose the requested path.
*/
export async function loadRemoteModule<T>(ref: RemoteModuleRef<T>): Promise<T> {
const key = `${ref.name}/${ref.module.replace(/^\.\//, "")}`;
const result = await loadRemote<T>(key);
if (result === null || result === undefined) {
throw new Error(`Remote module ${key} loaded as null/undefined`);
}
return result;
}
/** Test-only: resets the one-shot init flag. */
export function __resetRemoteLoaderForTests(): void {
initialized = false;
}