个人建站前端篇(二)项目采用服务端渲染SSR

news2024/11/22 19:42:20

SSR的优点

  1. 更好的SEO
  2. 首屏加载速度更快,用户体验更好
  3. 可以使用相同的语言以及相同的声明式、面向组件的心智模型来开发整个应用,而不需要在后端模板系统和前端框架之间来回切换。

Vue生态中的SSR通用解决方案

  • Nuxt是一个构建于 Vue 生态系统之上的全栈框架
  • Quasar是基于 Vue 的完整解决方案
  • Vite 提供了内置的 Vue 服务端渲染支持,插件使用vite-plugin-ssr
    这里采用vite进行ssr改造

项目改造

安装开发服务器所需依赖

  • sirv 是一个优化过的轻量级中间件,用来处理静态资源请求
  • compression 是一个 Node.js 的中间件,用来对 HTTP 响应进行压缩
  • express 是 Node.js 的一个轻量级的 Web 服务器框架
  • cross-env 是一个跨平台的环境变量设置和使用工具
  • vite-plugin-ssr 是一个 Vite 插件,用于在 Vue 应用中启用服务端渲染(SSR)
    执行以下命令安装依赖:
npm install sirv compression express cross-env -D

接下来对于package.json中的构建命令进行改造

"scripts": {
  "dev": "node server",
  "build": "npm run build:client && npm run build:server",
  "build:client": "vite build --ssrManifest --outDir dist/client",
  "build:server": "vite build --ssr src/entry-server.ts --outDir dist/server",
  "preview": "cross-env NODE_ENV=production node server"
}

进行代码改造,在 src 目录下新建entry-client.ts和entry-server.ts两个入口文件。
其中entry-client.ts文件内容如下

import './style.css'
import { createApp } from './main'
const { app } = createApp()
app.mount('#app')

entry-server.ts文件内容如下

import { renderToString } from 'vue/server-renderer'
import { createApp } from './main'
export async function render() {
  const { app } = createApp()
  const ctx = {}
  const html = await renderToString(app, ctx)
  return { html }
}

修改main.ts文件,将Vue应用的入口文件改为entry-server.ts。

import { createSSRApp } from 'vue'
import App from './App.vue'
export function createApp() {
  const app = createSSRApp(App)
  return { app }
}

修改index.html引入入口js路径

<div id="app"><!--app-html--></div>
<script type="module" src="/src/entry-client.ts"></script>

提示

重点来了,和不是单纯的注释,而是占位符,需要替换成实际的内容。 这里和server.js里面的设置向对应

最后在项目根目录新建启动文件server.js

import fs from 'node:fs/promises'
import express from 'express'

// Constants
const isProduction = process.env.NODE_ENV === 'production'
const port = process.env.PORT || 3000
const base = process.env.BASE || '/'

// Cached production assets
const templateHtml = isProduction
  ? await fs.readFile('./dist/client/index.html', 'utf-8')
  : ''
const ssrManifest = isProduction
  ? await fs.readFile('./dist/client/.vite/ssr-manifest.json', 'utf-8')
  : undefined

// Create http server
const app = express()

// Add Vite or respective production middlewares
let vite
if (!isProduction) {
  const { createServer } = await import('vite')
  vite = await createServer({
    server: { middlewareMode: true },
    appType: 'custom',
    base
  })
  app.use(vite.middlewares)
} else {
  const compression = (await import('compression')).default
  const sirv = (await import('sirv')).default
  app.use(compression())
  app.use(base, sirv('./dist/client', { extensions: [] }))
}

// Serve HTML
app.use('*', async (req, res) => {
  try {
    const url = req.originalUrl.replace(base, '')

    let template
    let render
    if (!isProduction) {
      // Always read fresh template in development
      template = await fs.readFile('./index.html', 'utf-8')
      template = await vite.transformIndexHtml(url, template)
      render = (await vite.ssrLoadModule('/src/entry-server.ts')).render
    } else {
      template = templateHtml
      render = (await import('./dist/server/entry-server.js')).render
    }

    const rendered = await render(url, ssrManifest)

    const html = template
      .replace(`<!--app-head-->`, rendered.head ?? '')
      .replace(`<!--app-html-->`, rendered.html ?? '')

    res.status(200).set({ 'Content-Type': 'text/html' }).end(html)
  } catch (e) {
    vite?.ssrFixStacktrace(e)
    console.log(e.stack)
    res.status(500).end(e.stack)
  }
})

