entry-server.js 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869
  1. import { createApp } from './main'
  2. import { renderToString } from 'vue/server-renderer'
  3. import path, { basename } from 'path'
  4. export async function render(url, manifest) {
  5. const { app, router } = createApp()
  6. // set the router to the desired URL before rendering
  7. router.push(url)
  8. await router.isReady()
  9. // passing SSR context object which will be available via useSSRContext()
  10. // @vitejs/plugin-vue injects code into a component's setup() that registers
  11. // itself on ctx.modules. After the render, ctx.modules would contain all the
  12. // components that have been instantiated during this render call.
  13. const ctx = {}
  14. const html = await renderToString(app, ctx)
  15. // the SSR manifest generated by Vite contains module -> chunk/asset mapping
  16. // which we can then use to determine what files need to be preloaded for this
  17. // request.
  18. const preloadLinks = renderPreloadLinks(ctx.modules, manifest)
  19. return [html, preloadLinks]
  20. }
  21. function renderPreloadLinks(modules, manifest) {
  22. let links = ''
  23. const seen = new Set()
  24. modules.forEach((id) => {
  25. const files = manifest[id]
  26. if (files) {
  27. files.forEach((file) => {
  28. if (!seen.has(file)) {
  29. seen.add(file)
  30. const filename = basename(file)
  31. if (manifest[filename]) {
  32. for (const depFile of manifest[filename]) {
  33. links += renderPreloadLink(depFile)
  34. seen.add(depFile)
  35. }
  36. }
  37. links += renderPreloadLink(file)
  38. }
  39. })
  40. }
  41. })
  42. return links
  43. }
  44. function renderPreloadLink(file) {
  45. if (file.endsWith('.js')) {
  46. return `<link rel="modulepreload" crossorigin href="${file}">`
  47. } else if (file.endsWith('.css')) {
  48. return `<link rel="stylesheet" href="${file}">`
  49. } else if (file.endsWith('.woff')) {
  50. return ` <link rel="preload" href="${file}" as="font" type="font/woff" crossorigin>`
  51. } else if (file.endsWith('.woff2')) {
  52. return ` <link rel="preload" href="${file}" as="font" type="font/woff2" crossorigin>`
  53. } else if (file.endsWith('.gif')) {
  54. return ` <link rel="preload" href="${file}" as="image" type="image/gif">`
  55. } else if (file.endsWith('.jpg') || file.endsWith('.jpeg')) {
  56. return ` <link rel="preload" href="${file}" as="image" type="image/jpeg">`
  57. } else if (file.endsWith('.png')) {
  58. return ` <link rel="preload" href="${file}" as="image" type="image/png">`
  59. } else {
  60. // TODO
  61. return ''
  62. }
  63. }