前端项目中创建自动化部署脚本,用于 Jenkins 触发 npm run publish 来完成远程部署
核心步骤包括:
- 读取
server.config.json
配置,获取目标服务器信息 - 使用
scp
上传前端打包文件 到serverWebPath
- 使用
ssh
远程执行部署命令(例如pm2 restart
或nginx reload
)
1. 安装依赖
使用 Node.js 编写 deploy.js
脚本,需要用到 ssh2
和 fs
:
npm install ssh2 fs-extra dotenv
2. 在config下配置server.config.json文件
{
"deploy": {
"host": "10.2...",
"port": 36000,
"username": "root",
"password": "*#00000",
"serverWebPath": "/...",
"splitIncludes": ["models"],
"splitUpload": false
},
"sandbox": {
"host": "10.2...",
"port": 36000,
"username": "root",
"password": "*#00000",
"serverWebPath": "/...",
"splitIncludes": [],
"splitUpload": true
}
}
3. deploy.js
自动化脚本
在 项目根目录 创建 scripts/deploy.js
,用于 自动化部署
const fs = require("fs-extra");
const path = require("path");
const { Client } = require("ssh2");
// 读取 server.config.json
const configPath = path.resolve(__dirname, "../server.config.json");
const config = JSON.parse(fs.readFileSync(configPath, "utf-8"));
// 选择环境(deploy 或 sandbox)
const env = process.env.ENV || "deploy";
const serverConfig = config[env];
if (!serverConfig) {
console.error(`配置错误: 未找到环境 ${env} 的配置信息`);
process.exit(1);
}
// 获取配置信息
const { host, port, username, password, serverWebPath } = serverConfig;
const localBuildPath = path.resolve(__dirname, "../dist"); // 前端打包目录
// 部署逻辑
async function deploy() {
console.log(`开始部署到 ${env} 环境: ${host}:${port}`);
const conn = new Client();
conn
.on("ready", () => {
console.log(`连接成功: ${host}`);
// 上传文件
uploadFiles(conn)
.then(() => executeRemoteCommand(conn, `cd ${serverWebPath} && ls -la`))
.then(() => {
console.log("部署完成!");
conn.end();
})
.catch((err) => {
console.error(`部署失败: ${err.message}`);
conn.end();
});
})
.connect({ host, port, username, password });
}
// 远程执行命令
function executeRemoteCommand(conn, command) {
return new Promise((resolve, reject) => {
conn.exec(command, (err, stream) => {
if (err) return reject(err);
stream
.on("close", (code, signal) => resolve(code))
.on("data", (data) => console.log(`远程输出: ${data.toString()}`))
.stderr.on("data", (data) => console.error(` 错误: ${data.toString()}`));
});
});
}
// 上传文件
function uploadFiles(conn) {
return new Promise((resolve, reject) => {
conn.sftp((err, sftp) => {
if (err) return reject(err);
sftp.mkdir(serverWebPath, (err) => {
if (err && err.code !== 4) return reject(err); // 目录已存在则忽略错误
sftp.fastPut(
path.join(localBuildPath, "index.html"),
`${serverWebPath}/index.html`,
(err) => (err ? reject(err) : resolve())
);
});
});
});
}
// 执行部署
deploy();
4. 在 package.json
添加 publish
命令
"scripts": {
"build": "vite build",
"publish": "npm run build && node scripts/deploy.js"
}