最近实在太忙了,过个春节也不想多打字写文章,这边最近做了个 egglib
全栈框架,这个框架还包含一堆东西,概念以及多余的就不说了,就先用这个框架实现了一个 约定式路由
和 通过配置动态渲染界面
的功能,就记录一下这个整体方案实施方法和过程
点击 示例,查看完整效果
项目基于 eggjs 开发和运行,目录结构也比较简单
jrender-server
├─ config
│ ├─ config.default.js
│ ├─ config.local.js
│ └─ plugin.js
├─ pages
│ ├─ sample
│ │ ├─ detail
│ │ │ └─ [id].yaml
│ │ └─ list.yaml
│ └─ index.yaml
├─ README.md
├─ index.js
└─ package.json
主要有三个地方需要关注
config
config 文件夹用来定义 eggjs 的配置信息
config.default.js
module.exports = (appInfo) => {
const config = (exports = {})
config.keys = appInfo.name + "_1556156913732_2632"
// nunjucks 视图模板引擎定义
config.view = {
defaultViewEngine: "nunjucks",
mapping: {
".html": "nunjucks"
}
}
return config
}
config.local.js
本地开发用到的配置,线上环境用 config.prod.js
const path = require("path")
// 界面视图配置相关定义
exports.render = {
homePath: "*",
renderPath: "/egglib/render",
configDir: path.resolve(process.cwd(), "pages") // 重要:配置文件所在目录
}
这里的
configDir
定义了动态界面配置所在位置
plugin.js
module.exports = {
nunjucks: {
enable: true,
package: "egg-view-nunjucks"
},
// 静态界面的插件
"@egglib/statics": {
enable: true,
package: "@egglib/statics-vite"
},
// 动态渲染功能插件
"@egglib/render": {
enable: true
}
}
用到的 eggjs 插件
@egglib/statics
和@egglib/render
,是基于 egglib 已经开发好的功能插件,这里主要依靠这两个插件
pages
这个文件夹存放界面配置文件,是前面 configDir 定义的目录,这里所谓的 约定式路由
简单来讲就是路由的定义可以根据文件和目录结构来描述,用户在浏览器地址栏输入的 path 显示哪个页面可以对应到目录里的文件
目录结构和约定式路由的对应关系示例
目录 | 路由 |
---|---|
/index.yaml | /index |
/sample/list.yaml | /sample/index |
/sample/detail/[id].yaml | /sample/detail/<传入的 id 参数> |
/sample/[category]/detail/index.yaml | /sample/<传入的 category 参数>/detail/index |
通过
[参数名].yaml
或 /[参数名]/page.yaml 来定义带有参数的路由
示例比较简单,没做文件监听和进程更新,在 pages 目录里增加页面后需要重启一下服务,重新加载约定式路由
index.js
这个就是动 node 进程的入口文件,如果使用 egg-script
来启动 eggjs 服务,这个文件可以不定义
const egg = require('egg');
egg
.start({
workers: 1,
port: 3000,
mode: 'single',
})
.then((app) => {
app.listen(3000);
console.log('listen 3000');
})
.catch((err) => {
console.error(err);
});
关于动态渲染
根据配置文件动态渲染是基于 JRender 实现,定义规则参照 vue 的 render 函数吧,应该一看就能明白
使用数据绑定就参照这个项目里 README 里的示例,这个东西一直再重复搞加优化实在没时间长篇大论了,大概就是跟 这篇文章 类似,只不过那个是基于 vue3 的,本篇是基于 vue2(有个需求是兼容 ie11)