Skip to content

docs: add createLink hook desc and faq #3785

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

Merged
merged 1 commit into from
May 16, 2025
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
8 changes: 8 additions & 0 deletions apps/manifest-demo/webpack-host/runtimePlugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,13 @@ export default function (): FederationRuntimePlugin {

return args;
},
createLink({ url }) {
const link = document.createElement('link');
link.setAttribute('href', url);
link.setAttribute('rel', 'preload');
link.setAttribute('as', 'script');
link.setAttribute('crossorigin', 'anonymous');
return link;
},
};
}
30 changes: 30 additions & 0 deletions apps/website-new/docs/en/guide/troubleshooting/other.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -90,3 +90,33 @@ When `exposes` is set in the project, it will be regarded as a producer. To ensu
* [Modern.js]: Set [devServer.headers](https://modernjs.dev/configure/app/tools/dev-server.html#headers) value to the specified domain whitelist instead of `*`

* [Rsbuild]: Set [server.cors.origin](https://rsbuild.dev/config/server/cors#origin) value to the specified domain whitelist instead of `*`

## A preload for 'http://resource-url' is found, but is not used because the request credentials mode does not match. Consider taking a look at crossorigin attribute.

### Reason

When the producer URL is a manifest, loading this producer module will automatically preload the corresponding resources. If the above warning occurs, it is because the default preload does not configure credentials, while the actual `load remote script` carries the corresponding credentials, causing the preload to fail.

### Solution

Add a runtime plugin via [runtimePlugins](../../configure/runtimeplugins) and configure the `crossorigin` attribute in the [createLink](../../plugin/dev/index#createlink) hook. Its value needs to be consistent with the actual `load script`.

For example, to modify the crossorigin attribute of the preloaded link to `anonymous`:

```ts title="runtimePlugin.ts
import { FederationRuntimePlugin } from '@module-federation/runtime/types';

export default function MFLinkPlugin(): FederationRuntimePlugin {
return {
name: 'link-plugin',
createLink({ url }) {
const link = document.createElement('link');
link.setAttribute('href', url);
link.setAttribute('rel', 'preload');
link.setAttribute('as', 'script');
link.setAttribute('crossorigin', 'anonymous');
return link
}
};
}
```
36 changes: 36 additions & 0 deletions apps/website-new/docs/en/plugin/dev/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -534,6 +534,42 @@ const changeScriptAttributePlugin: () => FederationRuntimePlugin = function () {
};
```


### createLink

`SyncHook`

- **Type**

```typescript
function createLink(args: CreateLinkOptions): HTMLLinkElement | void;

type CreateScriptOptions = {
url: string;
attrs?: Record<string, any>;
};
```

- Example

```typescript
import { init } from '@module-federation/enhanced/runtime';
import type { FederationRuntimePlugin } from '@module-federation/enhanced/runtime';

const changeLinkAttributePlugin: () => FederationRuntimePlugin = function () {
return {
name: 'change-link-attribute',
createLink({ url }) {
link.setAttribute('href', url);
link.setAttribute('rel', 'preload');
link.setAttribute('as', 'script');
link.setAttribute('crossorigin', 'anonymous');
return link;
},
};
};
```

### fetch
The `fetch` function allows customizing the request that fetches the manifest JSON. A successful `Response` must yield a valid JSON.

Expand Down
30 changes: 30 additions & 0 deletions apps/website-new/docs/zh/guide/troubleshooting/other.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -64,3 +64,33 @@ Uncaught TypeError: Cannot read properties on null (reading `useState`)
* [Modern.js]: 设置 [devServer.headers](https://modernjs.dev/configure/app/tools/dev-server.html#headers) 值为指定的域名白名单而非 `*`

* [Rsbuild]: 设置 [server.cors.origin](https://rsbuild.dev/config/server/cors#origin) 值为指定的域名白名单而非 `*`

## A preload for 'http://resource-url' is found, but is not used because the request credentials mode does not match. Consider taking a look at crossorigin attribute.

### 原因

当生产者 url 为 manifest 时,加载此生产者模块会自动预加载相应的资源。如果出现上述警告,是因为默认预加载不会配置 credentials ,而实际的 load remote script 携带了对应的 credentials ,导致预加载失败。

### 解决方案

通过 [runtimePlugins](../../configure/runtimeplugins) 添加运行时插件,在 [createLink](../../plugin/dev/index#createlink) hook 中配置 `crossorigin` 属性,其值需要和实际 load script 保持一致。

例如需要修改预加载 link 的 crossorigin 属性为 `anonymous`:

```ts title="runtimePlugin.ts
import { FederationRuntimePlugin } from '@module-federation/runtime/types';

export default function MFLinkPlugin(): FederationRuntimePlugin {
return {
name: 'link-plugin',
createLink({ url }) {
const link = document.createElement('link');
link.setAttribute('href', url);
link.setAttribute('rel', 'preload');
link.setAttribute('as', 'script');
link.setAttribute('crossorigin', 'anonymous');
return link
}
};
}
```
67 changes: 67 additions & 0 deletions apps/website-new/docs/zh/plugin/dev/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -532,6 +532,73 @@ const changeScriptAttributePlugin: () => FederationRuntimePlugin = function () {
};
```


### createLink

`SyncHook`

- 类型

```typescript
function createLink(args: CreateLinkOptions): HTMLLinkElement | void;

type CreateScriptOptions = {
url: string;
attrs?: Record<string, any>;
};
```

- 示例

```typescript
import { init } from '@module-federation/enhanced/runtime';
import type { FederationRuntimePlugin } from '@module-federation/enhanced/runtime';

const changeLinkAttributePlugin: () => FederationRuntimePlugin = function () {
return {
name: 'change-link-attribute',
createLink({ url }) {
link.setAttribute('href', url);
link.setAttribute('rel', 'preload');
link.setAttribute('as', 'script');
link.setAttribute('crossorigin', 'anonymous');
return link;
},
};
};
```

### fetch

`fetch` 函数用于自定义获取 Manifest 的请求。

`AsyncHook`

- **类型**

```typescript
function fetch(manifestUrl: string, requestInit: RequestInit): Promise<Response> | void | false;
```

- 示例:获取 manifest 时增加 credentials:

```typescript
// fetch-manifest-with-credentials-plugin.ts
import type { FederationRuntimePlugin } from '@module-federation/enhanced/runtime';

export default function (): FederationRuntimePlugin {
return {
name: 'fetch-manifest-with-credentials-plugin',
fetch(manifestUrl, requestInit) {
return fetch(manifestUrl, {
...requestInit,
credentials: 'include'
});
},
}
};
```

### loadEntry
可以完全自定义remote, 可以扩展新的remote类型。
下面两个简单的例子分别实现了加载json数据和模块代理
Expand Down