// Start http server
app.listen(port, () => {
  console.log(`Server started at http://localhost:${port}`)
})

运行npm run dev启动项目,查看源代码
如下图id为app的div标签中出现对应的内容就证明实现ssr了
在这里插入图片描述

最后将项目部署到生产环境上,执行npm run build打包
将dist文件夹/package.json/server.js部署到node服务上,启动服务,访问项目,查看效果。
在这里插入图片描述
在这里插入图片描述

提示

如果不清楚如何部署node项目到服务,可以去看云风的知识库,里面有详细步骤

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1425148.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Modelarts自动学习之旅,实现智慧食堂的人脸识别提示优化

前言 最近公司食堂进行了升级&#xff0c;不但餐盘更换为智能餐盘&#xff0c;且结账的时候可以刷脸支付。 这些升级让排队结账的速度提升了很多&#xff0c;且食堂员工效率也随之提高了很多。果然&#xff0c;科技改变世界。 我观察了一下&#xff0c;智能餐盘基本没有卡顿…

最新2024如何解决谷歌浏览器Chrome谷歌翻译无法使用问题

快速恢复谷歌浏览器一键翻译功能在Chrome 中安装好【翻译】插件 Macbook 操作步骤&#xff1a; 1点击“前往”&#xff0c;打开“前往文件夹” 2 在对话框中输入“/etc” 囝找到“hosts”文件&#xff0c;复制粘贴到桌面 3 在复制的文件最后新起一行&#xff0c;输入并保存&am…

UnityShader(十二)实现标准光照模型中的高光反射

目录 基本光照模型中的高光反射公式&#xff1a; 逐顶点光照 逐像素光照 基本光照模型中的高光反射公式&#xff1a; 从公式可以看出 要计算高光反射需要知道四个参数&#xff1a;入射光线的颜色和强度clight&#xff0c;材质的高光反射系数mspecular&#xff0c;视角方向v以…

怿星科技荣膺星河智联“2023年度卓越供应商”,共创智能座舱新未来

1月19日&#xff0c;在星河智联2023年度卓越供应商评选活动中&#xff0c;怿星科技凭借卓越的产品和优质的服务&#xff0c;以及在项目管理、设计开发和成本控制等多方面的出色表现&#xff0c;荣获了“年度卓越供应商”的荣誉称号。 添加图片注释&#xff0c;不超过 140 字&am…

UML/SysML建模工具更新情况(截至2024年1月)(2)Papyrus 6.6.0

工具最新版本&#xff1a;drawio-desktop 23.0.2 更新时间&#xff1a;2024年1月25日 工具简介 开源绘图工具&#xff0c;用Electron编写&#xff0c;跨平台&#xff0c;支持UML。桌面版和在线版现在版本号已统一。在线版&#xff1a;Flowchart Maker & Online Diagram S…

oracle数据库慢查询SQL

目录 场景&#xff1a; 环境&#xff1a; 慢SQL查询一&#xff1a; 问题一&#xff1a;办件列表查询慢 分析&#xff1a; 解决方法&#xff1a; 问题二&#xff1a;系统性卡顿 分析&#xff1a; 解决方法&#xff1a; 慢SQL查询二 扩展&#xff1a; 场景&#xff1a; 线…

Uniapp登录页面获取头像、昵称的最新方法的简单使用

前言 写小程序写到登录页面的时候&#xff0c;发现官方文档中原来的wx.getUserInfo和wx.getUserProfile不太能用了&#xff0c;学习了相对比较新的方法&#xff0c;这种方法的文档链接如下&#xff1a; https://developers.weixin.qq.com/miniprogram/dev/framework/open-abil…

免费的ChatGPT网站 ( 7个 )

ChatGPT的核心功能是基于用户在输入时的语言或文本生成相应的回复或继续内容。此外&#xff0c;它还能够完成多种任务&#xff0c;如撰写邮件、视频脚本、文案、翻译、代码编写以及撰写论文等。 博主归纳总结了7个国内非常好用&#xff0c;而且免费的chatGPT网站&#xff0c;AI…

Camunda ScriptTask SendTask ReceiveTask操作

文章目录 开始脚本任务(ScriptTask)发送任务(SendTask)接收任务(ReceiveTask)流程图xml 开始 前面我们已经介绍了Camunda最基本的操作和常见的监听器&#xff0c;如果不熟悉Camunda&#xff0c;可以先看一下&#xff0c;方便搭建环境&#xff0c;亲手测试。 Camunda组件与服务…

