前端代码一键打包上传服务器?10分钟配好永久告别手动部署!

搞了一个服务器准备折腾一下,但是每次打包用FTP一个个传文件太麻烦了。 受不了于是准备搞个脚本自动部署下。

于是乎,我今天教你配一套自动化部署脚本 ,以后改完代码直接一个命令npm run deploy,喝杯咖啡十分钟的功夫,就自动打包部署完了。

第一步:配置免密登录

让本地电脑和服务器之间建立信任关系,不然每次上传都要输密码,烦都烦死。

本地生成密钥(如果你之前没搞过的话):

bash 复制代码
ssh-keygen -t rsa -b 4096 -C "your-email@example.com"

一路回车就行。这就像给你的电脑办了张身份证。

查看刚生成的密钥

bash 复制代码
cat ~/.ssh/id_rsa.pub

会出来一长串字符,全选复制它!这是你电脑的"身份证号"。

登录服务器添加信任

bash 复制代码
ssh username@your-server-ip

输完密码进去后,执行下面这几条命令:

bash 复制代码
# 创建存放密钥的文件夹
mkdir -p ~/.ssh

# 设置文件夹权限
chmod 700 ~/.ssh

# 把刚才复制的公钥粘贴进去
echo "粘贴你刚才复制的那一长串" >> ~/.ssh/authorized_keys

# 设置密钥文件权限
chmod 600 ~/.ssh/authorized_keys

测试一下有没有配好 :退出服务器后重新执行ssh username@your-server-ip,如果不用输密码直接进去了,那就成了!

第二步:部署脚本

在项目根目录新建一个deploy。js文件,直接把下面代码复制进去:

javascript 复制代码
// deploy.js - 完整的部署脚本(直接上传文件版本)
import { execSync } from 'child_process'
import fs from 'fs'
import path from 'path'

// 配置信息 - 根据你的实际情况修改
const config = {
  server: 'username@your-server-ip', // 替换为你的服务器信息
  deployPath: 'yourpath'
}

// 彩色日志
const colors = {
  reset: '\x1b[0m',
  red: '\x1b[31m',
  green: '\x1b[32m',
  yellow: '\x1b[33m',
  blue: '\x1b[34m'
}

function log(message, color = colors.reset) {
  console.log(color + message + colors.reset)
}

function runCommand(command, description) {
  log(`📝 ${description}`, colors.blue)
  log(`  执行: ${command}`, colors.yellow)

  try {
    const output = execSync(command, { stdio: 'inherit' })
    log(`✅ ${description} 成功`, colors.green)
    return true
  } catch (error) {
    log(`❌ ${description} 失败: ${error.message}`, colors.red)
    return false
  }
}

// 递归获取目录中的所有文件
function getAllFiles(dirPath, arrayOfFiles = []) {
  const files = fs.readdirSync(dirPath)

  files.forEach((file) => {
    const fullPath = path.join(dirPath, file)
    if (fs.statSync(fullPath).isDirectory()) {
      arrayOfFiles = getAllFiles(fullPath, arrayOfFiles)
    } else {
      arrayOfFiles.push(fullPath)
    }
  })

  return arrayOfFiles
}

