本文是《大前端全栈实践》学习实践的总结,参考自抖音"哲玄前端"老师的课程内容,在此基础上进行了深度思考与实践。
一、背景与目标
在完成了前四个里程碑的开发后,随着功能模块的增加,业务逻辑与底层架构代码混杂在一起,导致核心架构难以复用。
里程碑五的核心目标是 "业务分离" 。
方案:封装npm包,抽离业务代码。
二、业务分离
我们将项目拆解为两个部分:
- 框架层 (@dobym/elpis) :负责底层驱动,包括 Koa 实例创建、环境识别、自动加载器(Loader)、基础组件库等。
- 业务层 (用户Project) :负责具体业务,遵循框架约定的目录结构编写 Controller、Service 和 Config以及自定义Components。
业务目录结构约定
框架采用了约定优于配置的设计理念。只要业务层按照以下结构组织代码,框架就能自动识别并加载:
js
Project/
├── app/
│ ├── controller/ # 业务逻辑控制器
│ ├── service/ # 业务逻辑服务层
│ ├── middleware/ # 业务中间件
│ ├── pages/ # 业务页面
│ ├── dashboard/ # 业务启动页面
│ ├── widgets/ # 业务自定义动态组件
│ ├── router/ # 路由定义
│ └── router-schema/ # 参数校验Schema
├── webpack.config.js # webpack配置
├── middleware.js # 全局中间件调用
├── config/ # 配置文件
│ ├── config.default.js
│ └── config.local.js
├── model/ # DSL文件
├── index.js # 入口文件
└── package.json
三、核心实现
框架的核心在于Loader(加载器) 。它利用 Node.js 的模块系统和文件系统能力(如 glob),自动扫描指定目录并挂载到 app 实例上。
3.1 elpis-core统一入口
js
// elpis-core/index.js
start(options = {}) {
const app = new Koa();
// 确定业务代码根路径
app.businessPath = path.resolve(process.cwd(), './app');
// 按顺序加载核心模块
app.env = env(); // 环境识别
middlewareLoader(app); // 中间件加载
routerSchemaLoader(app); // 参数校验加载
controllerLoader(app); // 控制器加载
serviceLoader(app); // 服务层加载
configLoader(app); // 配置加载
// 注册elpis全局中间件
const elpisMiddlewarePath = path.resolve(__dirname, `..${sep}app${sep}middleware.js`)
const elpisMiddleware = require(elpisMiddlewarePath)
elpisMiddleware(app)
// 注册业务全局中间件
try {
require(`${app.businessPath}${sep}middleware.js`)(app)
console.log(`-- [start] load global bussiness middleware file -- `);
} catch (error) {
}
// 注册路由
routerLoader(app) // 路由加载器
// ...最后启动elpis框架服务
app.listen(port);
}
3.2 npm包入口index.js
npm包供用户真正调用的文件
js
// index.js
// 引入elpis-core
const ElpisCore = require('./elpis-core')
// 引入前端工程化构建方法
const FEBuildDev = require('./app/webpack/dev.js')
const FEBuildProd = require('./app/webpack/prod.js')
module.exports = {
/**
* 服务端基础
*/
Controller: {
Base: require('./app/controller/base.js')
},
Service: {
Base: require('./app/service/base.js')
},
/**
* 编译构建前端工程
* @params env 环境变量 dev/prod
*/
frontendBuild(env) {
if (env === 'local') {
FEBuildDev()
} else if (env === 'production') {
FEBuildProd()
}
},
/**
* 启动elpis
* @params options 项目配置,透传到elpis-core
*/
serverStart(options = {}) {
return ElpisCore.start(options)
}
}
四、总结
里程碑五的完成,标志着 Elpis 从一个单一的练手项目,进化为一个可复用的企业级 Node.js 开发框架。
通过将通用逻辑抽离为 npm 包 (@dobym/elpis),我们不仅解耦了代码,更重要的是确立了一套开发规范。未来的微服务或新功能模块,都可以基于此框架快速构建,真正实现了"提质增效"。