解决小项目中的频繁部署-适用于没有Jenkins或者没有配置流水线的前端部署

背景

对于一些演示项目,或者公司内部没有流水线的情况下,我们前端项目部署问题,需要频繁额ssh unzip等等操作极其麻烦,或者使用xftp等传出工具,也需要频繁打开客户端 或者频繁的上传拖动打包文件。

基于此,我们前端项目有没有直接再没有流水线的情况下,直接直接执行 npm run build:deploy或者 npm run build 再次 npm run deploy就直接更新服务器资源了,

以上适用用nginx部署的前端服务,每次部署完文件 不需要reload 或者 重启镜像的情况

实现

安装依赖

js 复制代码
npm i scp2 -S

package.json 中增加命令

js 复制代码
 "deploy": "node deploy.js",
  "build:deploy": "npm run build && npm run deploy",

根目录增加

deploy.js文件,你需要修改的就是 服务器的信息 以及部署的目录

js 复制代码
import scpClient from 'scp2'
import path from 'path'
import fs from 'fs'

// 服务器配置
const serverConfig = {
  host: '172.11.111.222',    // 服务器IP
  port: 111,                 // 端口
  username: 'root',          // 用户名
  password: '******',  // 密码
  path: '/aaa/bb'          // 部署路径
}

const localDistPath = path.join(process.cwd(), './dist')

if (!fs.existsSync(localDistPath)) {
  console.error('错误:dist目录不存在,请先执行构建命令')
  process.exit(1)
}

console.log(`开始上传dist文件夹到 ${serverConfig.host}:${serverConfig.path}...`)

scpClient.scp(
  localDistPath,
  serverConfig,
  (err) => {
    if (err) {
      console.error('上传失败:', err)
      process.exit(1)
    } else {
      console.log('✅ dist文件夹已成功上传到服务器!')
      process.exit(0)
    }
  }
)

更安全的SFTP

js 复制代码
import Client from 'ssh2-sftp-client'
import path from 'path'
import fs from 'fs'

// 服务器配置
const serverConfig = {
  host: '172.11.111.222',    // 服务器IP
  port: 111,                 // 端口
  username: 'root',          // 用户名
  password: '******',  // 密码
  path: '/aaa/bb'          // 部署路径
}

const localDistPath = path.join(process.cwd(), './dist')

if (!fs.existsSync(localDistPath)) {
  console.error('错误:dist目录不存在,请先执行构建命令')
  process.exit(1)
}

console.log(`开始上传 dist 文件夹到 ${serverConfig.host}:${serverConfig.path}...`)

const sftp = new Client()

sftp.connect({
  host: serverConfig.host,
  port: serverConfig.port,
  username: serverConfig.username,
  password: serverConfig.password
})
  .then(() => {
    return sftp.uploadDir(localDistPath, serverConfig.path)
  })
  .then(() => {
    console.log('✅ dist文件夹已成功上传到服务器!')
    process.exit(0)
  })
  .catch((err) => {
    console.error('上传失败:', err)
    process.exit(1)
  })
  .finally(() => {
    sftp.end() // 关闭SFTP连接
  })

安全优化

服务器信息不应该写死,且不应该传递到 仓库中,可以自己创建 环境变量写入,并忽略提交

根目录创建 .env.deploy环境配置文件

js 复制代码
# .env.deploy
VITE_SFTP_HOST=172.11.111.222
VITE_SFTP_PORT=111
VITE_SFTP_USERNAME=root
VITE_SFTP_PASSWORD=******
VITE_SFTP_REMOTE_PATH=/aaa/bb

package.json做更改

js 复制代码
 "build:deploy": "vite build && node --env-file=.env.deploy deploy.js",
    "deploy": "node --env-file=.env.deploy deploy.js",

.gitignore修改

增加 .env.deploy 忽略提交

deploy.js更改

js 复制代码
import Client from 'ssh2-sftp-client'
import path from 'path'
import fs from 'fs'

// 从环境变量获取配置
const serverConfig = {
  host: process.env.VITE_SFTP_HOST,
  port: parseInt(process.env.VITE_SFTP_PORT || '22'),
  username: process.env.VITE_SFTP_USERNAME,
  password: process.env.VITE_SFTP_PASSWORD,
  path: process.env.VITE_SFTP_REMOTE_PATH
}


const localDistPath = path.join(process.cwd(), './dist')

if (!fs.existsSync(localDistPath)) {
  console.error('错误:dist目录不存在,请先执行构建命令')
  process.exit(1)
}

console.log(`开始上传 dist 文件夹到 ${serverConfig.host}:${serverConfig.path}...`)

const sftp = new Client()

sftp.connect({
  host: serverConfig.host,
  port: serverConfig.port,
  username: serverConfig.username,
  password: serverConfig.password
})
  .then(() => {
    return sftp.uploadDir(localDistPath, serverConfig.path)
  })
  .then(() => {
    console.log('✅ dist文件夹已成功上传到服务器!')
    process.exit(0)
  })
  .catch((err) => {
    console.error('上传失败:', err)
    process.exit(1)
  })
  .finally(() => {
    sftp.end() // 关闭SFTP连接
  })

执行

1:完整流程:

  1. 先运行 vite build 构建项目
  2. 如果构建成功,自动运行部署脚本
  3. 部署脚本会读取 .env.deploy 中的敏感信息(服务器账号等)
  4. dist 目录上传到服务器

2:也可在直接一键式部署

js 复制代码
npm run build:deploy
相关推荐
大橙子额7 分钟前
【解决报错】Cannot assign to read only property ‘exports‘ of object ‘#<Object>‘
前端·javascript·vue.js
爱喝白开水a2 小时前
前端AI自动化测试:brower-use调研让大模型帮你做网页交互与测试
前端·人工智能·大模型·prompt·交互·agent·rag
董世昌412 小时前
深度解析ES6 Set与Map:相同点、核心差异及实战选型
前端·javascript·es6
吃杠碰小鸡3 小时前
高中数学-数列-导数证明
前端·数学·算法
kingwebo'sZone3 小时前
C#使用Aspose.Words把 word转成图片
前端·c#·word
xjt_09013 小时前
基于 Vue 3 构建企业级 Web Components 组件库
前端·javascript·vue.js
我是伪码农3 小时前
Vue 2.3
前端·javascript·vue.js
夜郎king4 小时前
HTML5 SVG 实现日出日落动画与实时天气可视化
前端·html5·svg 日出日落
夏幻灵5 小时前
HTML5里最常用的十大标签
前端·html·html5
Mr Xu_5 小时前
Vue 3 中 watch 的使用详解:监听响应式数据变化的利器
前端·javascript·vue.js