摘录自: https://blog.csdn.net/weixin_43087487/article/details/90371869
在根目录创建一个publish.js文件
发布的时候 只要输入 node publish.js publish test
就可以了
// 一键打包部署 module.exports = function () { let O = 'xxx', // 文件名 Q = require('q'), del = require('del'), gulp = require('gulp'), zip = require('gulp-zip'), node_ssh = require('node-ssh'), colors = require('colors/safe'), dateFormat = require('dateformat'), argv = process.argv, fs = require('fs'), path = require('path'), exec = require('child_process').exec, IPs = [{ host: 'xx.xx.xx.xx', // 中控地址 post: 22, user: 'root', dist: '/root', privateKey: '/Users/.ssh/id_rsa' // 本地ssh }], SERVER = { // 这里可以写多个服务器 'test': { type: 'test', host: 'xx.xx.xx.xx', // 服务器地址 port: 22, user: '', dist: '/xx', // 路径 privateKey: '' } }, center = new node_ssh(), zipfile = O + '-' + dateFormat(new Date(), 'yyyy-mm-dd-HH-MM-ss') + '.zip'; if ('publish' !== argv[2]) { process.stdout.write(colors.green('Do you mean "publish"? ')); return } if (!SERVER[argv[3]]) { process.stdout.write(colors.green('x20SERVER REQUIRED! ')); process.stdout.write(colors.blue('x20-node dist.publish.js test ')); process.stdout.write(colors.blue('x20-node dist.publish.js prod ')); return } IPs.push(SERVER[argv[3]]); const testFilename = 'devdata.json', prodFilename = 'prodata.json' newname = 'domaindata.json', destPath = path.join(__dirname, './src/views/activity/', newname), sourceFile = '' // 第一步,build var BUILD = function () { var defered = Q.defer(); process.stdout.write(colors.green('1、: build -> ')); process.stdout.write(colors.blue('x20x20x20 build project... ')); exec('npm run build', function(error, stdout, stderr) { process.stdout.write(colors.green('x20x20x20 success ')); defered.resolve(true); }); return defered.promise; } // 第二步,将build后dist目录下的文件copy到zip,并命名yx-page var COPYTOZIP = function () { var deferred = Q.defer(); process.stdout.write(colors.green('2. copy -> ')); process.stdout.write(colors.blue('x20x20x20 copy... ')); gulp.src(['./dist/**']) .pipe(gulp.dest('zip/yx-page')) .on('finish', function () { process.stdout.write(colors.green('x20x20x20 copy successfully! ')); deferred.resolve(true); }) .on('error', function (error) { deferred.reject(new Error(error)); }) return deferred.promise } // 第三步,打包压缩zip文件夹里的yx-page var ZIPFILE = function () { var deferred = Q.defer(); process.stdout.write(colors.green('3. zipfile -> ')); process.stdout.write(colors.blue('x20x20x20 zip packing... ')); gulp.src([ 'zip/**' ]) .pipe(zip(zipfile)) .pipe(gulp.dest('zip')) .on('finish', function () { process.stdout.write(colors.green('x20x20x20 zip packed successfully! ')); deferred.resolve(zipfile); }) .on('error', function () { process.stdout.write(colors.red('x20x20x20 zip packed field! ')); deferred.reject(new Error(error)); }); return deferred.promise; } // 第四步,上传至中控 var UPLOAD = function (file) { var deferred = Q.defer(); process.stdout.write(colors.green('4. upload: ')); process.stdout.write(colors.blue('x20x20x20 upload ' + file + ' to ' + IPs[0].host + '... ')); exec('scp ./zip/' + file + ' ' + IPs[0].user + '@' + IPs[0].host + ':' + IPs[0].dist, function (error, stdout, stderr) { process.stdout.write(colors.blue('x20x20x20 upload to ' + IPs[0].host + 'successfully! ')); deferred.resolve(file) }) return deferred.promise; } // 第五步,连接中控机 var CONNECT = function (file) { var deferred = Q.defer(); process.stdout.write(colors.green('5. login: ')); process.stdout.write(colors.blue('x20x20x20 login ' + IPs[0].host + '... ')); center.connect({ host: IPs[0].host, port: IPs[0].port, username: IPs[0].user, privateKey: IPs[0].privateKey }).then( () => { process.stdout.write(colors.blue('x20x20x20 welcome to ' + IPs[0].host + '! ')); deferred.resolve(file); }) return deferred.promise } // 第六步,解压文件 var UNZIPFILE = function (file) { var deferred = Q.defer(); process.stdout.write(colors.green('6. unzip: ')); center.exec('unzip -o ' + IPs[0].dist + '/' + file) .then(function (result) { process.stdout.write(colors.blue('x20x20x20 unzip successfully! ')); deferred.resolve(file); }); return deferred.promise; } // 第起步,将文件拷贝到服务器 var COPYTOSERVER = function (file) { var deferred = Q.defer(); process.stdout.write(colors.green('7. copy to server: ')); process.stdout.write(colors.blue('x20x20x20 copy '+ O +' to ' + IPs[1].host + '! ')); center.exec('scp -r ' + IPs[0].dist + '/' + O + ' ' + IPs[1].host + ':' + IPs[1].dist) .then(function (result) { process.stdout.write(colors.blue('x20x20x20 copy successfully! ')); deferred.resolve(file); }); return deferred.promise; } // 第八步,删除打包文件 var DELZIPSERVERFILE = function (file) { var deferred = Q.defer(); process.stdout.write(colors.green('8. del zip.file: ')); center.exec('rm -rf ' + file + ' ' + O + '/').then(function (result) { process.stdout.write(colors.blue('x20x20x20 del successfully! ')); deferred.resolve(true); delDir('zip') }); return deferred.promise; } // 第九步,成功提示 var SUCCESS = function () { var deferred = Q.defer(); center.dispose(); process.stdout.write(colors.green('x20PUBLISH SUCCESSFULLY! ')); deferred.resolve(true); return deferred.promise } // 第十步,错误统一处理 var ERROR_CATCH = function (error) { process.stdout.write(colors.red('Wrong Message: ')) process.stdout.write(colors.red(error.message + ' ')) } // 删除本地zip文件 function delDir(path){ let files = [] if(fs.existsSync(path)){ files = fs.readdirSync(path) files.forEach((file, index) => { let curPath = path + "/" + file if(fs.statSync(curPath).isDirectory()){ delDir(curPath) } else { fs.unlinkSync(curPath) } }); fs.rmdirSync(path); } } Q.fcall(BUILD) .then(COPY) .then(COPYTOZIP) .then(ZIPFILE) .then(UPLOAD) .then(CONNECT) .then(UNZIPFILE) .then(COPYTOSERVER) .then(DELZIPSERVERFILE) .then(SUCCESS) .catch(ERROR_CATCH) .done() }()