diff options
-rw-r--r-- | examples/next/package.json | 4 | ||||
-rw-r--r-- | packages/bun-framework-next/client.development.tsx | 123 | ||||
-rw-r--r-- | packages/bun-framework-next/fallback.development.tsx | 1 | ||||
-rw-r--r-- | packages/bun-framework-next/renderDocument.tsx | 38 |
4 files changed, 37 insertions, 129 deletions
diff --git a/examples/next/package.json b/examples/next/package.json index bec686b60..3963ff5cc 100644 --- a/examples/next/package.json +++ b/examples/next/package.json @@ -4,8 +4,8 @@ "main": "index.js", "dependencies": { "next": "^12.1.0", - "react": "^18", - "react-dom": "^18", + "react": "^17", + "react-dom": "^17", "react-is": "^17.0.2" }, "devDependencies": { diff --git a/packages/bun-framework-next/client.development.tsx b/packages/bun-framework-next/client.development.tsx index fd8e43a20..1c51a97e8 100644 --- a/packages/bun-framework-next/client.development.tsx +++ b/packages/bun-framework-next/client.development.tsx @@ -41,8 +41,6 @@ import { createRouter, makePublicRouterInstance, } from "next/dist/client/router"; -import { packageVersion } from "macro:./packageVersion"; -import NextHead from "next/head"; export const emitter: MittEmitter<string> = mitt(); @@ -63,7 +61,6 @@ function nextDataFromBunData() { const { router: { routes, route, params: paramsList }, } = globalThis.__BUN_DATA__; - const appStyles = globalThis.__BUN_APP_STYLES || []; const paramsMap = new Map(); for (let i = 0; i < paramsList.keys.length; i++) { @@ -79,19 +76,8 @@ function nextDataFromBunData() { Object.assign(params, Object.fromEntries(paramsMap.entries())); const pages = routes.keys.reduce((acc, routeName, i) => { - if (!routes.values[i].startsWith("/_next/")) { - routes.values[i] = - "/_next/" + - routes.values[i].substring(routes.values[i].startsWith("/") ? 1 : 0); - } - const routePath = routes.values[i]; - if (routeName === "/_app" && appStyles.length) { - acc[routeName] = [routePath, ...appStyles]; - } else { - acc[routeName] = [routePath]; - } - + acc[routeName] = [routePath]; return acc; }, {}); @@ -122,11 +108,6 @@ const data: NEXT_DATA & { pages: Record<string, string[]> } = nextDataTag ? JSON.parse(document.getElementById("__NEXT_DATA__")!.textContent!) : nextDataFromBunData(); -var headManager: { - mountedInstances: Set<unknown>; - updateHead: (head: JSX.Element[]) => void; -} = initHeadManager(); - window.__NEXT_DATA__ = data; const { @@ -161,33 +142,19 @@ if (hasBasePath(asPath)) { asPath = delBasePath(asPath); } -window.__DEV_PAGES_MANIFEST = pages; export const pageLoader: PageLoader = new PageLoader(buildId, prefix, pages); +const headManager: { + mountedInstances: Set<unknown>; + updateHead: (head: JSX.Element[]) => void; +} = initHeadManager(); + export let router: Router; let CachedApp: AppComponent = null; -var ranBoot = false; + export default function boot(EntryPointNamespace) { - if (ranBoot) return; - ranBoot = true; - switch (document.readyState) { - case "loading": { - document.addEventListener( - "DOMContentLoaded", - () => boot(EntryPointNamespace), - { - once: true, - passive: true, - } - ); - break; - } - case "interactive": - case "complete": { - return _boot(EntryPointNamespace, false); - } - } + _boot(EntryPointNamespace, false); } class Container extends React.Component<{ @@ -313,9 +280,7 @@ class BootError extends Error { } export async function _boot(EntryPointNamespace, isError) { - NextRouteLoader.getClientBuildManifest = () => { - return Promise.resolve({}); - }; + NextRouteLoader.getClientBuildManifest = () => Promise.resolve({}); const PageComponent = EntryPointNamespace.default; @@ -326,7 +291,6 @@ export async function _boot(EntryPointNamespace, isError) { // @ts-expect-error CachedApp = NextApp; CachedComponent = PageComponent; - const styleSheets = []; if (appScripts && appScripts.length > 0) { let appSrc; @@ -338,7 +302,6 @@ export async function _boot(EntryPointNamespace, isError) { } if (appSrc) { - const initialHeadCount = document?.head?.children?.length ?? 0; const AppModule = await import(appSrc); console.assert( @@ -349,50 +312,9 @@ export async function _boot(EntryPointNamespace, isError) { if ("default" in AppModule) { CachedApp = AppModule.default; } - - if (pageLoader.cssQueue.length > 0) { - await Promise.allSettled(pageLoader.cssQueue.slice()); - pageLoader.cssQueue.length = 0; - } - - const newCount = document?.head?.children?.length ?? 0; - if (newCount > initialHeadCount && newCount > 1) { - // Move any <App />-inserted nodes to the beginning, preserving the order - // This way if there are stylesheets they appear in the expected order - var firstNonMetaTag = document.head.children.length; - - for (let i = 0; i < document.head.childNodes.length; i++) { - if (document.head.children[i].tagName !== "META") { - firstNonMetaTag = i; - break; - } - } - - if (firstNonMetaTag !== document.head.children.length) { - outer: for (let i = newCount - 1; i > initialHeadCount - 1; i--) { - const node = document.head.children[i]; - if ( - node.tagName === "LINK" && - node.hasAttribute("href") && - node.href - ) { - const normalized = new URL(node.href, location.origin).href; - for (let script of appScripts) { - if (new URL(script, location.origin).href === normalized) - continue outer; - } - - appScripts.push(normalized); - } - styleSheets.push(node); - } - } - } } } - headManager = initHeadManager(); - router = createRouter(page, query, asPath, { initialProps: hydrateProps, pageLoader, @@ -434,27 +356,12 @@ export async function _boot(EntryPointNamespace, isError) { domEl = nextEl; } - const StylePreserver = () => { - React.useEffect(() => { - for (let i = 0; i < styleSheets.length; i++) { - if (!document.head.contains(styleSheets[i])) { - document.head.appendChild(styleSheets[i]); - } - } - }, []); - - return null; - }; - const reactEl = ( - <> - <TopLevelRender - App={CachedApp} - Component={PageComponent} - props={hydrateProps} - /> - <StylePreserver /> - </> + <TopLevelRender + App={CachedApp} + Component={PageComponent} + props={hydrateProps} + /> ); if (USE_REACT_18) { @@ -529,7 +436,7 @@ export function renderError(e) { } globalThis.next = { - version: packageVersion("next"), + version: "12.0.4", emitter, render, renderError, diff --git a/packages/bun-framework-next/fallback.development.tsx b/packages/bun-framework-next/fallback.development.tsx index 67a6a387f..4db94e5d5 100644 --- a/packages/bun-framework-next/fallback.development.tsx +++ b/packages/bun-framework-next/fallback.development.tsx @@ -59,6 +59,7 @@ function renderFallback({ router }: FallbackMessageContainer) { document.removeEventListener("onimportcss", insertGlobalStyleSheet); document.addEventListener("onimportcss", pageLoader.onImportCSS); + var cssQueue; return import(route) .then((Namespace) => { diff --git a/packages/bun-framework-next/renderDocument.tsx b/packages/bun-framework-next/renderDocument.tsx index 694cb5f8c..c48040b27 100644 --- a/packages/bun-framework-next/renderDocument.tsx +++ b/packages/bun-framework-next/renderDocument.tsx @@ -4,7 +4,7 @@ import { HeadManagerContext } from "next/dist/shared/lib/head-manager-context"; import Loadable from "next/dist/shared/lib/loadable"; import { LoadableContext } from "next/dist/shared/lib/loadable-context"; import { RouterContext } from "next/dist/shared/lib/router-context"; -import { type NextRouter } from "next/dist/shared/lib/router/router"; +import type { NextRouter } from "next/dist/shared/lib/router/router"; import { getDisplayName, loadGetInitialProps, @@ -262,7 +262,7 @@ function renderDocument( ...docProps, }; - return ReactDOMServer.renderToString( + return ReactDOMServer.renderToStaticMarkup( <AmpStateContext.Provider value={ampState}> {/* HTMLContextProvider expects useMainContent */} {/* @ts-expect-error */} @@ -306,9 +306,16 @@ class ServerRouter implements NextRouter { isLocaleDomain?: boolean ) { this.route = pathname.replace(/\/$/, "") || "/"; - this.pathname = pathname; + this.pathname = new URL( + pathname || "/", + Bun.origin || "http://localhost:3000" + ).href; + this.query = query; - this.asPath = as; + this.asPath = new URL( + as || "/", + Bun.origin || "http://localhost:3000" + ).href; this.isFallback = isFallback; this.basePath = basePath; this.locale = locale; @@ -419,7 +426,7 @@ export async function render({ const getStaticProps = (PageNamespace as any)?.getStaticProps || null; const { default: AppComponent_ } = AppNamespace || {}; var query = Object.assign({}, route.query); - const origin = ""; + const origin = Bun.origin; // These are reversed in our Router versus Next.js...mostly due to personal preference. const pathname = route.name; @@ -787,13 +794,13 @@ export async function render({ }, // Only enabled in production as development mode has features relying on HMR (style injection for example) // @ts-expect-error - unstable_runtimeJS: false, + unstable_runtimeJS: true, // process.env.NODE_ENV === "production" // ? pageConfig.unstable_runtimeJS // : undefined, // unstable_JsPreload: pageConfig.unstable_JsPreload, // @ts-expect-error - unstable_JsPreload: false, + unstable_JsPreload: true, dangerousAsPath: router.asPath, ampState: undefined, props, @@ -822,20 +829,13 @@ export async function render({ }); // __NEXT_BODY_RENDER_TARGET__ html = appendNextBody(html, docProps.html); - + html = html + .replaceAll('"/_next/http://', '"http://') + .replaceAll('"/_next/https://', '"https://'); if (responseHeaders) { - return new Response( - html - .replaceAll("/_next/http://", "http://") - .replaceAll("/_next/https://", "https://"), - { headers: responseHeaders } - ); + return new Response(html, { headers: responseHeaders }); } else { - return new Response( - html - .replaceAll("/_next/http://", "http://") - .replaceAll("/_next/https://", "https://") - ); + return new Response(html); } } |