从0到1使用Vite创建一个SSR模版项目

使用Vite初始化项目模板

安装pnpm:

npm install pnpm -g 

创建Vue3 + Ts模版

pnpm create vite my-vite-vue3-ts-ssr-template --template vue-ts 

进入my-vite-vue3-ts-ssr-template目录执行pnpm install安装npm包,然后执行pnpm dev运行开发环境,可以看到如下页面:

设置开发服务器

一个典型的SSR服务目录结构是这样的:

- index.html
- server.ts # main application server
- src/
 - main.ts# 导出环境无关的(通用的)应用代码
 - entry-client.ts# 将应用挂载到一个 DOM 元素上
 - entry-server.ts# 使用某框架的 SSR API 渲染该应用 

我们首先来实现server.ts

参照官网,我们的开发服务器使用express,首先进行安装:

pnpm install express
pnpm install @types/express -D 

然后因为我们的是ts文件,服务端代码需要用到node,我们需要安装node的类型文件:

pnpm install @types/node -D 

简单的开发服务器

我们在src目录下创建一个server.ts目录,输入如下代码:

import fs from "fs";
import path from "path";
import { fileURLToPath } from "url";
import express from "express";

// 在ts文件里不能直接使用__dirname,所以需要使用这种方法
const __dirname = path.dirname(fileURLToPath(import.meta.url));

async function createServer() {const app = express();app.use("*", async (req, res) => {const html = fs.readFileSync(path.resolve(__dirname, "index.html"));res.status(200).set({ "Content-Type": "text/html" }).end(html);});app.listen(8900);console.log("Server is start at http://127.0.0.1:8900");
}

createServer(); 

这个服务的功能就是读取项目里的html文件然后返回。

使用ts-node启动服务

然后我们在package.json里添加启动脚本,启动脚本需要使用ts-node,先安装ts-node

pnpm install ts-node 

在package.json里添加:

 "scripts": {"dev": "ts-node server.ts","build": "vue-tsc && vite build","preview": "vite preview"}, 

然后执行pnpm run dev会发现如下报错

TypeError [ERR_UNKNOWN_FILE_EXTENSION]: 
Unknown file extension ".ts" for /Users/sunjunwei/Documents/mygithub/my-vite-vue3-ts-ssr-template/src/server.ts 

这时候我们将启动命令改为如下方式:

 "scripts": {"dev": "node --loader ts-node/esm server.ts",}, 

然后我们执行pnpm dev可以正确启动服务,然后访问http://127.0.0.1:8900可以拿到我们的html文件。

设置占位标记

我们在index.html文件里设置占位标记<!--ssr-outlet-->,这时的html如下:

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><link rel="icon" type="image/svg+xml" href="/vite.svg" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><title>Vite + Vue + TS</title></head><body><div id="app"><!--ssr-outlet--></div><script type="module" src="/src/main.ts"></script></body>
</html> 

我们要做的就是将ssr要渲染的内容填充到占位标记这里,我们更改server.ts如下:

import fs from "fs";
import path from "path";
import { fileURLToPath } from "url";
import express from "express";

// 在ts文件里不能直接使用__dirname,所以需要使用这种方法
const __dirname = path.dirname(fileURLToPath(import.meta.url));

async function createServer() {const app = express();app.use("*", async (req, res) => {const template = fs.readFileSync(path.resolve(__dirname, "index.html")).toString();const html = template.replace("<<img src="http://127.0.0.1:8900")" style="margin: auto" />
}

createServer(); 

这时候重启服务看到页面输出如下:

这就是SSR的基本原理,在此基础上我们来扩展功能。

使用Vite服务

我们在server.ts里加上vite提供的服务:

import fs from "fs";
import path from "path";
import { fileURLToPath } from "url";
import express from "express";

import { createServer as createViteServer } from "vite";

// 在ts文件里不能直接使用__dirname,所以需要使用这种方法
const __dirname = path.dirname(fileURLToPath(import.meta.url));

async function createServer() {const app = express();// 以中间件模式创建 Vite 应用,这将禁用 Vite 自身的 HTML 服务逻辑/
### 创建带有Vue 3、TypeScript和Vite 5的服务器端渲染(SSR项目 为了创建一个支持服务器端渲染(SSR)的Vue 3应用,使用TypeScript作为编程语言以及Vite 5作为构建工具,可以遵循如下方法: #### 初始化项目结构 首先安装`vite-plugin-vue2-ssr`插件来辅助设置SSR环境。然而对于Vue 3而言,应该关注官方推荐的方式或是社区内成熟的解决方案。 ```bash npm init vite@latest my-ssr-app --template vue-ts cd my-ssr-app ``` 这会基于模板初始化一个新的项目,其中包含了基本配置文件和支持TypeScript的基础架构[^1]。 #### 安装依赖项 接着增加必要的依赖包用于实现服务端渲染功能: ```bash npm install @vue/server-renderer express ``` 这里引入了两个主要组件:一个是来自Vue团队专门为Vue设计的服务端渲染器;另一个是Express框架,用来搭建Node.js HTTP服务器并处理请求响应逻辑。 #### 修改入口文件 调整客户端启动脚本,在`main.ts`里仅保留根实例挂载部分,并移除任何与DOM操作有关的内容以便兼容服务端执行上下文。另外新建一个名为`server-entry.ts`的服务端专用入口文件负责组装完整的HTML页面字符串输出给浏览器加载解析。 ```typescript // main.ts (Client Entry Point) import { createApp } from 'vue' import App from './App.vue' const app = createApp(App) app.mount('#app') ``` ```typescript // server-entry.ts (Server Entry Point) import { renderToString } from '@vue/server-renderer' import { createApp } from './src/main' // Adjust path according to your setup. export async function render() { const app = await createApp() return await renderToString(app) } ``` #### 构建HTTP Server 最后一步是在项目的根目录下编写简单的Express应用程序以监听特定端口等待传入连接,当接收到GET请求时调用之前定义好的render函数获取预渲染后的标记再发送回去完成整个流程闭环。 ```javascript // index.js or any other preferred filename. import express from 'express'; import { fileURLToPath } from 'url'; import { dirname, join } from 'path'; import { readFileSync } from 'fs'; import { render } from './build/server-entry.js'; // Make sure this matches the output location of built files. const isProd = process.env.NODE_ENV === 'production'; const root = dirname(fileURLToPath(import.meta.url)); const app = express(); app.use('/dist', express.static( join(root, 'dist'), !isProd && { index: false } )); app.get('*', async(req, res) => { try{ let html; if(!isProd){ // In development mode we need hot-reload capabilities so use SSR directly without bundling first. html = await render(); }else{ // For production builds load pre-built HTML string instead. html = readFileSync(join(__dirname,'./index.html'), 'utf8'); } res.setHeader('Content-Type','text/html;charset=utf-8'); res.end(html); }catch(error){ console.error(`Error during rendering : ${error}`); res.status(500).end('Internal Server Error'); } }); if (!isProd) { require('./server'); // Start Vite dev server for HMR support etc... } else { app.listen(process.env.PORT || 3000, () => console.log('Production Express server running at http://localhost:3000/') ); } ``` 上述代码片段展示了如何利用Vite的强大特性快速建立一套现代化前端开发工作流的同时兼顾高效的生产部署方案。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值