在上篇docker nginx 部署 node 和前端应用,在前端应用部署的过程中总是需要经过这个过程,本地打包,
将本地打包的资源借助FileZilla FTP Client这类工具上传到服务器上 nginx 配置好的文件夹下实现前端应用的部署。
在后续开发的过程中,更新的新的前端内容总需要手动部署,总感觉有些麻烦,开始思考有没有可以采取自动化的方案来进行操作,在网上调研过一些方案,有通过 jenkins 做的部署方案,通过 github hook 在每次提交的时候 jenkins 自动进行部署,这个方案很成熟,但是这段时间正好在学习 vite,看 vite 的文档,发现 vite 的插件也可以实现这个功能。
整个插件的源码见此
插件功能分析
当 vite 构建的项目进行打包时,在打包的最后一个阶段将资源上传到服务器即可。
根据 vite 的官方文档和 rollup 的文档,发现 build 阶段的最后一个 hook 是 closeBundle

- 所以在 closeBundle 阶段进行上传资源到服务器的相关逻辑
- 上传逻辑需要连接服务器,查找到 node-ssh 这个库可以帮助进行服务器的连接,并且可以进行文件内容的上传,所以选择这个库
插件细节分析
vite 的插件是一个函数,进行资源上传需要几个配置,服务器的 host,服务器用户 username,服务器密码 password(服务器登录私钥),服务器需要上传文件的远程路径 remote path、以及本地打包的地址,vite 默认的打包地址是 dist,但是如果用户手动修改了打包的地址,那么也需要获取用户修改的配置,vite 提供了 configResolved 这个 hook,这个 hook 也可以读取打包的地址

至此,这个插件需要提供四个配置参数
- 服务器 host
- 服务器用户名 username
- 服务器密码 password(服务器私钥)
- 服务器文件夹远程地址 remotePath
至此整个插件的实现如下:
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 41 42 43 44 45 46 47
| import { Plugin, ResolvedConfig } from "vite"; import path from "path"; import { NodeSSH } from "node-ssh";
export const serverPlugin = ({ host, remotePath, username, password, }: { host: string; remotePath: string; username: string; password: string; }): Plugin => { let viteConfig: ResolvedConfig | null = null; return { name: "将本地打包文件推送到服务器上的指定路径", configResolved(resolvedConfig: ResolvedConfig) { viteConfig = resolvedConfig; }, async closeBundle() { const ssh = new NodeSSH(); await ssh.connect({ host, username, password, }); const buildPath = path.resolve(viteConfig?.build.outDir || "dist"); await ssh.execCommand(`rm -rf ${remotePath}/*`); try { await ssh.putDirectory(buildPath, remotePath, { concurrency: 10, recursive: true, }); } catch (error) { console.log(error, "上传错误"); } ssh.dispose(); }, }; };
|
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
| import { defineConfig } from "vite"; import react from "@vitejs/plugin-react"; import viteTsconfigPaths from "vite-tsconfig-paths"; import svgrPlugin from "vite-plugin-svgr"; import { serverPlugin } from "./vite.server.plugin";
export default defineConfig({ build: { outDir: "build", }, server: { open: true, }, plugins: [ react(), viteTsconfigPaths(), svgrPlugin(), serverPlugin({ host: "yourIp", serverPath: "/root/nginx/html", username: "root", password: "yourpassword", }), ], });
|