当前位置: 首页 > 后端技术 > Node.js

Vue自动部署

时间:2023-04-03 23:43:45 Node.js

自动部署本教程在Vue项目下,使用scp2自动部署到静态文件,使用cross-env跨平台设置和使用环境变量,设置生产环境或开发环境。涉及配置文件:/deploy/*,编译部署code.env.*,项目环境设置文件,打包时区分开发环境和生产环境。package.json中的脚本模块,配置执行命令1安装安装scp2:一个基于ssh2的纯JavaScript安全拷贝程序。它是用纯JavaScript编写的,可以在每个操作系统上运行,甚至是Windows。必须使用Nodejs(v0.8.7或更高版本)才能工作。安装cross-env:这是一个跨平台运行的脚本,用于设置和使用环境变量。像这样设置NODE_ENV=production环境变量时,大多数Windows命令提示符都会卡住。npmi--save-devscp2cross-env两种配置测试环境/正式环境在项目根目录下,创建一个.env.dev文件(测试环境变量)VUE_APP_SERVER_ID变量表示当前要部署的测试服务器ID为1VUE_APP_CURRENTMODE:当前测试环境Vue-cli3项目打包生产环境和正式环境按照正式环境编译NODE_ENV=production//.env.dev文件NODE_ENV=productionVUE_APP_CURRENTMODE=developmentVUE_APP_SERVER_ID=1在项目根目录下,创建一个.env.prodfile(productionenvironmentVariable)VUE_APP_SERVER_ID变量表示当前要部署的官方服务器ID为0VUE_APP_CURRENTMODE:当前官方环境//NODE_ENV=productionVUE_APP_CURRENTMODE=productionVUE_APP_SERVER_ID=0当前官方环境//.env.prodfile.jsfile,写入服务器账号/**读取env环境变量*/constfs=require('fs');constpath=require('path');//env文件判断打包环境并指定对应的serveridconstenvfile=process.env.VUE_APP_CURRENTMODE==='prod'?'../.env.prod':'../.env.dev';//环境变量路径constenvPath=path.resolve(__dirname,envfile);//环境对象constenvObj=parse(fs.readFileSync(envPath,'utf8'));constSERVER_ID=parseInt(envObj['VUE_APP_SERVER_ID']);functionparse(src){//使用KEY=VAL解析文件constres={};来源分裂('\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];letvalue=keyValueArr[2]||'';//在引用值中扩展换行符constlen=value?value.length:0;if(len>0&&value.charAt(0)==='"'&&value.charAt(len-1)==='"'){value=value.replace(/\\n/gm,'\n');}//删除任何周围的引号和多余的空格value=value.replace(/(^['"]|['"]$)/g,'').trim();res[key]=value;}});returnres;}/**定义多个serveraccountsandExportcurrentenvironmentserveraccountaccordingtoSERVER_ID*/constSERVER_LIST=[{id:0,name:'A-官方环境',"host":'******',//IP地址"端口":'80',//服务器端口"username":'root',//用户名"password":'********',//密码"path":'/home/project/landingpage/',//服务器工程目录'localfile':envObj.VUE_APP_DEV//本地包文件名},{id:1,name:'A-生产环境',"host":'******',//IP地址"port":'443',//服务器端口"username":'root',//用户名"password":'******',//密码"path":'/home/project/landingpage/',//服务器项目目录'localfile':envObj.VUE_APP_DEV//本地包文件名},];module.exports=SERVER_LIST[SERVER_ID];4.在项目根目录下编译自动化部署脚本,创建deploy/index.js文件。删除服务器之前的文件,防止一直上传过多的冗余文件。然后将新文件上传到服务器,并替换到原文件夹中。问题:文件上传过程中,如果文件太大,上传时间过长。会导致服务器一段时间内打不开。constscpClient=require('scp2');constora=require('ora');constchalk=require('粉笔');constserver=require('./products');constspinner=ora('Publishingto'+(process.env.VUE_APP_CURRENTMODE==='prod'?'production':'test')+'server...');varClient=require('ssh2').Client;varconn=newClient();conn.on('ready',function(){//rm删除dist文件,\n是换行,换行执行重启nginx命令,这里我用docker来重启nginxconn.exec('rm-rf'+server.path+'\ndockerrestartnginx',function(err,stream){if(err)throwerr;stream.on('close',function(code,signal){//执行完shell命令后,开始上传部署工程把代码放在这里spinner.start();scpClient.scp(server.localfile,{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('发布失败。\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,//端口:server.port,用户名:server.username,密码:server.password//privateKey:require('fs').readFileSync('/home/admin/.ssh/id_dsa')});5.在package.json中添加scripts命令,自定义名称为“deploy”并使用cross-env跨平台设置和使用环境变量发布到测试环境的命令是npmrundeploy:dev,生产环境是npmrundeploy:prod"scripts":{"serve":"vue-cli-serviceserve--open","app":"npmrunserve&&npmrunnode","build":"vue-cli-servicebuild","node":"node./server/app.js","deploy:dev":"npmrunbuild&&cross-envVUE_APP_CURRENTMODE=devnode./deploy","deploy:prod":"npmrunbuild&&cross-envVUE_APP_CURRENTMODE=prodnode./deploy","test:unit":"vue-cli-servicetest:unit"},六优化版本编译自动化部署脚本:为解决上传过程中无法打开服务器的问题,首先安装压缩插件,对打包文件夹进行压缩。npmicompressing--save-dev然后将压缩文件上传到服务器。最后连接服务器,删除原文件,解压最新上传的文件。constscpClient=require('scp2');constchalk=require('chalk');constserver=require('./products');constClient=require('ssh2').Client;constora=require('ora');varcompressing=require("compressing");constenvironment=server.path+server.localpathconstspinner=ora('正在发布到'+environment+'服务器...');constziping=ora('正在压缩'+environment);constconn=newClient();//压缩ziping.start()compressing.zip.compressDir(server.localpath+"/","dist.zip").then((e)=>{ziping.stop()console.log(chalk.green('成功!压缩成功'));spinner.start()scpClient.scp('dist.zip',{host:server.host,//port:server.port,username:server.username,password:server.password,path:server.path},(err)=>{spinner.stop();if(err){console.log(chalk.red('发布失败。\n'));throwerr;}else{conn.on('ready',()=>{conn.exec('sudounzip-o'+server.path+'dist.zip\ndockerrestartnginx',(err,stream)=>{if(err)throwerr;stream.on('close',function(code,signal){console.log(chalk.green('Success!Successfullypublishedto'+environment+'server!\n'));conn.end()})})}).connect({host:server.host,//port:server.port,username:server.username,password:server.password//privateKey:require('fs').readFileSync('/home/admin/.ssh/id_dsa')});}});}).catch(err=>{console.log(chalk.red('失败!压缩失败'));});努力学习,如有不妥欢迎指教