// 主部署函数
async function deploy() {
  log('🚀 开始直接文件上传部署流程', colors.blue)
  log('='.repeat(50))

  // 1. 检查 dist 目录是否存在,如果不存在则构建
  if (!fs.existsSync('dist')) {
    log('📦 dist 目录不存在,开始构建项目...', colors.yellow)
    if (!runCommand('npm run build', '项目构建')) {
      return
    }
  } else {
    log('📦 发现已存在的 dist 目录,跳过构建', colors.green)
  }

  // 2. 获取 dist 目录中的所有文件
  log('📋 扫描 dist 目录中的文件...', colors.blue)
  const distFiles = getAllFiles('dist')
  log(`📄 找到 ${distFiles.length} 个文件需要上传`, colors.green)

  // 3. 测试服务器连接
  log('🔗 测试服务器连接...', colors.blue);
  if (!runCommand(`ssh -o ConnectTimeout=10 ${config.server} "echo '连接成功'; exit"`, '测试SSH连接')) {
    return;
  }

  // 4. 在服务器上创建备份
  log('💾 在服务器上创建备份...', colors.blue);
  const backupCommands = `set -e; cd ${config.deployPath}; echo "备份当前文件..."; if [ -f "index.html" ] || [ -d "assets" ]; then tar -czf backup_old.tar.gz index.html assets 2>/dev/null || true; echo "✅ 当前文件已备份为 backup_old.tar.gz"; else echo "⚠️ 没有找到当前文件,跳过备份"; fi; echo "清理旧文件..."; rm -rf index.html assets; echo "✅ 服务器准备完成"; exit 0`;
  
  if (!runCommand(`ssh -o ConnectTimeout=30 ${config.server} "${backupCommands}"`, '服务器准备')) {
    return;
  }

  // 5. 逐个上传文件到服务器
  log('📤 开始上传文件到服务器...', colors.blue)
  let uploadedCount = 0

  for (const filePath of distFiles) {
    const relativePath = path.relative('dist', filePath)
    const remotePath = path
      .join(config.deployPath, relativePath)
      .replace(/\\/g, '/')
    const remoteDir = path.dirname(remotePath).replace(/\\/g, '/')

    // 确保远程目录存在
    const mkdirCommand = `ssh ${config.server} "mkdir -p ${remoteDir}"`
    if (!runCommand(mkdirCommand, `创建目录: ${remoteDir}`)) {
      continue
    }

    // 上传文件
    const scpCommand = `scp ${filePath} ${config.server}:${remotePath}`
    if (runCommand(scpCommand, `上传文件: ${relativePath}`)) {
      uploadedCount++
    }
  }

  log(
    `✅ 文件上传完成: ${uploadedCount}/${distFiles.length} 个文件`,
    colors.green
  )

  // 6. 在服务器上设置文件权限
  log('🔒 设置服务器文件权限...', colors.blue);
  const permissionCommands = `set -e; cd ${config.deployPath}; echo "设置文件权限..."; chmod -R 755 .; echo "✅ 权限设置完成"; exit 0`;
  
  runCommand(`ssh -o ConnectTimeout=30 ${config.server} "${permissionCommands}"`, '设置文件权限');

  // 7. 验证部署
  log('🔍 验证部署结果...', colors.blue);
  runCommand(
    `ssh -o ConnectTimeout=10 ${config.server} "cd ${config.deployPath} && ls -la && echo '--- 文件统计 ---' && find . -type f | wc -l; exit"`,
    '检查部署目录'
  );

  log('\n🎉 部署完成!', colors.green)
  log(`🌐 请访问: http://${config.server.split('@')[1]}`, colors.green)
  log('='.repeat(50))
}

// 执行部署
deploy().catch((error) => {
  log(`💥 部署过程出现错误: ${error.message}`, colors.red)
  process.exit(1)
})

这脚本干了啥?

  1. 自动检查有没有打包文件,没有就先打包
  2. 测试服务器连接(别传到一半断了)
  3. 备份服务器上的旧文件(万一新版本有问题能回滚)
  4. 上传所有新文件
  5. 设置好权限让Nginx能访问

第三步:配置打包命令

打开package.json,在scripts里加一行:

json 复制代码
"scripts": {
  "dev": "vite",
  "build": "vite build",
  "preview": "vite preview",
  "deploy": "vite build && node deploy.js"
},

就这么简单!

开始享受一键部署

以后每次改完代码需要部署的时候,终端里输入:

bash 复制代码
npm run deploy

然后你就会看到彩色的日志在跑,打包→上传→部署 一气呵成。等出现🎉 部署完成!的时候,刷新浏览器就能看到新版本了。没看到记得重启一下nginx。

是不是超简单?

以后再也不用打开一堆工具手动传文件了,改完代码一个命令搞定,省下的时间够你多摸几次鱼了。

相关推荐
q***T5832 小时前
前端路由懒加载实现,React与Vue
前端·vue.js·react.js
灵犀坠2 小时前
前端开发核心知识:HTML5特性与经典面试题详解
前端·html·html5
Hilaku2 小时前
我为什么说全栈正在杀死前端?
前端·javascript·后端
8***B2 小时前
前端性能优化插件,图片懒加载与压缩
前端
木易士心3 小时前
Vue2 和 Vue3 中 watch 用法和原理详解
前端·vue.js
百***67033 小时前
Nodemailer使用教程:在Node.js中发送电子邮件
linux·运维·node.js
Harlen3 小时前
Cesium.js基本使用
前端
拿不拿铁193 小时前
Webpack 5.x 开发模式启动流程详解
前端
百***35943 小时前
如何在树莓派部署Nginx并实现无公网ip远程访问内网制作的web网站
前端·tcp/ip·nginx