Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(runtime): pass all loader hooks to the fetch and script functions #3174

Merged
merged 3 commits into from
Nov 5, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changeset/lucky-buckets-add.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
'@module-federation/runtime': minor
'@module-federation/sdk': minor
---

pass all loaderHooks to loadEntry and fetch functions instead of just createScript
2 changes: 1 addition & 1 deletion packages/runtime/src/remote/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ export class RemoteHandler {
loadEntry: new AsyncHook<
[
{
createScriptHook: FederationHost['loaderHook']['lifecycle']['createScript'];
loaderHook: FederationHost['loaderHook'];
remoteInfo: RemoteInfo;
remoteEntryExports?: RemoteEntryExports;
},
Expand Down
40 changes: 22 additions & 18 deletions packages/runtime/src/utils/load.ts
Original file line number Diff line number Diff line change
Expand Up @@ -68,12 +68,12 @@ async function loadEntryScript({
name,
globalName,
entry,
createScriptHook,
loaderHook,
}: {
name: string;
globalName: string;
entry: string;
createScriptHook: FederationHost['loaderHook']['lifecycle']['createScript'];
loaderHook: FederationHost['loaderHook'];
}): Promise<RemoteEntryExports> {
const { entryExports: remoteEntryExports } = getRemoteEntryExports(
name,
Expand All @@ -87,7 +87,7 @@ async function loadEntryScript({
return loadScript(entry, {
attrs: {},
createScriptHook: (url, attrs) => {
const res = createScriptHook.emit({ url, attrs });
const res = loaderHook.lifecycle.createScript.emit({ url, attrs });

if (!res) return;

Expand Down Expand Up @@ -127,11 +127,11 @@ async function loadEntryScript({
async function loadEntryDom({
remoteInfo,
remoteEntryExports,
createScriptHook,
loaderHook,
}: {
remoteInfo: RemoteInfo;
remoteEntryExports?: RemoteEntryExports;
createScriptHook: FederationHost['loaderHook']['lifecycle']['createScript'];
loaderHook: FederationHost['loaderHook'];
}) {
const { entry, entryGlobalName: globalName, name, type } = remoteInfo;
switch (type) {
Expand All @@ -141,16 +141,16 @@ async function loadEntryDom({
case 'system':
return loadSystemJsEntry({ entry, remoteEntryExports });
default:
return loadEntryScript({ entry, globalName, name, createScriptHook });
return loadEntryScript({ entry, globalName, name, loaderHook });
}
}

async function loadEntryNode({
remoteInfo,
createScriptHook,
loaderHook,
}: {
remoteInfo: RemoteInfo;
createScriptHook: FederationHost['loaderHook']['lifecycle']['createScript'];
loaderHook: FederationHost['loaderHook'];
}) {
const { entry, entryGlobalName: globalName, name, type } = remoteInfo;
const { entryExports: remoteEntryExports } = getRemoteEntryExports(
Expand All @@ -164,16 +164,18 @@ async function loadEntryNode({

return loadScriptNode(entry, {
attrs: { name, globalName, type },
createScriptHook: (url, attrs) => {
const res = createScriptHook.emit({ url, attrs });
loaderHook: {
createScriptHook: (url: string, attrs: Record<string, any> = {}) => {
const res = loaderHook.lifecycle.createScript.emit({ url, attrs });

if (!res) return;
if (!res) return;

if ('url' in res) {
return res;
}
if ('url' in res) {
return res;
}

return;
return;
},
},
})
.then(() => {
Expand Down Expand Up @@ -220,9 +222,11 @@ export async function getRemoteEntry({
if (!globalLoading[uniqueKey]) {
const loadEntryHook = origin.remoteHandler.hooks.lifecycle.loadEntry;
const createScriptHook = origin.loaderHook.lifecycle.createScript;
const loaderHook = origin.loaderHook;

globalLoading[uniqueKey] = loadEntryHook
.emit({
createScriptHook,
loaderHook,
remoteInfo,
remoteEntryExports,
})
Expand All @@ -231,8 +235,8 @@ export async function getRemoteEntry({
return res;
}
return isBrowserEnv()
? loadEntryDom({ remoteInfo, remoteEntryExports, createScriptHook })
: loadEntryNode({ remoteInfo, createScriptHook });
? loadEntryDom({ remoteInfo, remoteEntryExports, loaderHook })
: loadEntryNode({ remoteInfo, loaderHook });
});
}

Expand Down
40 changes: 16 additions & 24 deletions packages/sdk/src/node.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { CreateScriptHookNode } from './types';
import { CreateScriptHookNode, FetchHook } from './types';

function importNodeModule<T>(name: string): Promise<T> {
if (!name) {
Expand All @@ -22,12 +22,10 @@ const loadNodeFetch = async (): Promise<typeof fetch> => {
const lazyLoaderHookFetch = async (
input: RequestInfo | URL,
init?: RequestInit,
loaderHook?: any,
): Promise<Response> => {
// @ts-ignore
const loaderHooks = __webpack_require__.federation.instance.loaderHook;

const hook = (url: RequestInfo | URL, init: RequestInit) => {
return loaderHooks.lifecycle.fetch.emit(url, init);
return loaderHook.lifecycle.fetch.emit(url, init);
};

const res = await hook(input, init || {});
Expand All @@ -44,10 +42,13 @@ export function createScriptNode(
url: string,
cb: (error?: Error, scriptContext?: any) => void,
attrs?: Record<string, any>,
createScriptHook?: CreateScriptHookNode,
loaderHook?: {
createScriptHook?: CreateScriptHookNode;
fetch?: FetchHook;
},
) {
if (createScriptHook) {
const hookResult = createScriptHook(url);
if (loaderHook?.createScriptHook) {
const hookResult = loaderHook.createScriptHook(url);
if (hookResult && typeof hookResult === 'object' && 'url' in hookResult) {
url = hookResult.url;
}
Expand All @@ -63,20 +64,9 @@ export function createScriptNode(
}

const getFetch = async (): Promise<typeof fetch> => {
//@ts-ignore
if (typeof __webpack_require__ !== 'undefined') {
try {
//@ts-ignore
const loaderHooks = __webpack_require__.federation.instance.loaderHook;
if (loaderHooks.lifecycle.fetch) {
return lazyLoaderHookFetch;
}
} catch (e) {
console.warn(
'federation.instance.loaderHook.lifecycle.fetch failed:',
e,
);
}
if (loaderHook?.fetch) {
return (input: RequestInfo | URL, init?: RequestInit) =>
lazyLoaderHookFetch(input, init, loaderHook);
}

return typeof fetch === 'undefined' ? loadNodeFetch() : fetch;
Expand Down Expand Up @@ -162,7 +152,9 @@ export function loadScriptNode(
url: string,
info: {
attrs?: Record<string, any>;
createScriptHook?: CreateScriptHookNode;
loaderHook?: {
createScriptHook?: CreateScriptHookNode;
};
},
) {
return new Promise<void>((resolve, reject) => {
Expand All @@ -181,7 +173,7 @@ export function loadScriptNode(
}
},
info.attrs,
info.createScriptHook,
info.loaderHook,
);
});
}
Expand Down
4 changes: 4 additions & 0 deletions packages/sdk/src/types/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,7 @@ export type CreateScriptHook = (
url: string,
attrs?: Record<string, any> | undefined,
) => CreateScriptHookReturn;

export type FetchHook = (
args: [string, RequestInit],
) => Promise<Response> | void | false;
Loading