[学习笔记] Elpis-core 的学习过程理解笔记

本文基于抖音"哲玄前端", 《全栈实践课》,引擎内核实现章节所写。

elpis-core

  elpis-core是基于Koa实现的一个类似于Egg的轻量级的服务端框,包括routerLoader 、routerSchemaLoader 、middlewareLoader 、controllerLoader 、serviceLoader 、extendLoader 、configLoader。目录如下

arduino 复制代码
├─ app
│  ├─ controller
│  ├─ extend
│  ├─ middleware
│  │  ├─ api-params-verify.js
│  │  ├─ api-sign-verify.js
│  │  ├─ error-handler.js
│  ├─ public
│  ├─ router
│  ├─ router-schema
│  ├─ service
│  ├─ middleware.js
├─ config
├─ eggjs-core
│  └─ loader
│     ├─ config.js
│     ├─ controller.js
│     ├─ extend.js
│     ├─ middleware.js
│     ├─ router-schema.js
│     ├─ router.js
│     └─ service.js
│  ├─ env.js
│  ├─ index.js
├─ index.js

config

  该目录下通过读取 env.js \color{#FF4500}\textup{env.js} env.js 根据运行的环境去加载如下对应的配置文件: config.local.js(本地) \color{#FF4500}\textup{config.local.js(本地)} config.local.js(本地)、 config.beta.js(测试) \color{#FF4500}\textup{config.beta.js(测试)} config.beta.js(测试)、 config.prod.js(生产) \color{#FF4500}\textup{config.prod.js(生产)} config.prod.js(生产)

js 复制代码
    let envConfig = {}
    try {
        if (app.env.isLocal()) { // 本地
            envConfig = require(path.resolve(configPath, `.${sep}config.local.js`));
        } else if (app.env.isBeta()) { // 测试环境
            envConfig = require(path.resolve(configPath, `.${sep}config.beta.js`));
        } else if (app.env.isProduction()) { // 生产环境
            envConfig = require(path.resolve(configPath, `.${sep}config.production.js`));
        }
    } catch(e) {
        console.log('[exception] there is no default.config file');     
    }

service/middleware/controller

  同为加载app下相对应的所有文件,并挂载到app.对应的目录下

js 复制代码
module.exports = (app) => {
    // 读取 app/xxx/**/**.js 下所有的文件
    const xxxPath = path.resolve(app.businessPath, `.${sep}xxx`);
    const fileList = glob.sync(path.resolve(xxxPath, `.${sep}**${sep}**.js`))

    // 遍历所有文件目录,把内容加载到 app.xxx 下
    const service = {}
    fileList.forEach(file => {
        // 提取文件名称
        let name = path.resolve(file);
        // 截取路径 app/xxx/custom-module/custom-xxx.js => custom-module/custom-xxx
        name = name.substring(name.lastIndexOf(`xxx${sep}`) + `xxx${sep}`.length, name.lastIndexOf('.'));

        // 把 '-' 统一改成驼峰式,custom-module/custom-xxx => customModule.customxxx
        name = name.replace(/[_-][a-z]/ig, (s) => s.substring(1).toUpperCase());

        // 挂载 xxx 到内存 app 对象中
        let tempService = service;
        const names = name.split(sep); // [ customModule(目录), customService(文件) ]
        for(let i = 0, len = names.length; i < len; ++i) {
            if(i === len - 1) { // 文件
                const xxxMoule = require(path.resolve(file))(app);
                tempxxx[names[i]] = new xxxMoule();
            } else { // 文件夹
                if (!tempxxx[names[i]]) {
                    tempxxx[names[i]] = {};
                }
                tempxxx = tempxxx[names[i]];
            }
        }
    });
    app.xxx = xxx;
}

router-schema

  通过 'json-schema & ajv' 对 API 规则进行约束,配合 app-params-verify 中间件使用形成如下结构

js 复制代码
   {
     '${api1}': ${jsonSchema},
     '${api2}': ${jsonSchema},
     '${api3}': ${jsonSchema},
     '${api4}': ${jsonSchema},
   }

router

  解析所有 app/router/ 下所有 js 文件,加载到 KoaRouter 下且路由兜底 (健壮性)(当前路由不存在时,临时重定向到指定菜单的同时返回状态码302)

extend

  该目录下放置扩展文件,主要为 Koa 实例扩展额外的功能,如: 日志文件(方便日常更加便利的寻找对应的错误)

总结

  目前初次接触Nodejs、Koa中间件等内容,对elpis-core的理解浅薄。上诉如有错误望各位大佬们指点一二。

相关推荐
子兮曰26 分钟前
PHP漏洞危机,你的网站升级了吗?
前端·后端·php
jerrywus26 分钟前
给 Pi 装上生图插件:从登录报错到画出一只 200×200 的猫
前端·agent·claude
陈随易32 分钟前
搞钱点子之生态鱼缸
前端·后端·程序员
PBitW37 分钟前
从空目录到上线:我全程用 TRAE 做了一款微信小游戏合集(含一次完整架构重构)
前端·trae
不爱学英文的码字机器42 分钟前
从Q1迁到T1,同一个编号已经换了含义
前端·数据库·microsoft
云和数据.ChenGuang1 小时前
光哥说Python 循环导入(Circular Import)深度解析:成因、排查与解决方案
开发语言·前端·人工智能·python·langchain
avi91111 小时前
【AI教人】在Inspector显示所有Delegate-Odin Inspector之三
java·前端·算法·delegate·inspector·editor扩展·unity editor
fengci.1 小时前
BUUCTF(困难部分)
android·开发语言·前端·学习·php
Ward的AI产品实战1 小时前
开源 AI 网关 Magpie 调优终结篇:顺位排错、跨家族对抗审查与 5 大路由组重构(下篇)
前端·人工智能
Highcharts.js1 小时前
BI可视化图表“维护难”问题的解决方案
开发语言·前端·javascript·编辑器·ecmascript·bi·highcharts