frandiox / vite-ssr

Use Vite for server side rendering in Node
MIT License
823 stars 91 forks source link

下面是我的报错信息 之前还能用现在就不行了 #197

Open liu-bluesky opened 1 year ago

liu-bluesky commented 1 year ago

internal/modules/cjs/loader.js:948 throw new ERR_REQUIRE_ESM(filename); ^

Error [ERR_REQUIRE_ESM]: Must use import to load ES Module: D:\work\开源\webGl\day01install\vite-ssr-demo\dist\server\main.mjs at new NodeError (internal/errors.js:322:7) at Module.load (internal/modules/cjs/loader.js:948:11) at Function.Module._load (internal/modules/cjs/loader.js:790:12) at Module.require (internal/modules/cjs/loader.js:974:19) at require (internal/modules/cjs/helpers.js:93:18) at Object. (D:\work\开源\webGl\day01install\vite-ssr-demo\server.js:21:33) at Module._compile (internal/modules/cjs/loader.js:1085:14) at Object.Module._extensions..js (internal/modules/cjs/loader.js:1114:10) at Module.load (internal/modules/cjs/loader.js:950:32) at Function.Module._load (internal/modules/cjs/loader.js:790:12) { code: 'ERR_REQUIRE_ESM'

liu-bluesky commented 1 year ago

我修改好了 手动调整成 es6导出了 这个东西可真的很难受啊

ManneW commented 1 year ago

I recently ran into the same issue. I think this might very well be related to the switch to Vite 4 and the built server bundle being an ES Module. Some more details on this can be found in this issue: https://github.com/frandiox/vite-ssr/issues/185

The real change that is required to be able to consume the built server bundle would be to switch from loading it using require() to instead do an import().

Consuming the built server bundle in an ExpressJS context could look something like this:

// This is the server renderer we just built
const renderPagePromise = import(`${dist}/server/main.mjs`).then((result) => result.default);

// ...
// Other request handlers
// ...

// When there is a "rendering request"
server.get('*', async (request, response) => {
  // Wait for that promise to resolve
  const renderPage = await renderPagePromise;
  const url = `${request.protocol}://${request.get('host')}${request.originalUrl}`;
  const {
    html, status, statusText, headers,
  } = await renderPage(url, {
    manifest,
    preload: true,
    request,
    response,
    // Anything passed here will be available in the main hook
    // initialState: { ... } // <- This would also be available
  });

  response.type('html')
  response.writeHead(status || 200, statusText || headers, headers)
  response.end(html)
});
liu-bluesky commented 1 year ago

我也调整好了,与你的差不多

// This is a simple Node server that uses the built project.
import express from 'express';
// This contains a list of static routes (assets)
// const { ssr } = require(`./dist/server/package.json`)
// import ssasa from './dist/server/package.json' 
import { readFile } from 'fs/promises'
const {ssr} = JSON.parse(
  await readFile(
    new URL('./dist/server/package.json', import.meta.url)
  )
)
const manifest = JSON.parse(
  await readFile(
    new URL(`./dist/client/ssr-manifest.json`, import.meta.url)
  )
)

import {
  default as renderPage
} from './dist/server/main.mjs';

const server = express()

for (const asset of ssr.assets || []) {
  server.use(
    '/' + asset,
    express.static(`./dist/client/` + asset)
  )
}
server.get('*', async (request, response) => {
  const url =
    request.protocol + '://' + request.get('host') + request.originalUrl
  console.log("request.path"+request.path)
  const { html, status, statusText, headers } = await renderPage(url, {
    manifest,
    preload: true,
    request,
    response,
  })

  response.writeHead(status || 200, statusText || headers, headers)
  response.end(html)

})

const port = 8080
console.log(`Server started: http://localhost:${port}`)
server.listen(port)
liu-bluesky commented 1 year ago

I recently ran into the same issue. I think this might very well be related to the switch to Vite 4 and the built server bundle being an ES Module. Some more details on this can be found in this issue: #185

The real change that is required to be able to consume the built server bundle would be to switch from loading it using require() to instead do an import().

Consuming the built server bundle in an ExpressJS context could look something like this:

// This is the server renderer we just built
const renderPagePromise = import(`${dist}/server/main.mjs`).then((result) => result.default);

// ...
// Other request handlers
// ...

// When there is a "rendering request"
server.get('*', async (request, response) => {
  // Wait for that promise to resolve
  const renderPage = await renderPagePromise;
  const url = `${request.protocol}://${request.get('host')}${request.originalUrl}`;
  const {
    html, status, statusText, headers,
  } = await renderPage(url, {
    manifest,
    preload: true,
    request,
    response,
    // Anything passed here will be available in the main hook
    // initialState: { ... } // <- This would also be available
  });

  response.type('html')
  response.writeHead(status || 200, statusText || headers, headers)
  response.end(html)
});

Hello, can you understand the text I sent? Is it Chinese that I received from you in China? The current content is English translated by the translator

liu-bluesky commented 1 year ago

Hello, can you und

Hello, can you understand the text I sent? I am in China, is it Chinese that you received? The current content is English translated by the translator

gitsheny commented 1 year ago

cjs和esm都试过都可以用