remote-components 0.0.21 → 0.0.23
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/html/host.cjs +115 -40
- package/dist/html/host.cjs.map +1 -1
- package/dist/html/host.js +115 -40
- package/dist/html/host.js.map +1 -1
- package/dist/internal/next/host/app-router-client.cjs +72 -23
- package/dist/internal/next/host/app-router-client.cjs.map +1 -1
- package/dist/internal/next/host/app-router-client.d.ts +2 -2
- package/dist/internal/next/host/app-router-client.js +73 -24
- package/dist/internal/next/host/app-router-client.js.map +1 -1
- package/dist/internal/shared/client/remote-component.cjs +43 -16
- package/dist/internal/shared/client/remote-component.cjs.map +1 -1
- package/dist/internal/shared/client/remote-component.d.ts +2 -0
- package/dist/internal/shared/client/remote-component.js +43 -16
- package/dist/internal/shared/client/remote-component.js.map +1 -1
- package/dist/internal/shared/ssr/dom-flight.cjs +9 -17
- package/dist/internal/shared/ssr/dom-flight.cjs.map +1 -1
- package/dist/internal/shared/ssr/dom-flight.js +9 -17
- package/dist/internal/shared/ssr/dom-flight.js.map +1 -1
- package/dist/internal/shared/ssr/fetch-remote-component.cjs +3 -4
- package/dist/internal/shared/ssr/fetch-remote-component.cjs.map +1 -1
- package/dist/internal/shared/ssr/fetch-remote-component.js +3 -4
- package/dist/internal/shared/ssr/fetch-remote-component.js.map +1 -1
- package/dist/internal/webpack/next-client-pages-loader.cjs +43 -16
- package/dist/internal/webpack/next-client-pages-loader.cjs.map +1 -1
- package/dist/internal/webpack/next-client-pages-loader.js +43 -16
- package/dist/internal/webpack/next-client-pages-loader.js.map +1 -1
- package/dist/next/host/app-router-server.cjs +4 -0
- package/dist/next/host/app-router-server.cjs.map +1 -1
- package/dist/next/host/app-router-server.d.ts +5 -1
- package/dist/next/host/app-router-server.js +4 -0
- package/dist/next/host/app-router-server.js.map +1 -1
- package/dist/next/host/client/index.d.ts +1 -1
- package/dist/next/host/pages-router-server.cjs +11 -4
- package/dist/next/host/pages-router-server.cjs.map +1 -1
- package/dist/next/host/pages-router-server.d.ts +3 -0
- package/dist/next/host/pages-router-server.js +11 -4
- package/dist/next/host/pages-router-server.js.map +1 -1
- package/dist/next/middleware.cjs +1 -1
- package/dist/next/middleware.cjs.map +1 -1
- package/dist/next/middleware.js +1 -1
- package/dist/next/middleware.js.map +1 -1
- package/dist/react/index.cjs +56 -19
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.d.ts +6 -2
- package/dist/react/index.js +56 -19
- package/dist/react/index.js.map +1 -1
- package/dist/{types-7425dfe1.d.ts → types-b8210fd3.d.ts} +2 -0
- package/package.json +1 -1
|
@@ -24,9 +24,7 @@ async function fetchRemoteComponent(src, headers = new Headers(), options = {
|
|
|
24
24
|
headers: {
|
|
25
25
|
// pass all headers to the remote component
|
|
26
26
|
...Object.fromEntries(headers.entries()),
|
|
27
|
-
Accept: "text/html"
|
|
28
|
-
// pass the public address of the remote component to the server used for module map mutation
|
|
29
|
-
"Vercel-Remote-Component-Url": url.href
|
|
27
|
+
Accept: "text/html"
|
|
30
28
|
},
|
|
31
29
|
credentials: "include"
|
|
32
30
|
};
|
|
@@ -57,9 +55,10 @@ async function fetchRemoteComponent(src, headers = new Headers(), options = {
|
|
|
57
55
|
const hydrationData = [];
|
|
58
56
|
let nextData;
|
|
59
57
|
let html = "";
|
|
58
|
+
const remoteName = options.name || url.hash ? url.hash.substring(1) : void 0;
|
|
60
59
|
const rsc = visit(fragment, {
|
|
61
60
|
url,
|
|
62
|
-
name:
|
|
61
|
+
name: remoteName,
|
|
63
62
|
onMetadata(_metadata) {
|
|
64
63
|
metadata = _metadata;
|
|
65
64
|
},
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/shared/ssr/fetch-remote-component.ts"],"sourcesContent":["import { type DefaultTreeAdapterMap, Parser } from 'parse5';\nimport { visit } from '#internal/shared/ssr/dom-flight';\nimport type { RemoteComponentMetadata } from './types';\n\nconst CURRENT_ZONE = process.env.NEXT_PUBLIC_MFE_CURRENT_APPLICATION;\n\n/**\n * Resolves the base URL that should be used to fetch the remote component.\n * This function must support local development, Vercel environments, and SSG\n * and dynamic rendering.\n */\nexport function getBaseUrl(reqHeaders: Headers): string {\n const host = reqHeaders.get('host');\n if (host) {\n return host.startsWith('localhost') ? `http://${host}` : `https://${host}`;\n }\n const forwardedHost = reqHeaders.get('x-forwarded-host');\n if (forwardedHost) {\n return `https://${forwardedHost}`;\n }\n if (process.env.VERCEL_PROJECT_PRODUCTION_URL) {\n return `https://${process.env.VERCEL_PROJECT_PRODUCTION_URL}`;\n }\n // TODO: Resolve the correct URL in local development when the proxy is not running.\n return `http://localhost:${process.env.MFE_LOCAL_PROXY_PORT || 3024}`;\n}\n\nexport async function fetchRemoteComponent(\n src: string | URL,\n headers: Headers = new Headers(),\n options: {\n name?: string;\n rsc?: boolean;\n } = {\n rsc: false,\n },\n) {\n const url = new URL(src, getBaseUrl(headers));\n\n const fetchInit = {\n method: 'GET',\n headers: {\n // pass all headers to the remote component\n ...Object.fromEntries(headers.entries()),\n Accept: 'text/html',\n
|
|
1
|
+
{"version":3,"sources":["../../../../src/shared/ssr/fetch-remote-component.ts"],"sourcesContent":["import { type DefaultTreeAdapterMap, Parser } from 'parse5';\nimport { visit } from '#internal/shared/ssr/dom-flight';\nimport type { RemoteComponentMetadata } from './types';\n\nconst CURRENT_ZONE = process.env.NEXT_PUBLIC_MFE_CURRENT_APPLICATION;\n\n/**\n * Resolves the base URL that should be used to fetch the remote component.\n * This function must support local development, Vercel environments, and SSG\n * and dynamic rendering.\n */\nexport function getBaseUrl(reqHeaders: Headers): string {\n const host = reqHeaders.get('host');\n if (host) {\n return host.startsWith('localhost') ? `http://${host}` : `https://${host}`;\n }\n const forwardedHost = reqHeaders.get('x-forwarded-host');\n if (forwardedHost) {\n return `https://${forwardedHost}`;\n }\n if (process.env.VERCEL_PROJECT_PRODUCTION_URL) {\n return `https://${process.env.VERCEL_PROJECT_PRODUCTION_URL}`;\n }\n // TODO: Resolve the correct URL in local development when the proxy is not running.\n return `http://localhost:${process.env.MFE_LOCAL_PROXY_PORT || 3024}`;\n}\n\nexport async function fetchRemoteComponent(\n src: string | URL,\n headers: Headers = new Headers(),\n options: {\n name?: string;\n rsc?: boolean;\n } = {\n rsc: false,\n },\n) {\n const url = new URL(src, getBaseUrl(headers));\n\n const fetchInit = {\n method: 'GET',\n headers: {\n // pass all headers to the remote component\n ...Object.fromEntries(headers.entries()),\n Accept: 'text/html',\n },\n credentials: 'include',\n } as RequestInit;\n\n const res = await fetch(url, fetchInit);\n\n if (!res.ok) {\n throw new Error(\n `Failed to fetch remote component \"${url.href}\": ${res.status}`,\n );\n }\n\n // create a parser for the HTML response\n const parser = Parser.getFragmentParser<DefaultTreeAdapterMap>();\n\n if (!res.body) {\n throw new Error(`No response body for remote component \"${url.href}\"`);\n }\n\n const decoder = new TextDecoder();\n // read the response body as a stream and parse it using the parse5 fragment parser\n for await (const chunk of res.body as unknown as AsyncIterable<Uint8Array>) {\n parser.tokenizer.write(decoder.decode(chunk), false);\n }\n const fragment = parser.getFragment();\n\n let metadata: RemoteComponentMetadata = {\n bundle: CURRENT_ZONE ?? '__vercel_remote_component',\n route: '/',\n runtime: 'webpack',\n id: '__vercel_remote_component',\n };\n let remoteShared: Record<string, string> = {};\n const scripts: { src: string }[] = [];\n const links: Record<string, string | boolean>[] = [];\n const hydrationData: string[] = [];\n let nextData:\n | {\n props: { pageProps: Record<string, unknown> };\n buildId?: string;\n }\n | undefined;\n let html = '';\n\n const remoteName =\n options.name || url.hash ? url.hash.substring(1) : undefined;\n // convert the parsed HTML fragment into an RSC flight data\n // and extract the metadata, scripts, links and remote component RSC flight data\n const rsc = visit(fragment, {\n url,\n name: remoteName,\n onMetadata(_metadata) {\n metadata = _metadata;\n },\n onScript(attrs) {\n if (!scripts.find((it) => it.src === attrs.src)) {\n scripts.push({\n src: new URL(attrs.src as string, new URL(url).origin).href,\n });\n }\n },\n onLink(attrs) {\n const relativeAttrs = {\n ...attrs,\n href: new URL(attrs.href as string, new URL(url).origin).href,\n };\n if (\n !links.find(\n (it) => it.href === relativeAttrs.href && it.rel === attrs.rel,\n )\n ) {\n links.push(relativeAttrs);\n }\n },\n onRSC(chunk) {\n hydrationData.push(chunk);\n },\n onNextData(data) {\n nextData = data;\n\n // use the Next.js Pages Router props data to extract remote component metadata\n if (data.props.__REMOTE_COMPONENT__) {\n Object.assign(metadata, data.props.__REMOTE_COMPONENT__);\n // only a singleton remote component is supported per page when using the Next.js Pages Router\n metadata.id = '__next';\n metadata.route = data.page ?? '/';\n }\n },\n onHTML(_html) {\n if (!html.includes(_html)) {\n html += _html;\n }\n },\n onShared(_shared) {\n remoteShared = _shared;\n },\n });\n\n let component: React.ReactNode | undefined;\n\n // only create a React component if requested\n if (options.rsc) {\n // RSC flight data for the static HTML in a single RSC line\n const componentRSC = `0:${JSON.stringify(rsc)}\\n`;\n\n const { createFromReadableStream } = await import(\n 'next/dist/compiled/react-server-dom-webpack/client.edge'\n );\n\n // create a React tree from the RSC flight data\n component = await createFromReadableStream(\n new ReadableStream({\n type: 'bytes',\n start(controller) {\n const encoder = new TextEncoder();\n controller.enqueue(encoder.encode(componentRSC));\n controller.close();\n },\n }),\n {\n serverConsumerManifest: {\n moduleLoading: {\n prefix: url.origin,\n crossOrigin: true,\n },\n moduleMap: {},\n },\n },\n );\n }\n\n const name = metadata.id.replace(/_ssr$/, '');\n return {\n name,\n url,\n metadata,\n rsc,\n scripts,\n links,\n hydrationData,\n nextData,\n component,\n html,\n remoteShared,\n };\n}\n"],"mappings":"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","names":[]}
|
|
@@ -23,20 +23,28 @@ __export(next_client_pages_loader_exports, {
|
|
|
23
23
|
module.exports = __toCommonJS(next_client_pages_loader_exports);
|
|
24
24
|
function nextClientPagesLoader(bundle, route, styleContainer = document.head) {
|
|
25
25
|
const self = globalThis;
|
|
26
|
-
const nextCssOriginal = document.
|
|
26
|
+
const nextCssOriginal = document.querySelector(
|
|
27
|
+
`[id="__next_css__DO_NOT_USE__"]:not([data-bundle="${bundle}"][data-route="${route}"])`
|
|
28
|
+
);
|
|
27
29
|
if (nextCssOriginal) {
|
|
28
30
|
nextCssOriginal.parentNode?.removeChild(nextCssOriginal);
|
|
29
31
|
}
|
|
30
32
|
const nextCss = document.createElement("noscript");
|
|
31
33
|
nextCss.id = "__next_css__DO_NOT_USE__";
|
|
32
|
-
|
|
34
|
+
nextCss.setAttribute("data-bundle", bundle);
|
|
35
|
+
nextCss.setAttribute("data-route", route);
|
|
36
|
+
const nextCssEnd = document.createElement("noscript");
|
|
37
|
+
nextCssEnd.id = "__next_css__DO_NOT_USE_END__";
|
|
38
|
+
nextCssEnd.setAttribute("data-bundle", bundle);
|
|
39
|
+
nextCssEnd.setAttribute("data-route", route);
|
|
40
|
+
document.head.appendChild(nextCssEnd);
|
|
33
41
|
document.head.appendChild(nextCss);
|
|
34
42
|
const componentLoaderChunk = Object.keys(self.__remote_webpack_require__?.[bundle]?.m ?? {}).find(
|
|
35
|
-
(key) => key.includes("/webpack/loaders/next-client-pages-loader.js") && key.includes(`page=${encodeURIComponent(route)}
|
|
43
|
+
(key) => key.includes("/webpack/loaders/next-client-pages-loader.js") && key.includes(`page=${encodeURIComponent(route)}!`)
|
|
36
44
|
) ?? Object.keys(self.__remote_webpack_require__?.[bundle]?.m ?? {}).find(
|
|
37
45
|
(key) => key.includes("/next/dist/client/page-loader.js")
|
|
38
46
|
) ?? self.__remote_webpack_module_map__?.[bundle]?.[Object.keys(self.__remote_webpack_module_map__[bundle] ?? {}).find(
|
|
39
|
-
(key) => key.includes("/webpack/loaders/next-client-pages-loader.js") && key.includes(`page=${encodeURIComponent(route)}
|
|
47
|
+
(key) => key.includes("/webpack/loaders/next-client-pages-loader.js") && key.includes(`page=${encodeURIComponent(route)}!`)
|
|
40
48
|
) ?? Object.keys(self.__remote_webpack_module_map__[bundle] ?? {}).find(
|
|
41
49
|
(key) => key.includes("/next/dist/client/page-loader.js")
|
|
42
50
|
) ?? ""] ?? -1;
|
|
@@ -78,28 +86,47 @@ function nextClientPagesLoader(bundle, route, styleContainer = document.head) {
|
|
|
78
86
|
];
|
|
79
87
|
const { default: Component } = componentLoader();
|
|
80
88
|
const { default: App } = appLoader();
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
if (id) {
|
|
89
|
+
if (!self.__remote_next_css__) {
|
|
90
|
+
self.__remote_next_css__ = {};
|
|
91
|
+
}
|
|
92
|
+
if (!self.__remote_next_css__[bundle]) {
|
|
93
|
+
const cssRE = /\.s?css$/;
|
|
94
|
+
Object.keys(self.__remote_webpack_require__?.[bundle]?.m ?? {}).filter((id) => cssRE.test(id)).forEach((id) => {
|
|
88
95
|
self.__remote_webpack_require__?.[bundle]?.(id);
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
|
|
96
|
+
});
|
|
97
|
+
Object.keys(self.__remote_webpack_module_map__?.[bundle] ?? {}).filter((path) => cssRE.test(path)).forEach((path) => {
|
|
98
|
+
const id = self.__remote_webpack_module_map__?.[bundle]?.[path];
|
|
99
|
+
if (id) {
|
|
100
|
+
self.__remote_webpack_require__?.[bundle]?.(id);
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
const elements = [];
|
|
92
104
|
let node = nextCss.previousSibling;
|
|
93
|
-
while (node && node !==
|
|
94
|
-
|
|
105
|
+
while (node && node !== nextCssEnd) {
|
|
106
|
+
elements.push(node);
|
|
107
|
+
node.remove();
|
|
95
108
|
node = nextCss.previousSibling;
|
|
96
109
|
}
|
|
110
|
+
self.__remote_next_css__[bundle] = elements;
|
|
111
|
+
}
|
|
112
|
+
if (styleContainer) {
|
|
113
|
+
const elements = self.__remote_next_css__[bundle];
|
|
114
|
+
elements.forEach((el) => {
|
|
115
|
+
styleContainer.appendChild(el.cloneNode(true));
|
|
116
|
+
});
|
|
117
|
+
} else {
|
|
118
|
+
const elements = self.__remote_next_css__[bundle];
|
|
119
|
+
elements.forEach((el) => {
|
|
120
|
+
document.head.appendChild(el);
|
|
121
|
+
});
|
|
97
122
|
}
|
|
98
123
|
delete self.__NEXT_P;
|
|
99
124
|
self.__NEXT_P = __NEXT_P_ORIGINAL;
|
|
100
125
|
if (nextCssOriginal) {
|
|
101
126
|
nextCssOriginal.parentNode?.appendChild(nextCssOriginal);
|
|
102
127
|
}
|
|
128
|
+
nextCss.remove();
|
|
129
|
+
nextCssEnd.remove();
|
|
103
130
|
return { Component, App };
|
|
104
131
|
}
|
|
105
132
|
return { Component: null, App: null };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/shared/webpack/next-client-pages-loader.ts"],"sourcesContent":["// module loader for Next.js Pages Router\nexport function nextClientPagesLoader(\n bundle: string,\n route: string,\n styleContainer: HTMLHeadElement | ShadowRoot | null = document.head,\n) {\n // make a typed reference to the global scope\n const self = globalThis as typeof globalThis & {\n // webpack remote module loading function scoped for each bundle\n __remote_webpack_require__?: Record<\n string,\n ((remoteId: string | number) => unknown) & {\n c?: Record<\n string | number,\n { id: string; parents: string[]; children: string[] }\n >;\n m?: Record<string | number, (module: { exports: unknown }) => void>;\n type?: 'turbopack' | 'webpack';\n }\n >;\n // webpack module map for each bundle used in production builds\n __remote_webpack_module_map__?: Record<string, Record<string, number>>;\n // Next.js client pages loader reference storage\n __NEXT_P?: [\n (\n | [\n string,\n () => { default?: React.ComponentType<Record<string, unknown>> },\n ]\n | undefined\n ),\n (\n | [\n string,\n () => {\n default?: React.ComponentType<\n {\n Component: React.ComponentType<Record<string, unknown>>;\n } & Record<string, unknown>\n >;\n },\n ]\n | undefined\n ),\n (\n | [\n string,\n () => {\n default?: React.ComponentType<\n {\n Component: React.ComponentType<Record<string, unknown>>;\n } & Record<string, unknown>\n >;\n },\n ]\n | undefined\n ),\n ];\n };\n\n // temporarily remove the original Next.js CSS loader\n const nextCssOriginal = document.getElementById('__next_css__DO_NOT_USE__');\n if (nextCssOriginal) {\n nextCssOriginal.parentNode?.removeChild(nextCssOriginal);\n }\n\n // create a new Next.js CSS loader element\n const nextCss = document.createElement('noscript');\n nextCss.id = '__next_css__DO_NOT_USE__';\n const lastNode =\n document.head.childNodes[document.head.childNodes.length - 1];\n document.head.appendChild(nextCss);\n\n // find the page component loader chunk\n const componentLoaderChunk =\n Object.keys(self.__remote_webpack_require__?.[bundle]?.m ?? {}).find(\n (key) =>\n key.includes('/webpack/loaders/next-client-pages-loader.js') &&\n key.includes(`page=${encodeURIComponent(route)}`),\n ) ??\n Object.keys(self.__remote_webpack_require__?.[bundle]?.m ?? {}).find(\n (key) => key.includes('/next/dist/client/page-loader.js'),\n ) ??\n self.__remote_webpack_module_map__?.[bundle]?.[\n Object.keys(self.__remote_webpack_module_map__[bundle] ?? {}).find(\n (key) =>\n key.includes('/webpack/loaders/next-client-pages-loader.js') &&\n key.includes(`page=${encodeURIComponent(route)}`),\n ) ??\n Object.keys(self.__remote_webpack_module_map__[bundle] ?? {}).find(\n (key) => key.includes('/next/dist/client/page-loader.js'),\n ) ??\n ''\n ] ??\n -1;\n\n // find the app loader chunk\n const appLoaderChunk =\n Object.keys(self.__remote_webpack_require__?.[bundle]?.m ?? {}).find(\n (key) =>\n key.includes('/webpack/loaders/next-client-pages-loader.js') &&\n key.includes(`page=%2F_app`),\n ) ??\n Object.keys(self.__remote_webpack_require__?.[bundle]?.m ?? {}).find(\n (key) => key.includes('/next/dist/client/page-loader.js'),\n ) ??\n self.__remote_webpack_module_map__?.[bundle]?.[\n Object.keys(self.__remote_webpack_module_map__[bundle] ?? {}).find(\n (key) =>\n key.includes('/webpack/loaders/next-client-pages-loader.js') &&\n key.includes(`page=%2F_app`),\n ) ??\n Object.keys(self.__remote_webpack_module_map__[bundle] ?? {}).find(\n (key) => key.includes('/next/dist/client/page-loader.js'),\n ) ??\n ''\n ] ??\n -1;\n\n // if we didn't find the component loader or app loader, throw an error\n if (!(componentLoaderChunk && appLoaderChunk)) {\n throw new Error(\n `Next.js client pages loader not found in bundle \"${bundle}\"`,\n );\n }\n\n // temporarily store the original __NEXT_P reference\n // this is required to avoid conflicts with the Next.js client pages loader\n // which uses the same global variable to store the page components\n const __NEXT_P_ORIGINAL = self.__NEXT_P;\n const selfOriginal = self;\n delete selfOriginal.__NEXT_P;\n\n // load the component and app loader chunks\n self.__remote_webpack_require__?.[bundle]?.(\n self.__remote_webpack_require__[bundle].type !== 'turbopack'\n ? componentLoaderChunk\n : `[${bundle}] ${componentLoaderChunk}`,\n );\n if (\n typeof appLoaderChunk === 'string' ||\n (typeof appLoaderChunk === 'number' && appLoaderChunk !== -1)\n ) {\n self.__remote_webpack_require__?.[bundle]?.(\n self.__remote_webpack_require__[bundle].type !== 'turbopack'\n ? appLoaderChunk\n : `[${bundle}] ${appLoaderChunk}`,\n );\n }\n\n // if we have the __NEXT_P global variable, we can extract the component and app\n if (self.__NEXT_P) {\n const [, componentLoader] = self.__NEXT_P[0] ?? [\n undefined,\n () => ({ default: null }),\n ];\n const [, appLoader] = self.__NEXT_P[2] ?? [\n undefined,\n () => ({\n default: null,\n }),\n ];\n const { default: Component } = componentLoader();\n const { default: App } = appLoader();\n\n // load the CSS files from the remote bundle\n const cssRE = /\\.s?css$/;\n Object.keys(self.__remote_webpack_require__?.[bundle]?.m ?? {})\n .filter((id) => cssRE.test(id))\n .forEach((id) => {\n self.__remote_webpack_require__?.[bundle]?.(id);\n });\n\n Object.keys(self.__remote_webpack_module_map__?.[bundle] ?? {})\n .filter((path) => cssRE.test(path))\n .forEach((path) => {\n const id = self.__remote_webpack_module_map__?.[bundle]?.[path];\n if (id) {\n self.__remote_webpack_require__?.[bundle]?.(id);\n }\n });\n\n // if the styleContainer is provided, we need to move the styles to it\n if (styleContainer) {\n let node = nextCss.previousSibling;\n while (node && node !== lastNode) {\n styleContainer.appendChild(node);\n node = nextCss.previousSibling;\n }\n }\n\n // restore the original __NEXT_P reference\n delete self.__NEXT_P;\n self.__NEXT_P = __NEXT_P_ORIGINAL;\n\n // restore the original Next.js CSS loader\n if (nextCssOriginal) {\n nextCssOriginal.parentNode?.appendChild(nextCssOriginal);\n }\n\n return { Component, App };\n }\n\n return { Component: null, App: null };\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../src/shared/webpack/next-client-pages-loader.ts"],"sourcesContent":["// module loader for Next.js Pages Router\nexport function nextClientPagesLoader(\n bundle: string,\n route: string,\n styleContainer: HTMLHeadElement | ShadowRoot | null = document.head,\n) {\n // make a typed reference to the global scope\n const self = globalThis as typeof globalThis & {\n // webpack remote module loading function scoped for each bundle\n __remote_webpack_require__?: Record<\n string,\n ((remoteId: string | number) => unknown) & {\n c?: Record<\n string | number,\n { id: string; parents: string[]; children: string[] }\n >;\n m?: Record<string | number, (module: { exports: unknown }) => void>;\n type?: 'turbopack' | 'webpack';\n }\n >;\n // webpack module map for each bundle used in production builds\n __remote_webpack_module_map__?: Record<string, Record<string, number>>;\n // Next.js client pages loader reference storage\n __NEXT_P?: [\n (\n | [\n string,\n () => { default?: React.ComponentType<Record<string, unknown>> },\n ]\n | undefined\n ),\n (\n | [\n string,\n () => {\n default?: React.ComponentType<\n {\n Component: React.ComponentType<Record<string, unknown>>;\n } & Record<string, unknown>\n >;\n },\n ]\n | undefined\n ),\n (\n | [\n string,\n () => {\n default?: React.ComponentType<\n {\n Component: React.ComponentType<Record<string, unknown>>;\n } & Record<string, unknown>\n >;\n },\n ]\n | undefined\n ),\n ];\n // Next.js Pages Router CSS cache\n __remote_next_css__?: Record<string, ChildNode[]>;\n };\n\n // temporarily remove the original Next.js CSS loader\n const nextCssOriginal = document.querySelector(\n `[id=\"__next_css__DO_NOT_USE__\"]:not([data-bundle=\"${bundle}\"][data-route=\"${route}\"])`,\n );\n if (nextCssOriginal) {\n nextCssOriginal.parentNode?.removeChild(nextCssOriginal);\n }\n\n // create a new Next.js CSS loader element\n const nextCss = document.createElement('noscript');\n nextCss.id = '__next_css__DO_NOT_USE__';\n nextCss.setAttribute('data-bundle', bundle);\n nextCss.setAttribute('data-route', route);\n const nextCssEnd = document.createElement('noscript');\n nextCssEnd.id = '__next_css__DO_NOT_USE_END__';\n nextCssEnd.setAttribute('data-bundle', bundle);\n nextCssEnd.setAttribute('data-route', route);\n document.head.appendChild(nextCssEnd);\n document.head.appendChild(nextCss);\n\n // find the page component loader chunk\n const componentLoaderChunk =\n Object.keys(self.__remote_webpack_require__?.[bundle]?.m ?? {}).find(\n (key) =>\n key.includes('/webpack/loaders/next-client-pages-loader.js') &&\n key.includes(`page=${encodeURIComponent(route)}!`),\n ) ??\n Object.keys(self.__remote_webpack_require__?.[bundle]?.m ?? {}).find(\n (key) => key.includes('/next/dist/client/page-loader.js'),\n ) ??\n self.__remote_webpack_module_map__?.[bundle]?.[\n Object.keys(self.__remote_webpack_module_map__[bundle] ?? {}).find(\n (key) =>\n key.includes('/webpack/loaders/next-client-pages-loader.js') &&\n key.includes(`page=${encodeURIComponent(route)}!`),\n ) ??\n Object.keys(self.__remote_webpack_module_map__[bundle] ?? {}).find(\n (key) => key.includes('/next/dist/client/page-loader.js'),\n ) ??\n ''\n ] ??\n -1;\n\n // find the app loader chunk\n const appLoaderChunk =\n Object.keys(self.__remote_webpack_require__?.[bundle]?.m ?? {}).find(\n (key) =>\n key.includes('/webpack/loaders/next-client-pages-loader.js') &&\n key.includes(`page=%2F_app`),\n ) ??\n Object.keys(self.__remote_webpack_require__?.[bundle]?.m ?? {}).find(\n (key) => key.includes('/next/dist/client/page-loader.js'),\n ) ??\n self.__remote_webpack_module_map__?.[bundle]?.[\n Object.keys(self.__remote_webpack_module_map__[bundle] ?? {}).find(\n (key) =>\n key.includes('/webpack/loaders/next-client-pages-loader.js') &&\n key.includes(`page=%2F_app`),\n ) ??\n Object.keys(self.__remote_webpack_module_map__[bundle] ?? {}).find(\n (key) => key.includes('/next/dist/client/page-loader.js'),\n ) ??\n ''\n ] ??\n -1;\n\n // if we didn't find the component loader or app loader, throw an error\n if (!(componentLoaderChunk && appLoaderChunk)) {\n throw new Error(\n `Next.js client pages loader not found in bundle \"${bundle}\"`,\n );\n }\n\n // temporarily store the original __NEXT_P reference\n // this is required to avoid conflicts with the Next.js client pages loader\n // which uses the same global variable to store the page components\n const __NEXT_P_ORIGINAL = self.__NEXT_P;\n const selfOriginal = self;\n delete selfOriginal.__NEXT_P;\n\n // load the component and app loader chunks\n self.__remote_webpack_require__?.[bundle]?.(\n self.__remote_webpack_require__[bundle].type !== 'turbopack'\n ? componentLoaderChunk\n : `[${bundle}] ${componentLoaderChunk}`,\n );\n if (\n typeof appLoaderChunk === 'string' ||\n (typeof appLoaderChunk === 'number' && appLoaderChunk !== -1)\n ) {\n self.__remote_webpack_require__?.[bundle]?.(\n self.__remote_webpack_require__[bundle].type !== 'turbopack'\n ? appLoaderChunk\n : `[${bundle}] ${appLoaderChunk}`,\n );\n }\n\n // if we have the __NEXT_P global variable, we can extract the component and app\n if (self.__NEXT_P) {\n const [, componentLoader] = self.__NEXT_P[0] ?? [\n undefined,\n () => ({ default: null }),\n ];\n const [, appLoader] = self.__NEXT_P[2] ?? [\n undefined,\n () => ({\n default: null,\n }),\n ];\n const { default: Component } = componentLoader();\n const { default: App } = appLoader();\n\n if (!self.__remote_next_css__) {\n // eslint-disable-next-line camelcase\n self.__remote_next_css__ = {};\n }\n\n if (!self.__remote_next_css__[bundle]) {\n // load the CSS files from the remote bundle\n const cssRE = /\\.s?css$/;\n Object.keys(self.__remote_webpack_require__?.[bundle]?.m ?? {})\n .filter((id) => cssRE.test(id))\n .forEach((id) => {\n self.__remote_webpack_require__?.[bundle]?.(id);\n });\n\n Object.keys(self.__remote_webpack_module_map__?.[bundle] ?? {})\n .filter((path) => cssRE.test(path))\n .forEach((path) => {\n const id = self.__remote_webpack_module_map__?.[bundle]?.[path];\n if (id) {\n self.__remote_webpack_require__?.[bundle]?.(id);\n }\n });\n\n const elements = [];\n let node = nextCss.previousSibling;\n while (node && node !== nextCssEnd) {\n elements.push(node);\n node.remove();\n node = nextCss.previousSibling;\n }\n self.__remote_next_css__[bundle] = elements;\n }\n\n // if the styleContainer is provided, we need to move the styles to it\n if (styleContainer) {\n const elements = self.__remote_next_css__[bundle];\n elements.forEach((el) => {\n styleContainer.appendChild(el.cloneNode(true));\n });\n } else {\n // if no styleContainer is provided, we need to move the styles back to the head\n const elements = self.__remote_next_css__[bundle];\n elements.forEach((el) => {\n document.head.appendChild(el);\n });\n }\n\n // restore the original __NEXT_P reference\n delete self.__NEXT_P;\n self.__NEXT_P = __NEXT_P_ORIGINAL;\n\n // restore the original Next.js CSS loader\n if (nextCssOriginal) {\n nextCssOriginal.parentNode?.appendChild(nextCssOriginal);\n }\n\n nextCss.remove();\n nextCssEnd.remove();\n\n return { Component, App };\n }\n\n return { Component: null, App: null };\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1,19 +1,27 @@
|
|
|
1
1
|
function nextClientPagesLoader(bundle, route, styleContainer = document.head) {
|
|
2
2
|
const self = globalThis;
|
|
3
|
-
const nextCssOriginal = document.
|
|
3
|
+
const nextCssOriginal = document.querySelector(
|
|
4
|
+
`[id="__next_css__DO_NOT_USE__"]:not([data-bundle="${bundle}"][data-route="${route}"])`
|
|
5
|
+
);
|
|
4
6
|
if (nextCssOriginal) {
|
|
5
7
|
nextCssOriginal.parentNode?.removeChild(nextCssOriginal);
|
|
6
8
|
}
|
|
7
9
|
const nextCss = document.createElement("noscript");
|
|
8
10
|
nextCss.id = "__next_css__DO_NOT_USE__";
|
|
9
|
-
|
|
11
|
+
nextCss.setAttribute("data-bundle", bundle);
|
|
12
|
+
nextCss.setAttribute("data-route", route);
|
|
13
|
+
const nextCssEnd = document.createElement("noscript");
|
|
14
|
+
nextCssEnd.id = "__next_css__DO_NOT_USE_END__";
|
|
15
|
+
nextCssEnd.setAttribute("data-bundle", bundle);
|
|
16
|
+
nextCssEnd.setAttribute("data-route", route);
|
|
17
|
+
document.head.appendChild(nextCssEnd);
|
|
10
18
|
document.head.appendChild(nextCss);
|
|
11
19
|
const componentLoaderChunk = Object.keys(self.__remote_webpack_require__?.[bundle]?.m ?? {}).find(
|
|
12
|
-
(key) => key.includes("/webpack/loaders/next-client-pages-loader.js") && key.includes(`page=${encodeURIComponent(route)}
|
|
20
|
+
(key) => key.includes("/webpack/loaders/next-client-pages-loader.js") && key.includes(`page=${encodeURIComponent(route)}!`)
|
|
13
21
|
) ?? Object.keys(self.__remote_webpack_require__?.[bundle]?.m ?? {}).find(
|
|
14
22
|
(key) => key.includes("/next/dist/client/page-loader.js")
|
|
15
23
|
) ?? self.__remote_webpack_module_map__?.[bundle]?.[Object.keys(self.__remote_webpack_module_map__[bundle] ?? {}).find(
|
|
16
|
-
(key) => key.includes("/webpack/loaders/next-client-pages-loader.js") && key.includes(`page=${encodeURIComponent(route)}
|
|
24
|
+
(key) => key.includes("/webpack/loaders/next-client-pages-loader.js") && key.includes(`page=${encodeURIComponent(route)}!`)
|
|
17
25
|
) ?? Object.keys(self.__remote_webpack_module_map__[bundle] ?? {}).find(
|
|
18
26
|
(key) => key.includes("/next/dist/client/page-loader.js")
|
|
19
27
|
) ?? ""] ?? -1;
|
|
@@ -55,28 +63,47 @@ function nextClientPagesLoader(bundle, route, styleContainer = document.head) {
|
|
|
55
63
|
];
|
|
56
64
|
const { default: Component } = componentLoader();
|
|
57
65
|
const { default: App } = appLoader();
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
if (id) {
|
|
66
|
+
if (!self.__remote_next_css__) {
|
|
67
|
+
self.__remote_next_css__ = {};
|
|
68
|
+
}
|
|
69
|
+
if (!self.__remote_next_css__[bundle]) {
|
|
70
|
+
const cssRE = /\.s?css$/;
|
|
71
|
+
Object.keys(self.__remote_webpack_require__?.[bundle]?.m ?? {}).filter((id) => cssRE.test(id)).forEach((id) => {
|
|
65
72
|
self.__remote_webpack_require__?.[bundle]?.(id);
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
|
|
73
|
+
});
|
|
74
|
+
Object.keys(self.__remote_webpack_module_map__?.[bundle] ?? {}).filter((path) => cssRE.test(path)).forEach((path) => {
|
|
75
|
+
const id = self.__remote_webpack_module_map__?.[bundle]?.[path];
|
|
76
|
+
if (id) {
|
|
77
|
+
self.__remote_webpack_require__?.[bundle]?.(id);
|
|
78
|
+
}
|
|
79
|
+
});
|
|
80
|
+
const elements = [];
|
|
69
81
|
let node = nextCss.previousSibling;
|
|
70
|
-
while (node && node !==
|
|
71
|
-
|
|
82
|
+
while (node && node !== nextCssEnd) {
|
|
83
|
+
elements.push(node);
|
|
84
|
+
node.remove();
|
|
72
85
|
node = nextCss.previousSibling;
|
|
73
86
|
}
|
|
87
|
+
self.__remote_next_css__[bundle] = elements;
|
|
88
|
+
}
|
|
89
|
+
if (styleContainer) {
|
|
90
|
+
const elements = self.__remote_next_css__[bundle];
|
|
91
|
+
elements.forEach((el) => {
|
|
92
|
+
styleContainer.appendChild(el.cloneNode(true));
|
|
93
|
+
});
|
|
94
|
+
} else {
|
|
95
|
+
const elements = self.__remote_next_css__[bundle];
|
|
96
|
+
elements.forEach((el) => {
|
|
97
|
+
document.head.appendChild(el);
|
|
98
|
+
});
|
|
74
99
|
}
|
|
75
100
|
delete self.__NEXT_P;
|
|
76
101
|
self.__NEXT_P = __NEXT_P_ORIGINAL;
|
|
77
102
|
if (nextCssOriginal) {
|
|
78
103
|
nextCssOriginal.parentNode?.appendChild(nextCssOriginal);
|
|
79
104
|
}
|
|
105
|
+
nextCss.remove();
|
|
106
|
+
nextCssEnd.remove();
|
|
80
107
|
return { Component, App };
|
|
81
108
|
}
|
|
82
109
|
return { Component: null, App: null };
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/shared/webpack/next-client-pages-loader.ts"],"sourcesContent":["// module loader for Next.js Pages Router\nexport function nextClientPagesLoader(\n bundle: string,\n route: string,\n styleContainer: HTMLHeadElement | ShadowRoot | null = document.head,\n) {\n // make a typed reference to the global scope\n const self = globalThis as typeof globalThis & {\n // webpack remote module loading function scoped for each bundle\n __remote_webpack_require__?: Record<\n string,\n ((remoteId: string | number) => unknown) & {\n c?: Record<\n string | number,\n { id: string; parents: string[]; children: string[] }\n >;\n m?: Record<string | number, (module: { exports: unknown }) => void>;\n type?: 'turbopack' | 'webpack';\n }\n >;\n // webpack module map for each bundle used in production builds\n __remote_webpack_module_map__?: Record<string, Record<string, number>>;\n // Next.js client pages loader reference storage\n __NEXT_P?: [\n (\n | [\n string,\n () => { default?: React.ComponentType<Record<string, unknown>> },\n ]\n | undefined\n ),\n (\n | [\n string,\n () => {\n default?: React.ComponentType<\n {\n Component: React.ComponentType<Record<string, unknown>>;\n } & Record<string, unknown>\n >;\n },\n ]\n | undefined\n ),\n (\n | [\n string,\n () => {\n default?: React.ComponentType<\n {\n Component: React.ComponentType<Record<string, unknown>>;\n } & Record<string, unknown>\n >;\n },\n ]\n | undefined\n ),\n ];\n };\n\n // temporarily remove the original Next.js CSS loader\n const nextCssOriginal = document.getElementById('__next_css__DO_NOT_USE__');\n if (nextCssOriginal) {\n nextCssOriginal.parentNode?.removeChild(nextCssOriginal);\n }\n\n // create a new Next.js CSS loader element\n const nextCss = document.createElement('noscript');\n nextCss.id = '__next_css__DO_NOT_USE__';\n const lastNode =\n document.head.childNodes[document.head.childNodes.length - 1];\n document.head.appendChild(nextCss);\n\n // find the page component loader chunk\n const componentLoaderChunk =\n Object.keys(self.__remote_webpack_require__?.[bundle]?.m ?? {}).find(\n (key) =>\n key.includes('/webpack/loaders/next-client-pages-loader.js') &&\n key.includes(`page=${encodeURIComponent(route)}`),\n ) ??\n Object.keys(self.__remote_webpack_require__?.[bundle]?.m ?? {}).find(\n (key) => key.includes('/next/dist/client/page-loader.js'),\n ) ??\n self.__remote_webpack_module_map__?.[bundle]?.[\n Object.keys(self.__remote_webpack_module_map__[bundle] ?? {}).find(\n (key) =>\n key.includes('/webpack/loaders/next-client-pages-loader.js') &&\n key.includes(`page=${encodeURIComponent(route)}`),\n ) ??\n Object.keys(self.__remote_webpack_module_map__[bundle] ?? {}).find(\n (key) => key.includes('/next/dist/client/page-loader.js'),\n ) ??\n ''\n ] ??\n -1;\n\n // find the app loader chunk\n const appLoaderChunk =\n Object.keys(self.__remote_webpack_require__?.[bundle]?.m ?? {}).find(\n (key) =>\n key.includes('/webpack/loaders/next-client-pages-loader.js') &&\n key.includes(`page=%2F_app`),\n ) ??\n Object.keys(self.__remote_webpack_require__?.[bundle]?.m ?? {}).find(\n (key) => key.includes('/next/dist/client/page-loader.js'),\n ) ??\n self.__remote_webpack_module_map__?.[bundle]?.[\n Object.keys(self.__remote_webpack_module_map__[bundle] ?? {}).find(\n (key) =>\n key.includes('/webpack/loaders/next-client-pages-loader.js') &&\n key.includes(`page=%2F_app`),\n ) ??\n Object.keys(self.__remote_webpack_module_map__[bundle] ?? {}).find(\n (key) => key.includes('/next/dist/client/page-loader.js'),\n ) ??\n ''\n ] ??\n -1;\n\n // if we didn't find the component loader or app loader, throw an error\n if (!(componentLoaderChunk && appLoaderChunk)) {\n throw new Error(\n `Next.js client pages loader not found in bundle \"${bundle}\"`,\n );\n }\n\n // temporarily store the original __NEXT_P reference\n // this is required to avoid conflicts with the Next.js client pages loader\n // which uses the same global variable to store the page components\n const __NEXT_P_ORIGINAL = self.__NEXT_P;\n const selfOriginal = self;\n delete selfOriginal.__NEXT_P;\n\n // load the component and app loader chunks\n self.__remote_webpack_require__?.[bundle]?.(\n self.__remote_webpack_require__[bundle].type !== 'turbopack'\n ? componentLoaderChunk\n : `[${bundle}] ${componentLoaderChunk}`,\n );\n if (\n typeof appLoaderChunk === 'string' ||\n (typeof appLoaderChunk === 'number' && appLoaderChunk !== -1)\n ) {\n self.__remote_webpack_require__?.[bundle]?.(\n self.__remote_webpack_require__[bundle].type !== 'turbopack'\n ? appLoaderChunk\n : `[${bundle}] ${appLoaderChunk}`,\n );\n }\n\n // if we have the __NEXT_P global variable, we can extract the component and app\n if (self.__NEXT_P) {\n const [, componentLoader] = self.__NEXT_P[0] ?? [\n undefined,\n () => ({ default: null }),\n ];\n const [, appLoader] = self.__NEXT_P[2] ?? [\n undefined,\n () => ({\n default: null,\n }),\n ];\n const { default: Component } = componentLoader();\n const { default: App } = appLoader();\n\n // load the CSS files from the remote bundle\n const cssRE = /\\.s?css$/;\n Object.keys(self.__remote_webpack_require__?.[bundle]?.m ?? {})\n .filter((id) => cssRE.test(id))\n .forEach((id) => {\n self.__remote_webpack_require__?.[bundle]?.(id);\n });\n\n Object.keys(self.__remote_webpack_module_map__?.[bundle] ?? {})\n .filter((path) => cssRE.test(path))\n .forEach((path) => {\n const id = self.__remote_webpack_module_map__?.[bundle]?.[path];\n if (id) {\n self.__remote_webpack_require__?.[bundle]?.(id);\n }\n });\n\n // if the styleContainer is provided, we need to move the styles to it\n if (styleContainer) {\n let node = nextCss.previousSibling;\n while (node && node !== lastNode) {\n styleContainer.appendChild(node);\n node = nextCss.previousSibling;\n }\n }\n\n // restore the original __NEXT_P reference\n delete self.__NEXT_P;\n self.__NEXT_P = __NEXT_P_ORIGINAL;\n\n // restore the original Next.js CSS loader\n if (nextCssOriginal) {\n nextCssOriginal.parentNode?.appendChild(nextCssOriginal);\n }\n\n return { Component, App };\n }\n\n return { Component: null, App: null };\n}\n"],"mappings":"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","names":[]}
|
|
1
|
+
{"version":3,"sources":["../../../src/shared/webpack/next-client-pages-loader.ts"],"sourcesContent":["// module loader for Next.js Pages Router\nexport function nextClientPagesLoader(\n bundle: string,\n route: string,\n styleContainer: HTMLHeadElement | ShadowRoot | null = document.head,\n) {\n // make a typed reference to the global scope\n const self = globalThis as typeof globalThis & {\n // webpack remote module loading function scoped for each bundle\n __remote_webpack_require__?: Record<\n string,\n ((remoteId: string | number) => unknown) & {\n c?: Record<\n string | number,\n { id: string; parents: string[]; children: string[] }\n >;\n m?: Record<string | number, (module: { exports: unknown }) => void>;\n type?: 'turbopack' | 'webpack';\n }\n >;\n // webpack module map for each bundle used in production builds\n __remote_webpack_module_map__?: Record<string, Record<string, number>>;\n // Next.js client pages loader reference storage\n __NEXT_P?: [\n (\n | [\n string,\n () => { default?: React.ComponentType<Record<string, unknown>> },\n ]\n | undefined\n ),\n (\n | [\n string,\n () => {\n default?: React.ComponentType<\n {\n Component: React.ComponentType<Record<string, unknown>>;\n } & Record<string, unknown>\n >;\n },\n ]\n | undefined\n ),\n (\n | [\n string,\n () => {\n default?: React.ComponentType<\n {\n Component: React.ComponentType<Record<string, unknown>>;\n } & Record<string, unknown>\n >;\n },\n ]\n | undefined\n ),\n ];\n // Next.js Pages Router CSS cache\n __remote_next_css__?: Record<string, ChildNode[]>;\n };\n\n // temporarily remove the original Next.js CSS loader\n const nextCssOriginal = document.querySelector(\n `[id=\"__next_css__DO_NOT_USE__\"]:not([data-bundle=\"${bundle}\"][data-route=\"${route}\"])`,\n );\n if (nextCssOriginal) {\n nextCssOriginal.parentNode?.removeChild(nextCssOriginal);\n }\n\n // create a new Next.js CSS loader element\n const nextCss = document.createElement('noscript');\n nextCss.id = '__next_css__DO_NOT_USE__';\n nextCss.setAttribute('data-bundle', bundle);\n nextCss.setAttribute('data-route', route);\n const nextCssEnd = document.createElement('noscript');\n nextCssEnd.id = '__next_css__DO_NOT_USE_END__';\n nextCssEnd.setAttribute('data-bundle', bundle);\n nextCssEnd.setAttribute('data-route', route);\n document.head.appendChild(nextCssEnd);\n document.head.appendChild(nextCss);\n\n // find the page component loader chunk\n const componentLoaderChunk =\n Object.keys(self.__remote_webpack_require__?.[bundle]?.m ?? {}).find(\n (key) =>\n key.includes('/webpack/loaders/next-client-pages-loader.js') &&\n key.includes(`page=${encodeURIComponent(route)}!`),\n ) ??\n Object.keys(self.__remote_webpack_require__?.[bundle]?.m ?? {}).find(\n (key) => key.includes('/next/dist/client/page-loader.js'),\n ) ??\n self.__remote_webpack_module_map__?.[bundle]?.[\n Object.keys(self.__remote_webpack_module_map__[bundle] ?? {}).find(\n (key) =>\n key.includes('/webpack/loaders/next-client-pages-loader.js') &&\n key.includes(`page=${encodeURIComponent(route)}!`),\n ) ??\n Object.keys(self.__remote_webpack_module_map__[bundle] ?? {}).find(\n (key) => key.includes('/next/dist/client/page-loader.js'),\n ) ??\n ''\n ] ??\n -1;\n\n // find the app loader chunk\n const appLoaderChunk =\n Object.keys(self.__remote_webpack_require__?.[bundle]?.m ?? {}).find(\n (key) =>\n key.includes('/webpack/loaders/next-client-pages-loader.js') &&\n key.includes(`page=%2F_app`),\n ) ??\n Object.keys(self.__remote_webpack_require__?.[bundle]?.m ?? {}).find(\n (key) => key.includes('/next/dist/client/page-loader.js'),\n ) ??\n self.__remote_webpack_module_map__?.[bundle]?.[\n Object.keys(self.__remote_webpack_module_map__[bundle] ?? {}).find(\n (key) =>\n key.includes('/webpack/loaders/next-client-pages-loader.js') &&\n key.includes(`page=%2F_app`),\n ) ??\n Object.keys(self.__remote_webpack_module_map__[bundle] ?? {}).find(\n (key) => key.includes('/next/dist/client/page-loader.js'),\n ) ??\n ''\n ] ??\n -1;\n\n // if we didn't find the component loader or app loader, throw an error\n if (!(componentLoaderChunk && appLoaderChunk)) {\n throw new Error(\n `Next.js client pages loader not found in bundle \"${bundle}\"`,\n );\n }\n\n // temporarily store the original __NEXT_P reference\n // this is required to avoid conflicts with the Next.js client pages loader\n // which uses the same global variable to store the page components\n const __NEXT_P_ORIGINAL = self.__NEXT_P;\n const selfOriginal = self;\n delete selfOriginal.__NEXT_P;\n\n // load the component and app loader chunks\n self.__remote_webpack_require__?.[bundle]?.(\n self.__remote_webpack_require__[bundle].type !== 'turbopack'\n ? componentLoaderChunk\n : `[${bundle}] ${componentLoaderChunk}`,\n );\n if (\n typeof appLoaderChunk === 'string' ||\n (typeof appLoaderChunk === 'number' && appLoaderChunk !== -1)\n ) {\n self.__remote_webpack_require__?.[bundle]?.(\n self.__remote_webpack_require__[bundle].type !== 'turbopack'\n ? appLoaderChunk\n : `[${bundle}] ${appLoaderChunk}`,\n );\n }\n\n // if we have the __NEXT_P global variable, we can extract the component and app\n if (self.__NEXT_P) {\n const [, componentLoader] = self.__NEXT_P[0] ?? [\n undefined,\n () => ({ default: null }),\n ];\n const [, appLoader] = self.__NEXT_P[2] ?? [\n undefined,\n () => ({\n default: null,\n }),\n ];\n const { default: Component } = componentLoader();\n const { default: App } = appLoader();\n\n if (!self.__remote_next_css__) {\n // eslint-disable-next-line camelcase\n self.__remote_next_css__ = {};\n }\n\n if (!self.__remote_next_css__[bundle]) {\n // load the CSS files from the remote bundle\n const cssRE = /\\.s?css$/;\n Object.keys(self.__remote_webpack_require__?.[bundle]?.m ?? {})\n .filter((id) => cssRE.test(id))\n .forEach((id) => {\n self.__remote_webpack_require__?.[bundle]?.(id);\n });\n\n Object.keys(self.__remote_webpack_module_map__?.[bundle] ?? {})\n .filter((path) => cssRE.test(path))\n .forEach((path) => {\n const id = self.__remote_webpack_module_map__?.[bundle]?.[path];\n if (id) {\n self.__remote_webpack_require__?.[bundle]?.(id);\n }\n });\n\n const elements = [];\n let node = nextCss.previousSibling;\n while (node && node !== nextCssEnd) {\n elements.push(node);\n node.remove();\n node = nextCss.previousSibling;\n }\n self.__remote_next_css__[bundle] = elements;\n }\n\n // if the styleContainer is provided, we need to move the styles to it\n if (styleContainer) {\n const elements = self.__remote_next_css__[bundle];\n elements.forEach((el) => {\n styleContainer.appendChild(el.cloneNode(true));\n });\n } else {\n // if no styleContainer is provided, we need to move the styles back to the head\n const elements = self.__remote_next_css__[bundle];\n elements.forEach((el) => {\n document.head.appendChild(el);\n });\n }\n\n // restore the original __NEXT_P reference\n delete self.__NEXT_P;\n self.__NEXT_P = __NEXT_P_ORIGINAL;\n\n // restore the original Next.js CSS loader\n if (nextCssOriginal) {\n nextCssOriginal.parentNode?.appendChild(nextCssOriginal);\n }\n\n nextCss.remove();\n nextCssEnd.remove();\n\n return { Component, App };\n }\n\n return { Component: null, App: null };\n}\n"],"mappings":"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","names":[]}
|
|
@@ -31,6 +31,8 @@ async function RemoteComponent({
|
|
|
31
31
|
src,
|
|
32
32
|
name: nameProp,
|
|
33
33
|
isolate,
|
|
34
|
+
mode,
|
|
35
|
+
reset,
|
|
34
36
|
children
|
|
35
37
|
}) {
|
|
36
38
|
const headerList = await (0, import_headers.headers)();
|
|
@@ -55,9 +57,11 @@ async function RemoteComponent({
|
|
|
55
57
|
data: hydrationData,
|
|
56
58
|
isolate,
|
|
57
59
|
links,
|
|
60
|
+
mode,
|
|
58
61
|
name,
|
|
59
62
|
nextData,
|
|
60
63
|
remoteShared,
|
|
64
|
+
reset,
|
|
61
65
|
route: metadata.route,
|
|
62
66
|
runtime: metadata.runtime,
|
|
63
67
|
scripts,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/next/host/app-router-server.tsx"],"sourcesContent":["import { headers } from 'next/headers';\nimport { Suspense, Children } from 'react';\nimport { RemoteComponentClient } from '#internal/next/host/app-router-client';\nimport { fetchRemoteComponent } from '#internal/shared/ssr/fetch-remote-component';\n\nconst CURRENT_ZONE = process.env.NEXT_PUBLIC_MFE_CURRENT_APPLICATION;\n\nexport interface RemoteComponentProps {\n /** The source URL of the remote component. When using Vercel Microfrontends, you can use relative paths, e.g. `/nextjs-app-remote/components/header`. Absolute URLs are also supported. */\n src: string | URL;\n /** The name of the exposed remote component. Used to identify the remote component when multiple remote components are exposed on a page. */\n name?: string;\n /** Whether to isolate the remote component using a Shadow DOM wrapper. Defaults to `true`. Use `false` explicitly to disable isolation. */\n isolate?: boolean;\n /** Loading fallback content to display while the remote component is being fetched. */\n children?: React.ReactNode;\n}\n\n/**\n * RemoteComponent is a Next.js component that fetches and renders a remote component.\n * It supports SSR and can isolate the remote component in a shadow DOM.\n *\n * @param src - The source URL of the remote component. When using Vercel Microfrontends, you can use relative paths, e.g. `/nextjs-app-remote/components/header`. Absolute URLs are also supported.\n * @param isolate - Whether to isolate the remote component using a Shadow DOM wrapper. Defaults to `true`. Use `false` explicitly to disable isolation.\n * @returns A React component that renders the remote component.\n *\n * @example\n *\n * Use the `<RemoteComponent>` in your Next.js App Router application to consume a remote component from a remote application:\n *\n * ```tsx\n * import { RemoteComponent } from 'remote-components/next/host';\n *\n * export default function MyPage() {\n * return (\n * <>\n * <h1>Welcome to My Page</h1>\n * <p>This page consumes a remote component from another application.</p>\n * <RemoteComponent src=\"/nextjs-app-remote/components/header\" />\n * </>\n * );\n * }\n * ```\n */\nexport async function RemoteComponent({\n src,\n name: nameProp,\n isolate,\n children,\n}: RemoteComponentProps): Promise<React.ReactElement> {\n // get the headers from the request\n const headerList = await headers();\n\n const {\n metadata,\n scripts,\n links,\n hydrationData,\n nextData,\n component,\n remoteShared,\n url,\n } = await fetchRemoteComponent(src, headerList, {\n name: nameProp,\n rsc: true,\n });\n\n // pass all remote component data to the SSR/client layer\n // render remote component static HTML as children\n // remote _ssr suffix from remote component id\n const name = metadata.id.replace(/_ssr$/, '');\n const remoteComponentClient = (\n <RemoteComponentClient\n bundle={metadata.bundle || (CURRENT_ZONE ?? name)}\n data={hydrationData}\n isolate={isolate}\n links={links}\n name={name}\n nextData={nextData}\n remoteShared={remoteShared}\n route={metadata.route}\n runtime={metadata.runtime}\n scripts={scripts}\n url={url.href}\n >\n {component}\n </RemoteComponentClient>\n );\n\n if (Children.count(children) > 0) {\n // if there are children, render them inside the remote component\n return <Suspense fallback={children}>{remoteComponentClient}</Suspense>;\n }\n\n return remoteComponentClient;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;
|
|
1
|
+
{"version":3,"sources":["../../../src/next/host/app-router-server.tsx"],"sourcesContent":["import { headers } from 'next/headers';\nimport { Suspense, Children } from 'react';\nimport { RemoteComponentClient } from '#internal/next/host/app-router-client';\nimport { fetchRemoteComponent } from '#internal/shared/ssr/fetch-remote-component';\n\nconst CURRENT_ZONE = process.env.NEXT_PUBLIC_MFE_CURRENT_APPLICATION;\n\nexport interface RemoteComponentProps {\n /** The source URL of the remote component. When using Vercel Microfrontends, you can use relative paths, e.g. `/nextjs-app-remote/components/header`. Absolute URLs are also supported. */\n src: string | URL;\n /** The name of the exposed remote component. Used to identify the remote component when multiple remote components are exposed on a page. */\n name?: string;\n /** Whether to isolate the remote component using a Shadow DOM wrapper. Defaults to `true`. Use `false` explicitly to disable isolation. */\n isolate?: boolean;\n /** The mode of the Shadow DOM. Defaults to `open`. */\n mode?: 'open' | 'closed';\n /** Whether to include a CSS reset style in the shadow DOM. Defaults to `false`. */\n reset?: boolean;\n /** Loading fallback content to display while the remote component is being fetched. */\n children?: React.ReactNode;\n}\n\n/**\n * RemoteComponent is a Next.js component that fetches and renders a remote component.\n * It supports SSR and can isolate the remote component in a shadow DOM.\n *\n * @param src - The source URL of the remote component. When using Vercel Microfrontends, you can use relative paths, e.g. `/nextjs-app-remote/components/header`. Absolute URLs are also supported.\n * @param isolate - Whether to isolate the remote component using a Shadow DOM wrapper. Defaults to `true`. Use `false` explicitly to disable isolation.\n * @returns A React component that renders the remote component.\n *\n * @example\n *\n * Use the `<RemoteComponent>` in your Next.js App Router application to consume a remote component from a remote application:\n *\n * ```tsx\n * import { RemoteComponent } from 'remote-components/next/host';\n *\n * export default function MyPage() {\n * return (\n * <>\n * <h1>Welcome to My Page</h1>\n * <p>This page consumes a remote component from another application.</p>\n * <RemoteComponent src=\"/nextjs-app-remote/components/header\" />\n * </>\n * );\n * }\n * ```\n */\nexport async function RemoteComponent({\n src,\n name: nameProp,\n isolate,\n mode,\n reset,\n children,\n}: RemoteComponentProps): Promise<React.ReactElement> {\n // get the headers from the request\n const headerList = await headers();\n\n const {\n metadata,\n scripts,\n links,\n hydrationData,\n nextData,\n component,\n remoteShared,\n url,\n } = await fetchRemoteComponent(src, headerList, {\n name: nameProp,\n rsc: true,\n });\n\n // pass all remote component data to the SSR/client layer\n // render remote component static HTML as children\n // remote _ssr suffix from remote component id\n const name = metadata.id.replace(/_ssr$/, '');\n const remoteComponentClient = (\n <RemoteComponentClient\n bundle={metadata.bundle || (CURRENT_ZONE ?? name)}\n data={hydrationData}\n isolate={isolate}\n links={links}\n mode={mode}\n name={name}\n nextData={nextData}\n remoteShared={remoteShared}\n reset={reset}\n route={metadata.route}\n runtime={metadata.runtime}\n scripts={scripts}\n url={url.href}\n >\n {component}\n </RemoteComponentClient>\n );\n\n if (Children.count(children) > 0) {\n // if there are children, render them inside the remote component\n return <Suspense fallback={children}>{remoteComponentClient}</Suspense>;\n }\n\n return remoteComponentClient;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AA8EI;AA9EJ,qBAAwB;AACxB,mBAAmC;AACnC,+BAAsC;AACtC,oCAAqC;AAErC,MAAM,eAAe,QAAQ,IAAI;AA2CjC,eAAsB,gBAAgB;AAAA,EACpC;AAAA,EACA,MAAM;AAAA,EACN;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAsD;AAEpD,QAAM,aAAa,UAAM,wBAAQ;AAEjC,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI,UAAM,oDAAqB,KAAK,YAAY;AAAA,IAC9C,MAAM;AAAA,IACN,KAAK;AAAA,EACP,CAAC;AAKD,QAAM,OAAO,SAAS,GAAG,QAAQ,SAAS,EAAE;AAC5C,QAAM,wBACJ;AAAA,IAAC;AAAA;AAAA,MACC,QAAQ,SAAS,WAAW,gBAAgB;AAAA,MAC5C,MAAM;AAAA,MACN;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,OAAO,SAAS;AAAA,MAChB,SAAS,SAAS;AAAA,MAClB;AAAA,MACA,KAAK,IAAI;AAAA,MAER;AAAA;AAAA,EACH;AAGF,MAAI,sBAAS,MAAM,QAAQ,IAAI,GAAG;AAEhC,WAAO,4CAAC,yBAAS,UAAU,UAAW,iCAAsB;AAAA,EAC9D;AAEA,SAAO;AACT;","names":[]}
|
|
@@ -5,6 +5,10 @@ interface RemoteComponentProps {
|
|
|
5
5
|
name?: string;
|
|
6
6
|
/** Whether to isolate the remote component using a Shadow DOM wrapper. Defaults to `true`. Use `false` explicitly to disable isolation. */
|
|
7
7
|
isolate?: boolean;
|
|
8
|
+
/** The mode of the Shadow DOM. Defaults to `open`. */
|
|
9
|
+
mode?: 'open' | 'closed';
|
|
10
|
+
/** Whether to include a CSS reset style in the shadow DOM. Defaults to `false`. */
|
|
11
|
+
reset?: boolean;
|
|
8
12
|
/** Loading fallback content to display while the remote component is being fetched. */
|
|
9
13
|
children?: React.ReactNode;
|
|
10
14
|
}
|
|
@@ -34,6 +38,6 @@ interface RemoteComponentProps {
|
|
|
34
38
|
* }
|
|
35
39
|
* ```
|
|
36
40
|
*/
|
|
37
|
-
declare function RemoteComponent({ src, name: nameProp, isolate, children, }: RemoteComponentProps): Promise<React.ReactElement>;
|
|
41
|
+
declare function RemoteComponent({ src, name: nameProp, isolate, mode, reset, children, }: RemoteComponentProps): Promise<React.ReactElement>;
|
|
38
42
|
|
|
39
43
|
export { RemoteComponent, RemoteComponentProps };
|
|
@@ -8,6 +8,8 @@ async function RemoteComponent({
|
|
|
8
8
|
src,
|
|
9
9
|
name: nameProp,
|
|
10
10
|
isolate,
|
|
11
|
+
mode,
|
|
12
|
+
reset,
|
|
11
13
|
children
|
|
12
14
|
}) {
|
|
13
15
|
const headerList = await headers();
|
|
@@ -32,9 +34,11 @@ async function RemoteComponent({
|
|
|
32
34
|
data: hydrationData,
|
|
33
35
|
isolate,
|
|
34
36
|
links,
|
|
37
|
+
mode,
|
|
35
38
|
name,
|
|
36
39
|
nextData,
|
|
37
40
|
remoteShared,
|
|
41
|
+
reset,
|
|
38
42
|
route: metadata.route,
|
|
39
43
|
runtime: metadata.runtime,
|
|
40
44
|
scripts,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/next/host/app-router-server.tsx"],"sourcesContent":["import { headers } from 'next/headers';\nimport { Suspense, Children } from 'react';\nimport { RemoteComponentClient } from '#internal/next/host/app-router-client';\nimport { fetchRemoteComponent } from '#internal/shared/ssr/fetch-remote-component';\n\nconst CURRENT_ZONE = process.env.NEXT_PUBLIC_MFE_CURRENT_APPLICATION;\n\nexport interface RemoteComponentProps {\n /** The source URL of the remote component. When using Vercel Microfrontends, you can use relative paths, e.g. `/nextjs-app-remote/components/header`. Absolute URLs are also supported. */\n src: string | URL;\n /** The name of the exposed remote component. Used to identify the remote component when multiple remote components are exposed on a page. */\n name?: string;\n /** Whether to isolate the remote component using a Shadow DOM wrapper. Defaults to `true`. Use `false` explicitly to disable isolation. */\n isolate?: boolean;\n /** Loading fallback content to display while the remote component is being fetched. */\n children?: React.ReactNode;\n}\n\n/**\n * RemoteComponent is a Next.js component that fetches and renders a remote component.\n * It supports SSR and can isolate the remote component in a shadow DOM.\n *\n * @param src - The source URL of the remote component. When using Vercel Microfrontends, you can use relative paths, e.g. `/nextjs-app-remote/components/header`. Absolute URLs are also supported.\n * @param isolate - Whether to isolate the remote component using a Shadow DOM wrapper. Defaults to `true`. Use `false` explicitly to disable isolation.\n * @returns A React component that renders the remote component.\n *\n * @example\n *\n * Use the `<RemoteComponent>` in your Next.js App Router application to consume a remote component from a remote application:\n *\n * ```tsx\n * import { RemoteComponent } from 'remote-components/next/host';\n *\n * export default function MyPage() {\n * return (\n * <>\n * <h1>Welcome to My Page</h1>\n * <p>This page consumes a remote component from another application.</p>\n * <RemoteComponent src=\"/nextjs-app-remote/components/header\" />\n * </>\n * );\n * }\n * ```\n */\nexport async function RemoteComponent({\n src,\n name: nameProp,\n isolate,\n children,\n}: RemoteComponentProps): Promise<React.ReactElement> {\n // get the headers from the request\n const headerList = await headers();\n\n const {\n metadata,\n scripts,\n links,\n hydrationData,\n nextData,\n component,\n remoteShared,\n url,\n } = await fetchRemoteComponent(src, headerList, {\n name: nameProp,\n rsc: true,\n });\n\n // pass all remote component data to the SSR/client layer\n // render remote component static HTML as children\n // remote _ssr suffix from remote component id\n const name = metadata.id.replace(/_ssr$/, '');\n const remoteComponentClient = (\n <RemoteComponentClient\n bundle={metadata.bundle || (CURRENT_ZONE ?? name)}\n data={hydrationData}\n isolate={isolate}\n links={links}\n name={name}\n nextData={nextData}\n remoteShared={remoteShared}\n route={metadata.route}\n runtime={metadata.runtime}\n scripts={scripts}\n url={url.href}\n >\n {component}\n </RemoteComponentClient>\n );\n\n if (Children.count(children) > 0) {\n // if there are children, render them inside the remote component\n return <Suspense fallback={children}>{remoteComponentClient}</Suspense>;\n }\n\n return remoteComponentClient;\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../../../src/next/host/app-router-server.tsx"],"sourcesContent":["import { headers } from 'next/headers';\nimport { Suspense, Children } from 'react';\nimport { RemoteComponentClient } from '#internal/next/host/app-router-client';\nimport { fetchRemoteComponent } from '#internal/shared/ssr/fetch-remote-component';\n\nconst CURRENT_ZONE = process.env.NEXT_PUBLIC_MFE_CURRENT_APPLICATION;\n\nexport interface RemoteComponentProps {\n /** The source URL of the remote component. When using Vercel Microfrontends, you can use relative paths, e.g. `/nextjs-app-remote/components/header`. Absolute URLs are also supported. */\n src: string | URL;\n /** The name of the exposed remote component. Used to identify the remote component when multiple remote components are exposed on a page. */\n name?: string;\n /** Whether to isolate the remote component using a Shadow DOM wrapper. Defaults to `true`. Use `false` explicitly to disable isolation. */\n isolate?: boolean;\n /** The mode of the Shadow DOM. Defaults to `open`. */\n mode?: 'open' | 'closed';\n /** Whether to include a CSS reset style in the shadow DOM. Defaults to `false`. */\n reset?: boolean;\n /** Loading fallback content to display while the remote component is being fetched. */\n children?: React.ReactNode;\n}\n\n/**\n * RemoteComponent is a Next.js component that fetches and renders a remote component.\n * It supports SSR and can isolate the remote component in a shadow DOM.\n *\n * @param src - The source URL of the remote component. When using Vercel Microfrontends, you can use relative paths, e.g. `/nextjs-app-remote/components/header`. Absolute URLs are also supported.\n * @param isolate - Whether to isolate the remote component using a Shadow DOM wrapper. Defaults to `true`. Use `false` explicitly to disable isolation.\n * @returns A React component that renders the remote component.\n *\n * @example\n *\n * Use the `<RemoteComponent>` in your Next.js App Router application to consume a remote component from a remote application:\n *\n * ```tsx\n * import { RemoteComponent } from 'remote-components/next/host';\n *\n * export default function MyPage() {\n * return (\n * <>\n * <h1>Welcome to My Page</h1>\n * <p>This page consumes a remote component from another application.</p>\n * <RemoteComponent src=\"/nextjs-app-remote/components/header\" />\n * </>\n * );\n * }\n * ```\n */\nexport async function RemoteComponent({\n src,\n name: nameProp,\n isolate,\n mode,\n reset,\n children,\n}: RemoteComponentProps): Promise<React.ReactElement> {\n // get the headers from the request\n const headerList = await headers();\n\n const {\n metadata,\n scripts,\n links,\n hydrationData,\n nextData,\n component,\n remoteShared,\n url,\n } = await fetchRemoteComponent(src, headerList, {\n name: nameProp,\n rsc: true,\n });\n\n // pass all remote component data to the SSR/client layer\n // render remote component static HTML as children\n // remote _ssr suffix from remote component id\n const name = metadata.id.replace(/_ssr$/, '');\n const remoteComponentClient = (\n <RemoteComponentClient\n bundle={metadata.bundle || (CURRENT_ZONE ?? name)}\n data={hydrationData}\n isolate={isolate}\n links={links}\n mode={mode}\n name={name}\n nextData={nextData}\n remoteShared={remoteShared}\n reset={reset}\n route={metadata.route}\n runtime={metadata.runtime}\n scripts={scripts}\n url={url.href}\n >\n {component}\n </RemoteComponentClient>\n );\n\n if (Children.count(children) > 0) {\n // if there are children, render them inside the remote component\n return <Suspense fallback={children}>{remoteComponentClient}</Suspense>;\n }\n\n return remoteComponentClient;\n}\n"],"mappings":"AA8EI;AA9EJ,SAAS,eAAe;AACxB,SAAS,UAAU,gBAAgB;AACnC,SAAS,6BAA6B;AACtC,SAAS,4BAA4B;AAErC,MAAM,eAAe,QAAQ,IAAI;AA2CjC,eAAsB,gBAAgB;AAAA,EACpC;AAAA,EACA,MAAM;AAAA,EACN;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAsD;AAEpD,QAAM,aAAa,MAAM,QAAQ;AAEjC,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,IAAI,MAAM,qBAAqB,KAAK,YAAY;AAAA,IAC9C,MAAM;AAAA,IACN,KAAK;AAAA,EACP,CAAC;AAKD,QAAM,OAAO,SAAS,GAAG,QAAQ,SAAS,EAAE;AAC5C,QAAM,wBACJ;AAAA,IAAC;AAAA;AAAA,MACC,QAAQ,SAAS,WAAW,gBAAgB;AAAA,MAC5C,MAAM;AAAA,MACN;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,OAAO,SAAS;AAAA,MAChB,SAAS,SAAS;AAAA,MAClB;AAAA,MACA,KAAK,IAAI;AAAA,MAER;AAAA;AAAA,EACH;AAGF,MAAI,SAAS,MAAM,QAAQ,IAAI,GAAG;AAEhC,WAAO,oBAAC,YAAS,UAAU,UAAW,iCAAsB;AAAA,EAC9D;AAEA,SAAO;AACT;","names":[]}
|
|
@@ -135,8 +135,11 @@ function RemoteComponent(props) {
|
|
|
135
135
|
import_react2.RemoteComponent,
|
|
136
136
|
{
|
|
137
137
|
isolate: props.isolate,
|
|
138
|
+
mode: props.mode,
|
|
139
|
+
name: props.name,
|
|
140
|
+
reset: props.reset,
|
|
138
141
|
shared: shared(props.bundle ?? "default"),
|
|
139
|
-
src: props.src,
|
|
142
|
+
src: props.url ?? props.src,
|
|
140
143
|
children: props.children
|
|
141
144
|
}
|
|
142
145
|
);
|
|
@@ -145,9 +148,11 @@ function RemoteComponent(props) {
|
|
|
145
148
|
import_react2.RemoteComponent,
|
|
146
149
|
{
|
|
147
150
|
isolate: props.isolate,
|
|
151
|
+
mode: props.mode,
|
|
148
152
|
name: props.name,
|
|
153
|
+
reset: props.reset,
|
|
149
154
|
shared: shared(props.bundle ?? "default"),
|
|
150
|
-
src: props.src,
|
|
155
|
+
src: props.url ?? props.src,
|
|
151
156
|
children: remoteComponent
|
|
152
157
|
}
|
|
153
158
|
);
|
|
@@ -163,7 +168,8 @@ async function getRemoteComponentProps(src, headers) {
|
|
|
163
168
|
name,
|
|
164
169
|
links,
|
|
165
170
|
component,
|
|
166
|
-
nextData
|
|
171
|
+
nextData,
|
|
172
|
+
url
|
|
167
173
|
} = await (0, import_fetch_remote_component.fetchRemoteComponent)(
|
|
168
174
|
src,
|
|
169
175
|
headers instanceof Headers ? headers : (
|
|
@@ -189,7 +195,8 @@ async function getRemoteComponentProps(src, headers) {
|
|
|
189
195
|
name,
|
|
190
196
|
route,
|
|
191
197
|
runtime,
|
|
192
|
-
buildId: nextData?.buildId ?? null
|
|
198
|
+
buildId: nextData?.buildId ?? null,
|
|
199
|
+
url: url.href
|
|
193
200
|
};
|
|
194
201
|
const key = getKey(props);
|
|
195
202
|
if (nextData?.buildId !== "development") {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/next/host/pages-router-server.tsx"],"sourcesContent":["import type { IncomingHttpHeaders } from 'node:http';\nimport { useEffect } from 'react';\nimport { shared as _shared } from '@remote-components/shared/host/pages';\nimport * as Form from 'next/form';\nimport * as Image from 'next/image';\nimport * as Link from 'next/link';\nimport * as Script from 'next/script';\nimport { useRouter } from 'next/router';\nimport { RemoteComponent as RemoteComponentReact } from '#remote-components/react/index';\nimport { fetchRemoteComponent } from '#internal/shared/ssr/fetch-remote-component';\n\nconst navigationImpl = {\n useRouter,\n useSearchParams: () => {\n const router = useRouter();\n return {\n get: (key: string) => router.query[key],\n has: (key: string) => key in router.query,\n };\n },\n};\n\nconst sharedCache = new Map<string, Record<string, () => Promise<unknown>>>();\nconst shared = (bundle: string) => {\n if (sharedCache.has(bundle)) {\n return sharedCache.get(bundle);\n }\n\n const remoteLoader = ({ src, width, quality }: Image.ImageLoaderProps) => {\n const self = globalThis as typeof globalThis & {\n __remote_bundle_url__?: Record<string, URL>;\n };\n const { assetPrefix } =\n /^(?<assetPrefix>.*?)\\/_next\\//.exec(src)?.groups ?? {};\n return `${self.__remote_bundle_url__?.[bundle]?.origin ?? ''}${assetPrefix}/_next/image?url=${encodeURIComponent(src)}&w=${width}&q=${quality || 75}`;\n };\n\n const imageImpl = (ImageComponent: typeof Image.default) => {\n return function RemoteImage(props: Image.ImageProps) {\n return <ImageComponent loader={remoteLoader} {...props} />;\n };\n };\n\n return {\n // polyfill Next.js App Router client API (minimal)\n // some API methods are not available when using a Next.js Pages Router application as host\n 'next/navigation': () =>\n Promise.resolve(navigationImpl) as Promise<unknown>,\n 'next/dist/client/components/navigation': () =>\n Promise.resolve(navigationImpl) as Promise<unknown>,\n 'next/dist/client/app-dir/link': () =>\n Promise.resolve(Link.default) as Promise<unknown>,\n 'next/link': () => Promise.resolve(Link.default) as Promise<unknown>,\n 'next/dist/client/app-dir/form': () =>\n Promise.resolve(Form.default) as Promise<unknown>,\n 'next/form': () => Promise.resolve(Form.default) as Promise<unknown>,\n 'next/dist/client/script': () =>\n Promise.resolve(Script.default) as Promise<unknown>,\n 'next/script': () => Promise.resolve(Script.default) as Promise<unknown>,\n 'next/image': () =>\n Promise.resolve({\n // @ts-expect-error default.default\n // eslint-disable-next-line\n default: imageImpl(Image.default.default ?? Image.default),\n getImageProps: Image.getImageProps,\n }) as Promise<unknown>,\n 'next/dist/client/image-component': () =>\n Promise.resolve({\n // @ts-expect-error default.default\n // eslint-disable-next-line\n Image: imageImpl(Image.default.default ?? Image.default),\n }) as Promise<unknown>,\n 'next/dist/api/image': () =>\n Promise.resolve({\n // @ts-expect-error default.default\n // eslint-disable-next-line\n default: imageImpl(Image.default.default ?? Image.default),\n getImageProps: Image.getImageProps,\n }) as Promise<unknown>,\n ..._shared,\n };\n};\n\n// internal symbols to access global store\nconst REMOTE_COMPONENT_STORE = Symbol('REMOTE_COMPONENT_STORE');\nconst REMOTE_COMPONENT_KEY = '__REMOTE_COMPONENT_KEY__';\n\n// temporary global store for remote component HTML\n// the store is used to save the HTML of remote components for SSR without sending the content to the client\nconst self = globalThis as typeof globalThis & {\n [REMOTE_COMPONENT_STORE]?: Map<string, React.ReactNode>;\n};\n\nfunction getKey({\n bundle,\n route,\n name,\n}: {\n bundle?: string;\n route?: string;\n name?: string;\n}): string {\n return `${bundle ?? '__next'}:${route ?? '/'}:${name ?? '__vercel_remote_component'}__${crypto.randomUUID()}`;\n}\n\nfunction setComponent(key: string, component: React.ReactNode): void {\n if (!self[REMOTE_COMPONENT_STORE]) {\n self[REMOTE_COMPONENT_STORE] = new Map();\n }\n self[REMOTE_COMPONENT_STORE].set(key, component);\n}\n\nfunction getComponent(key: string): React.ReactNode | undefined {\n const component = self[REMOTE_COMPONENT_STORE]?.get(key);\n // remove the component from the store after retrieving it to prevent memory leaks\n // storing the HTML in the global store is only needed for SSR and it's temporary only used for a single render\n self[REMOTE_COMPONENT_STORE]?.delete(key);\n return component;\n}\n\nexport interface RemoteComponentProps {\n src: string;\n bundle?: string;\n route?: string;\n name?: string;\n isolate?: boolean;\n [REMOTE_COMPONENT_KEY]?: string;\n children?: React.ReactNode;\n}\n\n/**\n * This component handles the rendering of remote microfrontends.\n *\n * @param props - The properties for the remote component.\n * @returns A React component that renders the remote component.\n */\nexport function RemoteComponent(props: RemoteComponentProps) {\n const remoteComponent =\n typeof document !== 'undefined'\n ? null\n : // retrieve the HTML from the global store\n getComponent(\n props[REMOTE_COMPONENT_KEY] ?? '__vercel_remote_component',\n );\n\n useEffect(() => {\n const clientSelf = globalThis as typeof globalThis & {\n __remote_component_shared__?: Record<string, () => Promise<unknown>>;\n };\n // eslint-disable-next-line camelcase\n clientSelf.__remote_component_shared__ = shared(props.bundle ?? 'default');\n }, [props.bundle]);\n\n if (!props[REMOTE_COMPONENT_KEY]) {\n return (\n <RemoteComponentReact\n isolate={props.isolate}\n shared={shared(props.bundle ?? 'default')}\n src={props.src}\n >\n {props.children}\n </RemoteComponentReact>\n );\n }\n\n return (\n <RemoteComponentReact\n isolate={props.isolate}\n name={props.name}\n shared={shared(props.bundle ?? 'default')}\n src={props.src}\n >\n {remoteComponent}\n </RemoteComponentReact>\n );\n}\n\n/**\n * Fetches the remote component properties from the server. You need to pass these properties to the `<RemoteComponent>` component to render the fetched remote component.\n *\n * @param src - The source URL of the remote component. When using the Vercel Microfrontends solution, you can use relative paths, e.g. `/nextjs-app-remote/components/header`. Absolute URLs are also supported.\n * @param headers - The HTTP headers used for supporting the Vercel Microfrontends proxy.\n * @returns The properties of the remote component.\n *\n * @example\n *\n * ```tsx\n * import { getRemoteComponentProps } from 'remote-components/next/host/pages';\n * import type { GetServerSideProps } from 'next';\n *\n * export const getServerSideProps: GetServerSideProps<PageProps> = async function getServerSideProps({ req }) {\n * const myRemoteComponent = await getRemoteComponentProps(\n * '/nextjs-app-remote/components/header',\n * req.headers,\n * );\n * return {\n * props: {\n * remoteComponents: {\n * myRemoteComponent,\n * },\n * },\n * };\n * }\n * ```\n */\nexport async function getRemoteComponentProps(\n src: string,\n headers: IncomingHttpHeaders,\n): Promise<RemoteComponentProps> {\n if (typeof document !== 'undefined') {\n throw new Error(\n 'getRemoteComponentProps can only be used on the server side.',\n );\n }\n\n const {\n metadata: { bundle, route, runtime },\n name,\n links,\n component,\n nextData,\n } = await fetchRemoteComponent(\n src,\n headers instanceof Headers\n ? headers\n : // convert IncomingHttpHeaders to web standard Headers\n Object.entries(headers).reduce((acc, [key, value]) => {\n if (value) {\n if (Array.isArray(value)) {\n value.forEach((v) => acc.append(key, v));\n } else {\n acc.append(key, value);\n }\n }\n return acc;\n }, new Headers()),\n {\n rsc: true,\n },\n );\n\n const props = {\n src,\n bundle,\n name,\n route,\n runtime,\n buildId: nextData?.buildId ?? null,\n };\n\n const key = getKey(props);\n\n // do not render the HTML in development mode when remote is using Next.js Pages Router\n // this behavior is emulating the Next.js Pages Router FOUC as the styles are only applied on the client when running in development mode\n if (nextData?.buildId !== 'development') {\n // store the HTML in a global store\n setComponent(\n key,\n <>\n {links.map((link) => (\n <link\n key={`${link.as}_${link.href}`}\n {...link}\n precedence={undefined}\n />\n ))}\n {component}\n </>,\n );\n }\n\n return {\n ...props,\n // add remote component key to the props\n [REMOTE_COMPONENT_KEY]: key,\n };\n}\n"],"mappings":"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","names":["import_react","self","_shared","RemoteComponentReact","key"]}
|
|
1
|
+
{"version":3,"sources":["../../../src/next/host/pages-router-server.tsx"],"sourcesContent":["import type { IncomingHttpHeaders } from 'node:http';\nimport { useEffect } from 'react';\nimport { shared as _shared } from '@remote-components/shared/host/pages';\nimport * as Form from 'next/form';\nimport * as Image from 'next/image';\nimport * as Link from 'next/link';\nimport * as Script from 'next/script';\nimport { useRouter } from 'next/router';\nimport { RemoteComponent as RemoteComponentReact } from '#remote-components/react/index';\nimport { fetchRemoteComponent } from '#internal/shared/ssr/fetch-remote-component';\n\nconst navigationImpl = {\n useRouter,\n useSearchParams: () => {\n const router = useRouter();\n return {\n get: (key: string) => router.query[key],\n has: (key: string) => key in router.query,\n };\n },\n};\n\nconst sharedCache = new Map<string, Record<string, () => Promise<unknown>>>();\nconst shared = (bundle: string) => {\n if (sharedCache.has(bundle)) {\n return sharedCache.get(bundle);\n }\n\n const remoteLoader = ({ src, width, quality }: Image.ImageLoaderProps) => {\n const self = globalThis as typeof globalThis & {\n __remote_bundle_url__?: Record<string, URL>;\n };\n const { assetPrefix } =\n /^(?<assetPrefix>.*?)\\/_next\\//.exec(src)?.groups ?? {};\n return `${self.__remote_bundle_url__?.[bundle]?.origin ?? ''}${assetPrefix}/_next/image?url=${encodeURIComponent(src)}&w=${width}&q=${quality || 75}`;\n };\n\n const imageImpl = (ImageComponent: typeof Image.default) => {\n return function RemoteImage(props: Image.ImageProps) {\n return <ImageComponent loader={remoteLoader} {...props} />;\n };\n };\n\n return {\n // polyfill Next.js App Router client API (minimal)\n // some API methods are not available when using a Next.js Pages Router application as host\n 'next/navigation': () =>\n Promise.resolve(navigationImpl) as Promise<unknown>,\n 'next/dist/client/components/navigation': () =>\n Promise.resolve(navigationImpl) as Promise<unknown>,\n 'next/dist/client/app-dir/link': () =>\n Promise.resolve(Link.default) as Promise<unknown>,\n 'next/link': () => Promise.resolve(Link.default) as Promise<unknown>,\n 'next/dist/client/app-dir/form': () =>\n Promise.resolve(Form.default) as Promise<unknown>,\n 'next/form': () => Promise.resolve(Form.default) as Promise<unknown>,\n 'next/dist/client/script': () =>\n Promise.resolve(Script.default) as Promise<unknown>,\n 'next/script': () => Promise.resolve(Script.default) as Promise<unknown>,\n 'next/image': () =>\n Promise.resolve({\n // @ts-expect-error default.default\n // eslint-disable-next-line\n default: imageImpl(Image.default.default ?? Image.default),\n getImageProps: Image.getImageProps,\n }) as Promise<unknown>,\n 'next/dist/client/image-component': () =>\n Promise.resolve({\n // @ts-expect-error default.default\n // eslint-disable-next-line\n Image: imageImpl(Image.default.default ?? Image.default),\n }) as Promise<unknown>,\n 'next/dist/api/image': () =>\n Promise.resolve({\n // @ts-expect-error default.default\n // eslint-disable-next-line\n default: imageImpl(Image.default.default ?? Image.default),\n getImageProps: Image.getImageProps,\n }) as Promise<unknown>,\n ..._shared,\n };\n};\n\n// internal symbols to access global store\nconst REMOTE_COMPONENT_STORE = Symbol('REMOTE_COMPONENT_STORE');\nconst REMOTE_COMPONENT_KEY = '__REMOTE_COMPONENT_KEY__';\n\n// temporary global store for remote component HTML\n// the store is used to save the HTML of remote components for SSR without sending the content to the client\nconst self = globalThis as typeof globalThis & {\n [REMOTE_COMPONENT_STORE]?: Map<string, React.ReactNode>;\n};\n\nfunction getKey({\n bundle,\n route,\n name,\n}: {\n bundle?: string;\n route?: string;\n name?: string;\n}): string {\n return `${bundle ?? '__next'}:${route ?? '/'}:${name ?? '__vercel_remote_component'}__${crypto.randomUUID()}`;\n}\n\nfunction setComponent(key: string, component: React.ReactNode): void {\n if (!self[REMOTE_COMPONENT_STORE]) {\n self[REMOTE_COMPONENT_STORE] = new Map();\n }\n self[REMOTE_COMPONENT_STORE].set(key, component);\n}\n\nfunction getComponent(key: string): React.ReactNode | undefined {\n const component = self[REMOTE_COMPONENT_STORE]?.get(key);\n // remove the component from the store after retrieving it to prevent memory leaks\n // storing the HTML in the global store is only needed for SSR and it's temporary only used for a single render\n self[REMOTE_COMPONENT_STORE]?.delete(key);\n return component;\n}\n\nexport interface RemoteComponentProps {\n src: string;\n url?: string | URL;\n bundle?: string;\n route?: string;\n name?: string;\n isolate?: boolean;\n mode?: 'open' | 'closed';\n reset?: boolean;\n [REMOTE_COMPONENT_KEY]?: string;\n children?: React.ReactNode;\n}\n\n/**\n * This component handles the rendering of remote microfrontends.\n *\n * @param props - The properties for the remote component.\n * @returns A React component that renders the remote component.\n */\nexport function RemoteComponent(props: RemoteComponentProps) {\n const remoteComponent =\n typeof document !== 'undefined'\n ? null\n : // retrieve the HTML from the global store\n getComponent(\n props[REMOTE_COMPONENT_KEY] ?? '__vercel_remote_component',\n );\n\n useEffect(() => {\n const clientSelf = globalThis as typeof globalThis & {\n __remote_component_shared__?: Record<string, () => Promise<unknown>>;\n };\n // eslint-disable-next-line camelcase\n clientSelf.__remote_component_shared__ = shared(props.bundle ?? 'default');\n }, [props.bundle]);\n\n if (!props[REMOTE_COMPONENT_KEY]) {\n return (\n <RemoteComponentReact\n isolate={props.isolate}\n mode={props.mode}\n name={props.name}\n reset={props.reset}\n shared={shared(props.bundle ?? 'default')}\n src={props.url ?? props.src}\n >\n {props.children}\n </RemoteComponentReact>\n );\n }\n\n return (\n <RemoteComponentReact\n isolate={props.isolate}\n mode={props.mode}\n name={props.name}\n reset={props.reset}\n shared={shared(props.bundle ?? 'default')}\n src={props.url ?? props.src}\n >\n {remoteComponent}\n </RemoteComponentReact>\n );\n}\n\n/**\n * Fetches the remote component properties from the server. You need to pass these properties to the `<RemoteComponent>` component to render the fetched remote component.\n *\n * @param src - The source URL of the remote component. When using the Vercel Microfrontends solution, you can use relative paths, e.g. `/nextjs-app-remote/components/header`. Absolute URLs are also supported.\n * @param headers - The HTTP headers used for supporting the Vercel Microfrontends proxy.\n * @returns The properties of the remote component.\n *\n * @example\n *\n * ```tsx\n * import { getRemoteComponentProps } from 'remote-components/next/host/pages';\n * import type { GetServerSideProps } from 'next';\n *\n * export const getServerSideProps: GetServerSideProps<PageProps> = async function getServerSideProps({ req }) {\n * const myRemoteComponent = await getRemoteComponentProps(\n * '/nextjs-app-remote/components/header',\n * req.headers,\n * );\n * return {\n * props: {\n * remoteComponents: {\n * myRemoteComponent,\n * },\n * },\n * };\n * }\n * ```\n */\nexport async function getRemoteComponentProps(\n src: string,\n headers: IncomingHttpHeaders,\n): Promise<RemoteComponentProps> {\n if (typeof document !== 'undefined') {\n throw new Error(\n 'getRemoteComponentProps can only be used on the server side.',\n );\n }\n\n const {\n metadata: { bundle, route, runtime },\n name,\n links,\n component,\n nextData,\n url,\n } = await fetchRemoteComponent(\n src,\n headers instanceof Headers\n ? headers\n : // convert IncomingHttpHeaders to web standard Headers\n Object.entries(headers).reduce((acc, [key, value]) => {\n if (value) {\n if (Array.isArray(value)) {\n value.forEach((v) => acc.append(key, v));\n } else {\n acc.append(key, value);\n }\n }\n return acc;\n }, new Headers()),\n {\n rsc: true,\n },\n );\n\n const props = {\n src,\n bundle,\n name,\n route,\n runtime,\n buildId: nextData?.buildId ?? null,\n url: url.href,\n };\n\n const key = getKey(props);\n\n // do not render the HTML in development mode when remote is using Next.js Pages Router\n // this behavior is emulating the Next.js Pages Router FOUC as the styles are only applied on the client when running in development mode\n if (nextData?.buildId !== 'development') {\n // store the HTML in a global store\n setComponent(\n key,\n <>\n {links.map((link) => (\n <link\n key={`${link.as}_${link.href}`}\n {...link}\n precedence={undefined}\n />\n ))}\n {component}\n </>,\n );\n }\n\n return {\n ...props,\n // add remote component key to the props\n [REMOTE_COMPONENT_KEY]: key,\n };\n}\n"],"mappings":"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","names":["import_react","self","_shared","RemoteComponentReact","key"]}
|
|
@@ -4,10 +4,13 @@ import { IncomingHttpHeaders } from 'node:http';
|
|
|
4
4
|
declare const REMOTE_COMPONENT_KEY = "__REMOTE_COMPONENT_KEY__";
|
|
5
5
|
interface RemoteComponentProps {
|
|
6
6
|
src: string;
|
|
7
|
+
url?: string | URL;
|
|
7
8
|
bundle?: string;
|
|
8
9
|
route?: string;
|
|
9
10
|
name?: string;
|
|
10
11
|
isolate?: boolean;
|
|
12
|
+
mode?: 'open' | 'closed';
|
|
13
|
+
reset?: boolean;
|
|
11
14
|
[REMOTE_COMPONENT_KEY]?: string;
|
|
12
15
|
children?: React.ReactNode;
|
|
13
16
|
}
|