littlebot
Published on 2025-04-13 / 0 Visits
0

【源码】基于Vue 3和Vite的服务器端渲染(SSR)项目

项目简介

本项目是一个基于Vue 3和Vite的服务器端渲染(SSR)应用,借助Vue 3的强大功能与Vite的快速构建能力,结合Koa2作为服务器端框架,打造出首屏加载速度快、SEO友好的Web应用开发框架。

项目的主要特性和功能

  • 服务器端渲染(SSR):实现首屏快速加载,利于SEO优化。
  • Vue 3:运用Composition API和响应式系统,开发更灵活高效。
  • Vite:利用其快速开发和构建能力,提升开发效率。
  • Koa2:作为服务器端框架,提供轻量级、高性能的服务器环境。
  • Pinia:集成该状态管理工具,提供简单高效的状态管理方案。
  • Vue Router:实现前端路由管理。
  • TypeScript:进行类型检查,提升代码质量和可维护性。

安装使用步骤

1. 初始化项目

使用pnpm创建并初始化项目: shell pnpm create vite koa2-ssr-vue3-ts-pinia -- --template vue-ts

2. 修改客户端入口

修改~/src/main.ts文件,创建SSR应用实例: ```ts import { createSSRApp } from "vue"; import App from "./App.vue";

export const createApp = () => { const app = createSSRApp(App); return { app }; } 新建`~/src/entry-client.ts`文件,挂载Vue应用:ts import { createApp } from "./main"

const { app } = createApp();

app.mount("#app"); 修改`~/index.html`文件,设置入口:html

... ...

```

3. 创建开发服务器

安装Koa2及相关中间件: shell pnpm i koa --save && pnpm i @types/koa --save-dev pnpm i koa-connect --save 新建~/server.js文件,配置Koa2服务器: ```js const Koa = require('koa'); const fs = require('fs'); const path = require('path');

(async () => { const app = new Koa();

const template = fs.readFileSync(path.resolve(__dirname, 'index.html'), 'utf-8');

app.use(async (ctx) => {
    let vueTemplate = '<h1 style="text-align:center;">现在假装这是一个vue模板</h1>';
    let html = template.replace('<!--app-html-->', vueTemplate);
    ctx.body = html;
});

app.listen(9000, () => {
    console.log('server is listening in 9000');
});

})(); ```

4. 新增服务端入口

安装@vue/server-renderershell pnpm i @vue/server-renderer --save 新建~/src/entry-server.ts文件,配置服务端渲染: ```ts import { createApp } from './main'; import { renderToString } from '@vue/server-renderer';

export const render = async () => { const { app } = createApp(); const renderCtx: {modules?: string[]} = {} let renderedHtml = await renderToString(app, renderCtx) return { renderedHtml }; } ```

5. 注入Vite

修改~/server.js文件,集成Vite: ```js const fs = require('fs') const path = require('path') const Koa = require('koa') const koaConnect = require('koa-connect') const vite = require('vite')

;(async () => { const app = new Koa(); const viteServer = await vite.createServer({ root: process.cwd(), logLevel: 'error', server: { middlewareMode: true } }) app.use(koaConnect(viteServer.middlewares))

app.use(async ctx => {
    try {
        let template = fs.readFileSync(path.resolve(__dirname, 'index.html'), 'utf-8');
        template = await viteServer.transformIndexHtml(ctx.path, template)
        const { render } = await viteServer.ssrLoadModule('/src/entry-server.ts')
        const { renderedHtml } = await render(ctx, {})
        const html = template.replace('<!--app-html-->', renderedHtml)
        ctx.type = 'text/html'
        ctx.body = html
    } catch (e) {
        viteServer && viteServer.ssrFixStacktrace(e)
        console.log(e.stack)
        ctx.throw(500, e.stack)
    }
})

app.listen(9000, () => {
    console.log('server is listening in 9000');
});

})() ```

6. 添加开发环境

修改package.json,添加构建和运行脚本: json { "scripts": { "dev": "node server-dev.js", "server": "node server-prod.js", "build": "pnpm build:client && pnpm build:server", "build:client": "vite build --outDir dist/client", "build:server": "vite build --ssr src/entry-server.js --outDir dist/server" } }

7. 预加载

package.json中添加预加载指令: json { "scripts": { "build:client": "vite build --ssrManifest --outDir dist/client" } }entry-server.ts中添加解析预加载链接的方法: ```ts function renderPreloadLinks(modules: undefined | string[], manifest: Record): string { let links = ''; const seen = new Set(); if (modules === undefined) throw new Error(); modules.forEach((id) => { const files = manifest[id]; if (files) { files.forEach((file) => { if (!seen.has(file)) { seen.add(file); links += renderPreloadLink(file); } }); } }); return links; }

function renderPreloadLink(file: string): string { if (file.endsWith('.js')) { return <link rel="modulepreload" crossorigin href="${file}">; } else if (file.endsWith('.css')) { return <link rel="stylesheet" href="${file}">; } else { return ''; } } ```

8. 集成Vue Router

安装Vue Router: shell pnpm i vue-router --save 配置路由文件src/router/index.ts: ```ts import { createRouter, createMemoryHistory, createWebHistory, Router } from 'vue-router';

export const createRouter = (type: 'client' | 'server'): Router => createRouter({ history: type === 'client' ? createWebHistory() : createMemoryHistory(), routes: [ { path: '/', name: 'index', component: () => import('@/pages/index.vue') }, ] }); ```

9. 集成Pinia

安装Pinia: shell pnpm i pinia --save 配置Pinia状态管理: ```ts import { createPinia } from 'pinia'; import useUserStore from './user';

export default () => { const pinia = createPinia(); useUserStore(pinia); return pinia; }; ```

10. 运行项目

在开发环境运行: shell pnpm run dev 在生产环境运行: shell pnpm run build pnpm run server

下载地址

点击下载 【提取码: 4003】【解压密码: www.makuang.net】