轻量式RPC调用日志链路设计方案

导语: 调用链跟踪系统,又称为tracing&#xff0c;是微服务设计架构中&#xff0c;从系统层面对整体的monitoring和profiling的一种技术手 背景说明 由于我们的项目是微服务方向&#xff0c;中后台服务调用链路过深&#xff0c;追踪路径过长&#xff0c;其中某个服务报错或者异…

YOLOv5改进芒果首发:24年最新论文Shift-ConvNets:稀疏/移位操作让小卷积核也能达到大卷积核效果,来打造新颖YOLOv5检测器

💡本篇内容:YOLOv5改进芒果首发:24年最新论文Shift-ConvNets:稀疏/移位操作让小卷积核也能达到大卷积核效果,来打造新颖YOLOv5检测器 💡附改进源代码及教程,用来改进作为 🚀改进Shift-ConvNets 深圳大学出品!!24年最新论文 Shift-ConvNets地址:https://arxiv.o…

c/c++串的链式操作

文章目录 1.链式串的定义2.初始化3.赋值为04.赋值操作5.打印操作6.源码 本篇博客中都是带头结点的串。 1.链式串的定义 这里的数据域是4个字节&#xff0c;是为了节省空间。 typedef struct StringNode{char ch[4]; //按串长分配存储区&#xff0c;ch指向串的基地址struct S…

史诗级详细离线更新centos系统的openssh,升级到9.3p1!!

离线更新openssh步骤 文章目录 前言一、openssh是什么?二、更新步骤 1.查看相关组件版本是否存在(代码包已全部打包)2.进行openssh离线更新总结(安装时可能出现的问题等)前言 对于可能很多人在离线更新openssh时都没找到一篇能解决实际问题的文章,那么今天它来了,请往下看…

安卓相对布局RelativeLayout

<?xml version"1.0" encoding"utf-8"?> <RelativeLayout xmlns:android"http://schemas.android.com/apk/res/android"android:layout_width"match_parent"android:layout_height"150dp"><TextViewandroid…

PostgreSql和Oracle的事务机制区别以及对程序的影响

前言 几年前IT信息产业的一些核心技术包括架构、产品以及生态都是国外制定&#xff0c;然而自从“遥遥领先”公司被制裁后&#xff0c;国家开始大力支持信息产业“新基建”&#xff0c;自2020年开始市场上涌现出了大量的国产化软件&#xff0c;就国产化数据库而言我所在的公司…

vue2+html2pdf下载PDF,PDF分页切割

问题: PDF下载下来后,文档内容被暴力分割。 解决方案: HTML <!-- 打印按钮 --> <el-button type="primary" size="small" class="el-icon-download right_btn" @click="downloadPDF">PDF</el-button><!-- …

Windows存储空间不足局域网文件共享 Dism备份系统空间不足

问题情景 在日常使用中难免遇到Windows的空间不足的情况&#xff0c;常用办法是清理垃圾释放空间&#xff0c;部分场景例如我们需要使用Dism备份完整系统&#xff0c;所以需要非常大的存储空间不够&#xff0c;如果空间不够什么才是最有效的方案呢&#xff1f; 我们假设身边没有…

字符串转换const char* , char*,QByteArray,QString,string相互转换,支持中文

文章目录 1.char * 与 const char * 的转换2.QByteArray 与 char* 的转换3.QString 与 QByteArray 的转换4.QString 与 string 的转换5.QString与const string 的转换6.QString 与 char* 的转换 在开发中&#xff0c;经常会遇到需要将数据类型进行转换的情况&#xff0c;下面依…

伪原创生成器手机版,移动端上写文章更方便!

伪原创生成器虽然不少&#xff0c;但我们大家见到最多的还是电脑使用版&#xff0c;然而提及到伪原创生成器手机版的资源却不是那么多&#xff0c;特别是对于现在手机端也成为了大家办公的一大途径&#xff0c;这主要也是因为手机的便携性&#xff0c;它可以做到让大家随时随地…

【图例】直观的感受MySQL事务的隔离级别分别解决了什么问题?以及如何查看和设置事务隔离级别!

目录 前言一、读未提交&#xff08;Read Uncommitted&#xff09;二、读已提交&#xff08;Read Committed&#xff09;三、可重复读&#xff08;Repeatable Read&#xff09;四、串行化&#xff08;Serializable&#xff09; 前言 在MySQL中&#xff0c;事务的隔离级别决定了…