项目:项目发布系统(尚未阅读过 git hooks)
需求:1.选择需要上传的项目;2.下载到本地;3.选择需要上传的服务器;4.实现上传ftp服务器
技术:node.js + node-ftp
实现:
1.下载远程代码
通过命令node调取命令行实现下载(svn命令行需要安装subversion)
依赖 child_process 实现命令行调取 exec = require('child_process').exec
异步执行,需要结合 promise 返回状态
/**
* cmd 执行的命令行 (我执行多条命令的时候出错,然后没有去找解决的办法,妈的没有时间)
* {} 配置项。设置下载的超时时间,以及下载的buffer(小了可能报错)
* cb 回调处理
*/
exec(cmd, { encoding: 'utf8', timeout: 0, maxBuffer: 10000 * 1024, // 默认 200 * 1024 killSignal: 'SIGTERM' }, function(err, stdout, stderr) { if (err) { console.log('下载文件%s出错%s',cmd,err) } else {cb() } });
2.读取本地文件(如果本地文件夹上传直接读取)
//递归读取文件
//参数 path 读取的文件夹 相对路径是相对当前的服务(server index)路径,绝对路径带盘符
function readFile(path) {
files = fs.readdirSync(path); //需要用到同步读取
files.forEach(walk);
function walk(file) {
states = fs.statSync(path + '/' + file);
if (states.isDirectory()) {
readFile(path + '/' + file);
} else {
_fileList.push(path + '/' + file);
}
}
}
try {
readFile(path);
resolve(fileList) //读取文件夹是同步api
} catch (err) {
reject(err)
}
3.实现ftp的远程连接
//需要依赖 node-ftp (npm install)
Client = require('ftp')
var ftp_client = new Client()
ftp_client.on('ready', function() {
console.log('ftp连接建立成功');
//成功的执行
cb(file_client)
});
ftp_client.on('error', function(err) {
console.log('ftp连接建立失败',error);
//失败的回调
cb(err)
return;
});
4.根据文件列表,远程创建(调用nodejs的api好像不能远程创建,他只能创建在该服务运行的电脑)
使用ftp-node 的api
参数: ftp_client ftp的实例
fileList 文件列表
serverPath 服务器端的相对目录
还需要参数就是文件列表
hash快速去重:
function uniqArray(arr) {
var hash = {},
len = arr.length,
result = [];
for (var i = 0; i < len; i++) {
if (!hash[arr[i]]) {
hash[arr[i]] = true;
result.push(arr[i]);
}
}
return result;
}
创建文件夹:
var pre = new Promise(function(resolve, reject) {
// 建立相应的文件夹
async.each(fileList, function(item, cb) {
var _path = serverPath + "/" + item;
ftp_client.mkdir(_path, true, function(err) { //参数 true 表示已有文件夹不报错
if (err) {
console.log('创建文件夹%s出错%s', _path, err)
reject(err)
} else {
++file_num;
if (file_len == file_num) { //这一步很重要!!! 分别是文件的总数量,和当前数量
resolve()
}
}
});
})
})
5.上传文件
参数:ftp_client ftp的实例
fileList 文件列表
serverPath 服务器端的相对目录
var pre = new Promise(function(resolve, reject) {
async.each(fileList, function(item, cb) {
ftp_client.put(item, serverPath + "/" + item, function(err) {
if (err) {
console.log('上传文件%s出错:%s', item, err)
reject(err)
} else {
++file_num;
if (file_len == file_num) { //同上,很重要
resolve(ftp_client)
}
}
})
})
})
关于更多ftp上文件的操作,可以参考 node-ftp
说明:1.这个是个项目发布系统的思路
2.由于通过ftp上传并没有返回给我实时的进度以及错误信息,断点续传项目被否定了
3.上传文件很慢
4.考虑将项目迁移到git 然后使用git hooks