温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

node.js怎样自动化部署项目

发布时间:2021-02-05 13:58:29 来源:亿速云 阅读:280 作者:小新 栏目:web开发

小编给大家分享一下node.js怎样自动化部署项目,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!

一、功能设计

9.9元的阿里云服务器真的很慢,但还是足够折腾完这个项目。
用3个目录来模拟不同的环境。

目录存放
project存放所有的项目,比如本系统的前后端代码。
pre-dir预发环境,当然是用来测试的。
pro-dir生产环境,测试没问题,部署上线。

一图胜千言。

node.js怎样自动化部署项目

二、系统页面

我的任务

接到一个新的需求,可以新建一个需求,并创建开发分支。

node.js怎样自动化部署项目

发布队列

开发结束之后,便可以到发布队列中,部署到预发环境进行测试。 测试通过指定Cookie 就可以访问到测试的代码。最终再进行线上部署。

 node.js怎样自动化部署项目

项目信息

node.js怎样自动化部署项目 

二、技术栈

前端技术栈
Vue + elementUI,具体代码在Github,感兴趣的可以看下并点个star哈~✨
服务端技术栈
非常常见的Node.js(Koa2) + Mysql + Redis + Pm2。
具体代码在Github,感兴趣的可以看下并点个star哈~✨

三、Redis和Session配置

// utils/Store.js const Redis = require("ioredis"); const { Store } = require("koa-session2");   class RedisStore extends Store {   constructor() {     super();     this.redis = new Redis();   }     async get(sid, ctx) {     let data = await this.redis.get(`SESSION:${sid}`);     return JSON.parse(data);   }     async set(session, { sid = this.getID(24), maxAge = 1000 * 60 * 60 } = {}, ctx) {     try {       console.log(`SESSION:${sid}`);       // Use redis set EX to automatically drop expired sessions       await this.redis.set(`SESSION:${sid}`, JSON.stringify(session), 'EX', maxAge / 1000);     } catch (e) {}     return sid;   }     async destroy(sid, ctx) {     return await this.redis.del(`SESSION:${sid}`);   } }   module.exports = RedisStore;
// 入口文件 const session = require("koa-session2"); const Store = require("./utils/Store.js"); // session配置 app.use(session({   store: new Store(),   key: "SESSIONID", }));

 四、Router配置

为了Router看起来更优雅,也是通过中间件

// 1、middleware配置文件 const routers = require('../routers'); module.exports = (app) => {   app.use(routers()); } // 2、index.js入口文件 const middleware = require('./middleware'); middleware(app); // 3、routers 注册文件 const Router = require('koa-router'); const router = new Router(); const koaCompose = require('koa-compose'); // 接口入口 const {insertDemand} = require('../controllers/demand/insertDemand'); const {deleteDemand} = require('../controllers/demand/deleteDemandByDid'); const {updateDemand} = require('../controllers/demand/updateDemandByDid'); // 加前缀 router.prefix('/api'); module.exports = () => {   // 新增需求   router.get('/insertDemand', insertDemand);   // 删除需求   router.get('/deleteDemand', deleteDemand);   return koaCompose([router.routes(), router.allowedMethods()]); }

五、nginx配置

最头痛的就是nginx配置了,因为不是很熟悉,一直在试错、踩坑。不过还好终于成功了!
前后端项目通过Nignx提供服务,Node服务通过Nginx转发,主要是为了验证各种环境。
如果不设置Cookie,默认访问的就是线上环境,设置Cookie 就会走到预发布测试环境,用于测试。

# cookie 取TEST 赋值给$proxy_node map $cookie_TEST $proxy_node {   default "";   "1"   "1";   "2"   "2";   "3"   "3"; } # 发布管理系统前端设置 server {   listen    80;   server_name test.xue.com;   if ($proxy_node = ''){     set $dollar "/data/pro-dir/dandelion/dist/";   }   if ($proxy_node = "1") {     set $dollar "/data/pre-dir/dandelion/dist/";   }   location / {     root $dollar;     index index.html;     try_files $uri $uri/ /index.html;   } } # 发布管理系统后端设置 # 反向代理到node服务 server {   listen    80;   server_name m.xue.com;   if ($proxy_node = ''){     set $dollar "/data/pro-dir/study-demo/";   }   if ($proxy_node = "2") {     set $dollar "/data/pre-dir/study-demo/";   }   location / {     root $dollar;     index index.html;   } } # demo项目前端设置 server {   listen    80;   server_name api.xue.com;   location / {     if ($proxy_node = "") {       set $from 3001;       proxy_pass http://47.107.188.55:3001;     }     if ($proxy_node = "3") {       set $from 3002;       proxy_pass http://47.107.188.55:3002;     }   } }

