前言部署前端项目通常的流程是:先部署到测试环境ok然后发布到生产环境,部署到测试环境连接到服务器用xshell,然后使用xftp连接服务器,然后在本地构建项目,然后通过xftp将构建的文件上传到服务器。整个过程感觉有点繁琐和重复。本教程讲解Vue-CLI3.x脚手架搭建的vue项目,使用scp2自动部署到静态文件服务器Nginx,安装scp2scp2是基于ssh2的增强实现,纯JavaScript编写。而ssh2是使用nodejs对SSH2的模拟实现。scp是securecopy的缩写,scp是Linux系统下基于SSH登录的安全远程文件复制命令。这里我们使用该功能在Vue编译构建成功后将项目推送到测试/生产环境,方便测试,提高效率。安装scp2:npminstallscp2--save-dev二、配置测试/生产环境服务器SSH远程登录账号信息1、在项目根目录下,创建.env.dev文件(测试环境变量)VUE_APP_SERVER_ID变量表示当前部署.env.dev文件中的测试服务器ID为0//VUE_APP_SERVER_ID=02。在项目根目录下,创建.env.prod文件(生产环境变量)。VUE_APP_SERVER_ID变量表示当前要部署的生产服务器ID是.prod文件中的1//.envVUE_APP_SERVER_ID=13。在项目根目录下,创建一个deploy/products.js文件/**读取env环境变量*/constfs=require('fs');constpath=require('path');//env文件决定打包环境并指定对应的serveridconstenvfile=process.env.NODE_ENV==='prod'?'../.env.prod':'../.env.dev';//env环境变量路径constenvPath=path.resolve(__dirname,envfile);//env对象constenvObj=parse(fs.readFileSync(envPath,'utf8'));constSERVER_ID=parseInt(envObj['VUE_APP_SERVER_ID']);functionparse(src){//解析KEY=VAL的文件constres={};src.split('\n').forEach(line=>{//匹配'KEY=VAL'中的"KEY'和'VAL'//eslint-disable-next-lineno-useless-escapeconstkeyValueArr=line.match(/^\s*([\w\.\-]+)\s*=\s*(.*)?\s*$/);//匹配?if(keyValueArr!=null){constkey=keyValueArr[1];让值=keyValueArr[2]||'';//在引用值中扩展换行符constlen=value?值.长度:0;if(len>0&&value.charAt(0)==='"'&&value.charAt(len-1)==='"'){value=value.replace(/\\n/gm,'\n');}//删除所有周围的引号和多余的空格value=value.replace(/(^['"]|['"]$)/g,'').trim();res[键]=值;}});返回资源;}/**定义多个服务器账号,根据SERVER_ID导出当前环境服务器账号*/constSERVER_LIST=[{id:0,name:'A-productionenvironment',domain:'www.prod.com',//域名host:'46.106.38.24',//ipport:22,//端口username:'root',//登录服务器密码:'Rock@sz18!',//登录帐号totheserverpath:'/mdm/nginx/dist'//发布到静态服务器的项目路径},{id:1,name:'B-testenvironment',domain:'test.xxx.com',host:'XX.XX.XX.XX',端口:22,用户名:'root',密码:'xxxxxxx',路径:'/usr/local/www/xxx_program_test/'}];module.exports=SERVER_LIST[SERVER_ID];3.使用scp2库创建自动化部署脚本。在项目根目录下,创建一个deploy/index.js文件constscpClient=require('scp2');constora=require('ora');constchalk=require('粉笔');constserver=require('./products');constspinner=ora('发布到'+(process.env.NODE_ENV==='prod'?'production':'Test')+'Server...');spinner.start();scpClient.scp('dist/',{host:server.host,port:server.port,username:server.username,password:server.password,path:server.path},function(err){spinner.stop();if(err){console.log(chalk.red('Publishfailed.\n'));throwerr;}else{console.log(chalk.green('成功!成功发布到'+(process.env.NODE_ENV==='prod'?'production':'test')+'server!\n'));}});4.在package.json中添加scripts命令,自定义名称为"deploy",发布到测试环境的命令为npmrundeploy:dev,生产环境为npmrundeploy:prod"scripts":{"serve":"vue-cli-serviceserve--modedev","build":"vue-cli-servicebuild--modeprod","deploy:dev":"npmrunbuild&&cross-envNODE_ENV=devnode./deploy","deploy:prod":"npmrunbuild&&cross-envNODE_ENV=prodnode./deploy",},这里使用pscross_env,必须安装npm--save-devcross-envcross-env可以跨平台设置和使用环境变量,这里用来设置是生产环境还是测试环境图解结论欢迎指正,Vue学习群493671066欢迎大家加入加入我的前端学习交流群,一起学习进步。补充热心小伙伴说每次打包hash值都不一样,dist里的文件不是越来越多吗,可以用ssh2删除dist文件,删除后重启nginx,然后上传到服务器。//在deploy/index.jsconstscpClient=require('scp2');constora=require('ora');constchalk=require('粉笔');constserver=require('./products');constspinner=ora('发布到'+(process.env.NODE_ENV==='prod'?'production':'test')+'server...');varClient=require('ssh2')。Client;varconn=newClient();conn.on('ready',function(){//rm删除dist文件,\n是换行换行执行命令重启nginx我用的docker重启nginxconn.exec('rm-rf/mdm/nginx/dist\ndockerrestartnginx',function(err,stream){if(err)throwerr;stream.on('close',function(code,signal){//执行shell命令后,将开始上传和部署项目的代码放在这里spinner.start();scpClient.scp('./dist',{host:server.host,port:server.端口,用户名:server.username,密码:server.password,路径:server.path},function(err){spinner.stop();if(err){console.log(chalk.red('发布失败。\n'));抛出错误;}else{console.log(chalk.green('成功!成功发布到'+(process.env.NODE_ENV==='prod'?'production':'test')+'server!\n'));}});conn.end();}).on('data',function(data){console.log('STDOUT:'+data);}).stderr.on('data',function(data){console.log('STDERR:'+数据);});});}).connect({host:server.host,port:server.port,username:server.username,password:server.password//privateKey:require('fs').readFileSync('/home/admin/.ssh/id_dsa')});参考文章https://www.cnblogs.com/sufai...
