使用Vite+Vue3搭建前端SSR应用(四)应用的部署

1 引言

使用Vite+Vue3搭建前端SSR应用

相关文章

  • 使用Vite+Vue3搭建前端SSR应用(一)新建项目并配置基础环境
  • 使用Vite+Vue3搭建前端SSR应用(二)搭建SSR服务端渲染
  • 使用Vite+Vue3搭建前端SSR应用(三)SEO网页头配置
  • 使用Vite+Vue3搭建前端SSR应用(四)应用的部署

关键词

  • Vite
  • Vue
  • SSR

源代码地址
https://gitee.com/bitem/vite-vue-ssr-demo.git

2 安装依赖

yarn add path fs express
1

3 编译

// 添加命令 "build:ssr": "rimraf dist && vite-ssr build",
{
  "scripts": {
    "dev": "vite dev",
    "ssr": "vite-ssr dev",
    "build": "rimraf dist && vite build",
    "build:ssr": "rimraf dist && vite-ssr build",
    "preview": "vite preview"
  },
}
1
2
3
4
5
6
7
8
9
10

执行命令

yarn build:ssr
1

4 添加service.mjs

使用mjs是由于我使用的esmodule,如果你使用的其他规范,可以使用cjs或者js替换mjs

// 根目录 service.mjs
import path from "path"
import { fileURLToPath, URL } from 'node:url'
import express from "express"
import fs from "fs"
import renderPage from "./dist/server/main.mjs"

const dist = `./dist`

const ssr = JSON.parse(fs.readFileSync(`${dist}/server/package.json`, 'utf-8')).ssr
const manifest = JSON.parse(fs.readFileSync(`${dist}/client/ssr-manifest.json`, 'utf-8'))

const server = express()
// Serve every static asset route
for (const asset of ssr.assets || []) {
  server.use('/' + asset, express.static(fileURLToPath(new URL('./dist/client', import.meta.url)) + "/" + asset))
}

// Everything else is treated as a "rendering request"
server.get('*', async (request, response) => {
  const url = request.protocol + '://' + request.get('host') + request.originalUrl

  const { html, status, statusText, headers } = await renderPage(url, {
    manifest,
    preload: true,
    // Anything passed here will be available in the main hook
    request,
    response,
    // initialState: { ... } // <- This would also be available
  })

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

const port = 8080
server.listen(port, () => {
  console.log(`Server started: http://localhost:${port}`)
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40

5 直接部署

拷贝文件到服务器

注意:package.json中只需要六express和fs两个包即可
需要拷贝以下文件到服务器的一个空文件夹:

  • dist
  • package.json
  • service.mjs

在服务器执行命令

yarn --production
node ./service.mjs
1
2

这种方式是直接在终端前台运行node进程,不稳定,很容易断,不可取。

注意:
前面涉及的API接口地址需要改成正式可访问地址

6 Docker部署

我们使用Docker进行部署,当然也可以使用其他工具,如pm2。

保证服务器已经有了docker环境

6.1 首次部署

编写Dockerfile

FROM node:lts-alpine
ENV NODE_ENV=production
RUN mkdir -p /app
WORKDIR /app
EXPOSE 80
CMD ["node", "./service.mjs"]
1
2
3
4
5
6

将Dockerfile拷贝到服务器空文件夹并执行生成命令
docker build -t vite-vue-ssr-demo:1.0 .

编译
yarn build:ssr

新建服务器文件夹

cd /home
mkdir /home/bitem
mkdir /home/bitem/vite-vue-ssr-demo
cd /home/bitem/vite-vue-ssr-demo
1
2
3
4

拷贝文件到服务器/home/bitem/vite-vue-ssr-demo中

  • dist
  • package.json
  • restart.sh
  • service.mjs

启动容器

docker run -d --restart=always \
--network=bitem --ip=172.10.100.0 \
-v /home/bitem/vite-vue-ssr-demo:/app \
--name=vite-vue-ssr-demo vite-vue-ssr-demo:1.0
1
2
3
4

5.2 重新部署

编译
yarn build:ssr

拷贝文件到服务器/home/bitem/vite-vue-ssr-demo中

  • dist
  • package.json (可选,无新的生产依赖则不需要拷贝)
  • restart.sh (可选,无改动则不需要拷贝)
  • service.mjs (可选,无改动则不需要拷贝)

执行重启命令

cd /home/bitem-cms/web
./restart.sh
1
2

restart.sh 脚本可在源代码中找到