六、一些中间件

常用的HTTP设置

解决跨域,OPTIONS请求,携带Cookie凭证等问题。

module.exports = () => {   return async (ctx, next) => {     ctx.set('Access-Control-Allow-Origin', 'http://test.xue.com');     ctx.set('Access-Control-Allow-Credentials', true);     ctx.set('Access-Control-Allow-Headers', 'content-type');     ctx.set('Access-Control-Allow-Methods', 'OPTIONS, GET, HEAD, PUT, POST, DELETE, PATCH');     // 这个响应头的意义在于,设置一个相对时间,在该非简单请求在服务器端通过检验的那一刻起,     // 当流逝的时间的毫秒数不足Access-Control-Max-Age时,就不需要再进行预检,可以直接发送一次请求。     ctx.set('Access-Control-Max-Age', 3600 * 24);     if (ctx.method == 'OPTIONS') {       ctx.body = 200;      } else {       await next();     }   } }

登录

这个系统属于强制登录的,登录统一进行了处理。

const Store = require("../../utils/Store"); const redis = new Store(); module.exports = () => {   return async (ctx, next) => {     // 白名单     if (ctx.request.url === '/api/login') {       return await next();     }      const SESSIONID = ctx.cookies.get('SESSIONID');     if (!SESSIONID) {       return ctx.body = {         mes: '没有携带SESSIONID~',         data: '',         err_code: 1,         success: false,       };     }     const redisData = await redis.get(SESSIONID);     if (!redisData) {       return ctx.body = {         mes: 'SESSIONID已经过期~',         data: '',         err_code: 1,         success: false,       };     }     if (redisData && redisData.uid) {       console.log(`登录了,用户uid为${redisData.uid}`);       await next();     }   } }

七、操作shell脚本

举个例子,创建项目分支

let path = ''; // 项目路径 // 创建分支 const branch_name = `branch_${new Date().getTime()}`; cp.execSync(`/data/dandelion-server/shell/createBranch.sh ${path} ${branch_name}`);
#!/bin/bash cd $1 git pull origin master git checkout -b $2 git push --set-upstream origin $2

八、连接数据库

config.js配置文件

let dbConf = null; const DEV = {   database: 'dandelion',  //数据库   user: 'root',  //用户   password: '123456',   //密码   port: '3306',    //端口   host: '127.0.0.1'   //服务ip地址 } const PRO = {   database: 'dandelion',  //数据库   user: 'root',  //用户   password: '123456',   //密码   port: '3306',    //端口   host: 'xx.xx.xx.xx'   //服务ip地址 } dbConf = PRO; //这个可以通过判断区分开发环境 module.exports = dbConf;

数据库连接文件

const mysql = require('mysql'); const dbConf = require('./../config/dbConf'); const pool = mysql.createPool({  host: dbConf.host,  user: dbConf.user,  password: dbConf.password,  database: dbConf.database, }) let query = function( sql, values ) {   return new Promise(( resolve, reject ) => {     pool.getConnection(function(err, connection) {       if (err) {         reject( err )       } else {         connection.query(sql, values, ( err, rows) => {           if ( err ) {             reject( err )           } else {             resolve( rows )           }           connection.release()         })       }     })   }) } module.exports = {   query, }

就可以在model层调用了~

const {query} = require('../common/mysql'); class UserModel {   constructor() {}   /**    * @description: 根据pid和did创建一个分支    * @param {pid} 项目id    * @param {did} 需求id    * @param {branch_name} 分支名    * @return: 分支信息    */   async insertBranchInfo(sqlParams) {     const sql = 'insert branch_info (pid, bid, branch_name, pub_time) values(?,?,?,?)';     console.log(sql)     let data = await query(sql, sqlParams, (err, result) => {       return result;     });     return data;    } }

九、域名

没有买域名,通过本地修改hosts(可以直接用工具)

47.107.188.xx为服务器IP

47.107.188.xx test.xue.com
47.107.188.xx api.xue.com
47.107.188.xx m.xue.com

以上是“node.js怎样自动化部署项目”这篇文章的所有内容,感谢各位的阅读!相信大家都有了一定的了解,希望分享的内容对大家有所帮助,如果还想学习更多知识,欢迎关注亿速云行业资讯频道!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI