侧边栏壁纸
博主头像
神的孩子都在跳舞博主等级

HARD WORK PAYS OFF

  • 累计撰写 22 篇文章
  • 累计创建 64 个标签
  • 累计收到 0 条评论

微信公众号 | 模块化工程文件

神的孩子都在跳舞
2022-04-07 / 0 评论 / 0 点赞 / 1,462 阅读 / 3,042 字 / 正在检测是否收录...

本篇的主题

  • 模块化整理

模块化的优势

随着项目不断复杂,功能不断增多,如果代码全都放在app.js中势必后期维护起来变得极其困难。在准备新的功能前必须要重新规整代码,按照业务逻辑封装你的代码是程序员良好的习惯。

js是一种脚本语言,理论上说js中“万物皆对象”,甚至基本数据结构也是在c++的基础上封装后的对象。js的对象并不具有底层“对象”的意义,但是我们操作它们还是应该保持操作底层对象的逻辑。

设计思路

express的中间件是很优秀的设计,这就相当于一个管道,数据通过层层管道,只会在对应的管道中停下处理,这好比邮件的分拣中心,包裹从统一的入口进入传送带,最后被传送到不同的出口。
参考文档:
https://www.expressjs.com.cn/guide/using-middleware.html
譬如我这边把路由作为一个传送带的一个管道,再细分下,这个路由管道的’/wx’就是一个分管道之一,再细分’GET’,'POST’等又是一层更小的管道,再再细分如’POST’处理’text’和’image’又会进入新的管道。还能细分就是’text’处理每种文字又会进入更更细的管道。这种从顶至下不断细分的管道能使业务逻辑变得清晰,同时也能避免if else嵌套。代码分文件储存,如果问题出在哪里就能直接定位到最细的那一个模块中。
有一种设计模式叫”开闭原则“,对扩展开放,对修改封闭。当业务有新的需求时候,不需要修改原来的代码,只要添加新的处理管道连接上最终的主管道即可。这种管道的思路恰好能符合这样的设计思路。

项目文件分类

以下是项目重新构建的目录

  • middleware文件夹中放置所有中间件
  • tools文件夹中放置所有工具函数
  • middleware文件夹按照逻辑继续细分
  • 管道的最后需要统一处理没有配置的请求写在errorHandler.js文件中

这样的好处就是所有业务分模块分文件储存,哪里错了改哪里,以最小代价影响其他模块性能;同样要新增功能也很直观,按照业务逻辑进入不同的管道来添加新的处理中间件代码。

代码详细

  1. 首先是app.js入口文件,原先都写在这一个文件里很乱,现在再看下效果:
//app.js
const express = require('express')
const app = express()

//验证服务器中间件
app.use(require('./middleware/verifyServerRouter'))

//消息预处理中间件
app.use(require('./middleware/paseMsgMW'))

//消息服务中间件
app.use(require('./middleware/messageRouter'))

//处理未知情况返回404
app.use(require('./errorHandler'))

app.listen('3000', () => {
    console.log('server started at port 3000')
})
  1. 中间件文件
    我就不一一展示每个路由,大家可以在代码仓库查看代码,这里展示几个典型的文件:
//parseMsgMW.js
//消息预处理中间件
const parseMsgMW = require('express').Router()
parseMsgMW.route('/wx')
    .post(async (req, res, next) => {
        //消息预处理
        const xmlMsg = await require('../tools/getUserMessage')(req)
        const jsonData = await require('../tools/paresMsg')(xmlMsg)
        //信息放入req中继续传递
        req.jsonData = jsonData
	//传递到下一个中间件处理
        next()
    })
module.exports = parseMsgMW
//msgRouter.js
const msgRouter = require('express').Router()

// 处理系统消息
msgRouter.use(require('./messageDelling/sysMsgMW'))

// 最后处理文字消息
msgRouter.use(require('./messageDelling/textMsgMW'))
module.exports = msgRouter
//dailyVerseMW.js
const dailyVerseMW = require('express').Router()
dailyVerseMW.route('/wx')
    .post((req, res, next) => {
        if (req.jsonData.MsgType[0] == 'text') {
            const { jsonData } = req
            //发送每日经文
            if (jsonData.Content[0] == '每日经文') {
                const axios = require('axios')
                //使用axios来处理请求
                axios.get('http://127.0.0.1:3001/api/getDailyVerse').then(response => {
                    //使用sendMsg方法发回收到的数据
                    const xmlSendData = require('../../../tools/sendMsg')(jsonData.FromUserName[0], jsonData.ToUserName[0], response.data)
                    res.end(xmlSendData)
                })
            } else
		//其余消息继续转到下一个中间件处理
                next()
        }

    })

module.exports = dailyVerseMW
  1. 404页面处理
    微信服务器确保外部用户无法非正常的访问,只能通过从微信客户端进行访问。所以当不是微信客户端的请求一律不予支持。
//errorHander.js
module.exports = (req,res)=> {
    res.writeHead(404, { 'content-type': 'text/html' })
        res.end(`<div style="
    display: flex; 
    justify-content: center;
    align-items: center;
    flex-direction: column;
    height: 100vh;
    ">
    <h1>404 NOT FOUND!!!</h1>
    <a href="https://ivanccc.com">
        <h4>back to my homepage<h4><a>
                    <p>Created By: ivan chen</p>
</div>`)}

效果展示

  • 浏览器访问'/wx'
  • 浏览器访问其他路径
    Snipaste_20220407_230423.png
  • 微信端还是能正常访问

之后的想法

会话的保存能够使得服务器有初期AI的能力,引入数据库是我下一步的所要做的。在node上操作我习惯用MongoDB这种非关系型数据库,因为mongoose包很方便对mongoDB进行CURD操作,大家拭目以待,感谢阅读,如有想法欢迎交流,感谢!!!

下一篇: 微信公众号 | 数据的存储 (上)

0
博主关闭了所有页面的评论