vikejs / vike

🔨 Flexible, lean, community-driven, dependable, fast Vite-based frontend framework.
https://vike.dev
MIT License
4.33k stars 348 forks source link

not working in vike with fastify and https #1683

Closed rockey2020 closed 4 months ago

rockey2020 commented 4 months ago

Description

/usr/local/bin/yarn run start:dev

> vite-project@1.0.0 server:dev
> NODE_OPTIONS="--loader ts-node/esm --no-warnings --inspect --experimental-specifier-resolution=node" node --env-file=./.env --env-file=./.env.development ./server/index.ts

Debugger listening on ws://127.0.0.1:9229/19a3216e-ebc9-44ae-9eb0-53d56a27eac3
For help, see: https://nodejs.org/en/docs/inspector
https://localhost:9000
2:17:38 PM [vike][request(1)] HTTP request: /
[14:17:38.890] ERROR (4974): Could not convert argument of type symbol to string.
    reqId: "req-1"
    req: {
      "method": "GET",
      "url": "/",
      "hostname": "localhost:9000",
      "remoteAddress": "::1",
      "remotePort": 56886
    }
    res: {
      "statusCode": 500
    }
    err: {
      "type": "TypeError",
      "message": "Could not convert argument of type symbol to string.",
      "stack":
          TypeError: Could not convert argument of type symbol to string.
              at Object.webidl.converters.DOMString (node:internal/deps/undici/undici:1977:15)
              at webidl.converters.ByteString (node:internal/deps/undici/undici:1982:35)
              at Object.record<ByteString, ByteString> (node:internal/deps/undici/undici:1894:30)
              at Object.webidl.converters.HeadersInit (node:internal/deps/undici/undici:3424:67)
              at new Headers (node:internal/deps/undici/undici:3278:36)
              at normalizeHeaders (file:///Users/rockey/WebstormProjects/darwin.node/node_modules/vike/dist/esm/utils/normalizeHeaders.js:6:29)
              at getPageContextInitEnhanced (file:///Users/rockey/WebstormProjects/darwin.node/node_modules/vike/dist/esm/node/runtime/renderPage/renderPageAlreadyRouted.js:152:23)
              at getPageContextInitEnhancedSSR (file:///Users/rockey/WebstormProjects/darwin.node/node_modules/vike/dist/esm/node/runtime/renderPage.js:301:37)
              at renderPageAlreadyPrepared (file:///Users/rockey/WebstormProjects/darwin.node/node_modules/vike/dist/esm/node/runtime/renderPage.js:113:41)
              at renderPageAndPrepare (file:///Users/rockey/WebstormProjects/darwin.node/node_modules/vike/dist/esm/node/runtime/renderPage.js:99:18)
    }

const commonFastifyOptions: InitFastifyOptions = {
  http2: true,
  https: {
    allowHTTP1: true,
    keepAlive: true,
    minVersion: "TLSv1.3",
    key: readFileSync(`${serverDir}/ssl/private.key`),
    cert: readFileSync(`${serverDir}/ssl/certificate.crt`),
    ca: readFileSync(`${serverDir}/ssl/certificate.crt`),
    dhparam: readFileSync(`${serverDir}/ssl/dhparam.pem`),
  },
};
export const renderer = async (
  app: MyFastifyInstance,
  isProduction: boolean,
  https: InitFastifyOptions["https"],
) => {
  if (!isProduction) {
    const viteDevMiddleware = (
      await vite.createServer({
        root: projectDir,
        server: {
          middlewareMode: true,
          https: { key: https.key, cert: https.cert },
        },
      })
    ).middlewares;

    app.addHook("onRequest", async (request, reply) => {
      const next = () => {
        return new Promise<void>((resolve) => {
          viteDevMiddleware(request.raw, reply.raw, () => {
            resolve();
          });
        });
      };
      await next();
    });
  }

  app.get("*", async (request, reply) => {
    const pageContextInit = {
      urlOriginal: request.raw.url || "",
      headersOriginal: request.raw.headers || {},
    };
    const pageContext = await renderPage(pageContextInit);

    const { httpResponse } = pageContext;

    if (!httpResponse) {
      return reply.notFound();
    }

    const { statusCode, headers } = httpResponse;
    headers.forEach(([name, value]) => reply.raw.setHeader(name, value));
    reply.status(statusCode);
    try {
      await httpResponse.pipe(reply.raw);
    } catch (e) {
      return reply.notFound();
    }
  });
};
import { Layout } from "./Layout";
import { escapeInject } from "vike/server";
import type { OnRenderHtmlAsync } from "vike/types";
import { renderToStream } from "react-streaming/server";

export const onRenderHtml: OnRenderHtmlAsync = async (
  pageContext,
): ReturnType<OnRenderHtmlAsync> => {
  if (!pageContext.Page) {
    throw new Error("pageContext.page未定义");
  }

  const htmlStream = await renderToStream(
    <Layout pageContext={pageContext}></Layout>,
    { userAgent: pageContext.headers["user-agent"] },
  );

  const documentHtml = escapeInject`
<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8"/>
    <meta content="IE=edge" http-equiv="X-UA-Compatible">
    <meta content="portrait" name="x5-orientation">
    <meta content="portrait" name="screen-orientation">
    <meta content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no, viewport-fit=cover"
          name="viewport">
    <meta content="telephone=no" name="format-detection">
    <meta content="yes" name="apple-mobile-web-app-capable">
    <meta content="yes" name="mobile-web-app-capable">
    <title></title>
</head>
<body>
<div id="react-root">${htmlStream}</div>
</body>
</html>
`;

  return {
    documentHtml,
    pageContext: {},
  };
};
rockey2020 commented 4 months ago
const pageContextInit = {
      urlOriginal: request.raw.url || "",
      headersOriginal: {},
    };

    Object.keys(request.raw.headers)
      .filter((name) => !name.startsWith(":"))
      .forEach((name) => {
        pageContextInit.headersOriginal[name] = request.raw.headers[name];
      });

i find my way

brillout commented 4 months ago

Fix pre-released as 0.4.174-commit-8abdb8f.