jianghu-init探索
120021、jianghu-init介绍
- jianghu-init是什么,解决什么问题
jianghu-init 是 JianghuJS 框架提供的命令行工具,通过jianghu-init可以快速生成一个符合 JianghuJS 的标准项目框架。它解决了以下主要问题:
快速初始化项目:
通过简单的命令,开发者可以快速初始化一个 JianghuJS 项目,无需手动创建项目结构和配置文件。标准化项目结构:
jianghu-init 提供了一个标准化的项目结构,确保了项目的一致性,有利于团队协作和项目维护。默认配置选项:
提供了一些默认配置选项,减少了配置的复杂性,同时保留了灵活性,开发者可以根据需要进行自定义配置。前后端一体化配置:
自动生成的项目框架集成了 Vuetify 前端页面模板和后端数据库配置,使得开发者可以迅速搭建一个整体的应用。减少学习曲线:
新加入的开发者可以通过 jianghu-init 快速获得标准的开发环境,降低了学习曲线,提高了项目的可维护性。JianghuJS项目-目录结构如下:
├── config # egg config
│ ├── config.default.js # default config
│ ├── config.local.js # npm run dev 时使用的 config
│ ├── config.prod.js # npm run start 时使用的 config
│ ├── config.unittest.js # npm run test 时使用的 config
│ └── plugin.js # egg插件配置
├── app
│ ├── common # 项目的常用工具、静态方法等
│ ├── constant # 常量
│ │ ├── constant.js
│ │ └── error.js
│ ├── controller # 对外暴露接口
│ ├── public # 静态资源目录
│ ├── schedule # 定时任务; 参考https://www.eggjs.org/zh-CN/basics/schedule
│ ├── service # 应用协议service目录
│ └── view # 页面存放目录
├── app.js # 自定义启动时的初始化工作
├── jsconfig.json
├── package.json
├── sql # sql文件
│ └── init.sql
└── upload
jianghu-init的使用
基础环境
操作系统:Windows/macOS/Linux
运行环境:Node.js v16.x
数据库环境:Mysql5.7+开发工具
开发工具: Vscode
数据库开发工具:navicat安装jianghu-init
# 卸载/卸载旧版 jianghu-init
$ npm uninstall -g jianghu-init
$ npm uninstall -g @jianghujs/jianghu-init
# 安装最新版本 jianghu-init
$ npm install -g @jianghujs/jianghu-init
# 查看版本
$ npm list @jianghujs/jianghu-init -g
运行jianghu-init
- 打开cmd,输入jianghu-init命令,选择你要创建的项目类型
- 选择后,输入你要创建的项目名称和指定路径
- 确认项目的名称和数据名称
- 确认数据库信息,创建项目成功
- 找到你新建的项目my-project,并用vscode打开,运行终端,安装依赖
- 确认Navicat里面,已经存在项目的数据库
- 按照好依赖,启动该项目,浏览器打开访问http://127.0.0.1:7001
- 输入用户名admin 密码123456
- 登录成功,你可以在这个项目上进行开发了!
2、案例:JianghuJS-服务端渲染
jianghujs-server-render
简介
server-render 主要演示如何将数据挂载到ctx上下文中,并通过模板引擎nunjucks渲染数据。在前后端分离的项目结构中,通常是发起请求调用接口获取所需数据,然后再渲染到页面。而server-render模式不发起获取数据的请求,而是在服务端将模板渲染完成后,将页面返回前端。服务器端渲染可以提高首次页面加载速度和SEO优化,一般用于需要SEO和内容型的网站。
- 浏览器演示
- 用户名:admin
- 密码:123456
项目总览
server-render项目包含以下页面:
- 文章管理
- 服务端渲染
本文主要以项目目录下的 jianghujs-server-render/app/view/page/home.html 为例,阐述服务端渲染的实现。
,文章管理相关的课程可以参考模板-高级-seo课程。
- 服务端渲染实现
- 在 _page 表中 pageHook 字段下绑定 service 方法并定义模板中要使用的变量名
//home 的 pageHook 下,我们绑定了两个 service 方法
{
"beforeHook":[
// 在页面渲染的时候,会调用 njk service 中的 test 方法
{"service": "njk", "serviceFunc": "test"},
// 在页面渲染的时候,会调用 article service 中的 getCategoryListAndArticleList 方法,并将数据绑定到 categoryList 变量
{"templateVar": "categoryList", "service": "article", "serviceFunc": "getCategoryListAndArticleList"}
]
}
- service 中实现 _page 表中 pageHook 字段下定义的方法
//njk service 中实现 test 方法
class NjkService extends Service {
async test() {
this.ctx.seo = this.ctx.seo || {}
this.ctx.seo.article = {
string: '服务端渲染 Demo',
};
}
}
module.exports = NjkService;
//article service 中实现 getCategoryListAndArticleList 方法
class ArticleService extends Service {
async getCategoryListAndArticleList() {
const {ctx, app} = this;
const {jianghuKnex} = app;
let categoryList = await jianghuKnex(tableEnum.view01_category).select('categoryId', 'categoryName');
return categoryList;
}
}
module.exports = ArticleService;
- 在 home.html 中使用 service 返回的数据
//使用 njk service 中在 ctx 上下文中定义的数据
<div><$ ctx.seo.article.string $></div>
//使用 article service 中返回的数据,该数据绑定到了 categoryList 变量
{% for item in categoryList %}
<div><$ item.categoryName $></div>
{% endfor %}
3、案例:JianghuJS-页面二次认证
- 页面二次认证的用处
通过在页面上设置密码(passcode),增强了页面的安全性。用户访问设置了密码的页面时,需要输入正确的密码,才能正常访问页面,否则无法访问。用户输入正确密码后,一段时间内不需要再次输入密码认证。该时间长度可通过修改页面上的配置来调整。
为页面配置二次认证
数据库修改
结构修改:在数据库
_page
表中增加一列:passcode
,数据类型为VARCHAR(255)
。ALTER TABLE `_page` ADD COLUMN `passcode` varchar(255) NULL COMMENT '页面二次认证; passcode ' AFTER `sort`;
为页面配置密码:在
_page
表中,找到要添加密码的页面,在passcode
字段中输入密码,并保存。
注意:若
passcode
字段密码为空,则等同于该页面没有设置密码。
- 页面加入组件
- 添加组件文件:
在项目文件夹中创建/app/view/component/pagePasscodeValidation.html
页面引入组件:
在项目文件夹/app/page/password.html
引入pagePasscodeValidation
组件{% include 'component/pagePasscodeValidation.html' %}
在页面HTML部分中,增加以下组件:
<page-passcode-validation validation-duration-hour="1"></page-passcode-validation>
其中,
validation-duration-hour
是当前密码认证的有效期,以小时计算。修改此数值即可调整密码认证的有效期。存储&校验逻辑
设置校验时间缓存
let pageValidationObj = {}
try {
const pageValidationObjStr = localStorage.getItem(`${window.appInfo.appId}_page_validation_obj`);
pageValidationObj = JSON.parse(pageValidationObjStr || '{}');
} catch (error) {
console.error("[cachePageValidation]", "json 数据异常");
}
pageValidationObj[pageId] = value;
localStorage.setItem(`${window.appInfo.appId}_page_validation_obj`, JSON.stringify(pageValidationObj));
校验认证信息
if (this.passcodeOfUser !== this.passcodeOfServer) {
window.vtoast.fail({message: '页面认证失败'});
}
if (this.passcodeOfUser === this.passcodeOfServer) {
this.cachePageValidation({
pageId: this.pageId,
value: {
pageId: this.pageId,
date: dayjs(),
success: true,
}
});
this.isPageValidationDialogShown = false;
}