相对于部署到 Github Page 来说,可以使用 GitHub Actions 来进行自动部署。我们自己拥有服务器的选手,就相对来说比较麻烦。一般的情况就这些:
方法 | 分析 |
---|---|
FTP | FTP 的速度相对来说确实太慢了,上传东西真的是龟速 |
SSH | 通过 SSH 直接连通服务器,大大加快了传输速度。但是还是需要手动操作数据包 |
宝塔面板 | 直接打开宝塔页面,找到指定的页面,上传文件即可。但是网速较差的情况下打会很慢 |
之前每次更新项目都得上传半天,很烦人。所以就着手研究怎么部署比较方便快捷。
👉 设想
1.首先需要把我构建的文件夹压缩为 zip 文件。 (archiver)
2.能不能直接把压缩包从本地通过 SSH 上传到服务器。 (node-ssh)
3.上传到服务器以后怎么操作这个压缩包? (执行预留在服务器的 shell 命令)
👉 上手
首先在根目录创建 deploy 文件夹,并创建config.js
和index.js
。
├─ deploy
│ ├─config.js
│ └─index.js
├─ docs
├─ public
👉 config.js
导出一些配置信息。
module.exports = {
path: "/www/wwwroot/reinness.com/public.zip", //服务器上这个文件要放在哪里
host: "xxx.xxx.xx.xx", // 服务器的host地址
username: "xxxxxxx", // SSH用户名
password: "xxxxxxxx", // SSH密码
port: xx, //SSH连接的端口
};
👉 index.js
首先我们需要安装依赖插件
npm install archiver node-ssh -S
依赖安装完成后,导入我们需要的包
const path = require("path");
const archiver = require("archiver");
const fs = require("fs");
const node_ssh = require("node-ssh");
const ssh = new node_ssh();
const configs = require("./config");
const srcPath = path.resolve(__dirname, "../public");
// 为什么是"../public"?
// 因为我的项目设置的打包名称为public,而且从上面的目录树中可以了解到,public与deploy是一级。
// 所以我为了找到public文件夹,就得使用 "../public"
压缩目录为 public.zip
console.log("开始压缩dist目录...");
startZip();
function startZip() {
var archive = archiver("zip", {
zlib: {
level: 8, // 搜索路径深度
},
}).on("error", function(err) {
throw err; //压缩过程中如果有错误则抛出
});
var output = fs
.createWriteStream(__dirname + "/public.zip")
.on("close", function(err) {
/*压缩结束时会触发close事件,然后才能开始上传,
否则会上传一个内容不全且无法使用的zip包*/
if (err) {
console.log("关闭archiver异常:", err);
return;
}
console.log("已生成zip包");
console.log("开始上传public.zip至远程机器...");
uploadFile();
});
archive.pipe(output); //典型的node流用法
archive.directory(srcPath, "/public"); //将srcPach路径对应的内容添加到zip包中/public路径
archive.finalize();
}
上传文件到服务器
function uploadFile() {
ssh
.connect({
host: configs.host,
username: configs.username,
password: configs.password,
port: configs.port,
})
.then(function() {
console.log(configs.path);
//上传网站的发布包至configs中配置的远程服务器的指定地址
ssh
.putFile(__dirname + "/public.zip", configs.path)
.then(function(status) {
console.log("上传文件成功");
console.log("开始执行远端脚本");
startRemoteShell(); //上传成功后触发远端脚本
})
.catch((err) => {
console.log("文件传输异常:", err);
process.exit(0);
});
})
.catch((err) => {
console.log("ssh连接失败:", err);
process.exit(0);
});
}
执行远端部署脚本
具体远端部署脚本···
function startRemoteShell() {
// 在服务器上cwd配置的路径下执行sh deploy.sh脚本来实现发布
ssh
.execCommand("sh deploy.sh", {
cwd: "/www/wwwroot/reinness.com",
})
.then(function(result) {
console.log("远程STDOUT输出: " + result.stdout);
console.log("远程STDERR输出: " + result.stderr);
if (!result.stderr) {
console.log("发布成功!");
removeLocalFile();
process.exit(0);
}
});
}
为了不占用本地空间,完成操作后删除本地的打包文件
function removeLocalFile() {
fs.unlink(__dirname + "/public.zip", function(error) {
if (error) {
console.log(error);
return false;
}
console.log("删除文件成功");
});
}
👉 deploy.sh
以我的项目为例,服务器上面的目录结构如下
├─ public
│
└─ deploy.sh
我的站点根节点为 public ,当上传了 public.zip 后,我需要先删除原来的 public 文件夹,然后再解压。然后删除 public.zip
rm -rf public
unzip public.zip
rm -rf public.zip
👉 在 package.json 中添加 scripts 命令
"scripts": {
"deploy": "node ./deploy/index.js", // 一键发布
"auto": "vuepress build docs && node ./deploy/index.js" // 一键打包加发布
}
以上所有内容供大家参考,如有问题请及时指正。