-
启用
-
使用方法
-
模板渲染(选用nunjucks)
-
- 安装
-
启用与配置
-
使用方法
-
静态文件
-
Git规范
-
- 分支类型
-
分支命名
-
开发流程
-
提交格式
-
接口自测
-
- 软件
-
操作规范
-
RESTful API规范
-
- 请求协议
-
请求方法
-
状态码
-
- 成功状态码
-
错误状态码
-
服务器错误状态码
-
自定义状态码
-
版本号
-
URL规范
-
请求体格式
-
返回体格式
-
过滤、分页与排序
-
- 过滤
-
排序
-
分页
-
请求格式
===================================================================
项目默认编码格式统一为UTF-8格式,语法采用ES6+语法
注释符号后要有一个空格
函数/方法注释
函数/方法注释放置于函数/方法的上方,主要描述函数/方法功能以及参数类型,参数和返回值说明
/**
-
功能
-
@param {参数类型} 参数名 参数说明
-
@return {返回值类型} 返回值 返回值说明
*/
单行注释
对代码做简要说明
// 功能简要说明
每段代码应放在一个代码块中。块内的代码都应该统一地缩进一个单位。
使用空格作为缩进
使用2个空格作为一个缩进单位。
代码块符号
代码块的开始符号要放在行尾,不可单独一行;代码块结束符号要单独一行。
function demo() { // 代码块开始符号
// …} // 代码块结束符号
不同功能或多个代码块之间,使用空白行分隔
/**
- 方法1
*/function demo1() {
}
/**
- 方法2
*/function demo1() {
… // 代码块1
… // 代码块2}
全部使用英文单词
文件命名
-
控制器,模型,服务的文件名使用小写名词。
-
中间件使用下划线分割命名。
-
使用中间件使用将下划线命名改为首字母小写的驼峰命名。
-
控制器,服务的类名为首字母大写的文件名+Controller。
变量与常量命名
尽量使用const代替let
若变量需要改变才使用let
固定常量为全大写,其余使用首字母小写的驼峰命名法
函数/方法命名
使用首字母小写的驼峰命名
一般情况使用单引号,若字符串拼接,使用"``“和”${}"
不用分号
===================================================================
库的安装和项目的初始化全部使用npm
egg-init 项目名 --type=simple
npm install
$ npm i --save 库名
项目开发运行
$ npm run dev
项目部署运行
$ npm run start
项目docker运行
向package.json中的scripts键添加一个值
“scripts”: {
…
“docker”: “egg-sequelize db:migrate && egg-scripts start”,
…}
2.4 项目目录
├── app.js
├── app
│ ├── router.js
│ ├── controller
│ ├── extend
│ ├── middleware
│ ├── service
│ ├── public
│ ├── view
│ ├── router
│ ├── io (自建socket.io目录)
│ │ ├── middleware
│ │ └── controller
│ └── model (自建Sequelize目录)
├── config
│ ├── plugin.js
│ ├── config.default.js
│ └── config.prod.js
├── migrations(自建Sequelize目录)
├── logs
└── test
└── app
├── middleware
└── controller
以上目录约定如下:
1.app/router.js 用于配置URL路由规则。
2.app/controller/ 用于解析用户输入,处理后返回响应结果。
3.app/extend/ 用于框架内部对象的拓展(request,response,context,application)和工具类(helper)的编写。
4.app/middleware/ 用于编写中间件。
5.app/service/ 用于编写业务逻辑,如数据库操作的封装,api请求的封装等。
6.app/public/ 用于放置静态文件。
7.app/view/ 用于放置模板文件(可能不需要)。
8.app/model/ 用于放置数据模型(若使用Sequelize)。
9.app/router/ 用户放置分离的路由
10.migrations/ 用与放置数据库迁移的文件。
11.logs/ 日志存放目录。
12.test/ 测试文件目录。
13.app.js 用于自定义启动时的初始化工作。
所有代码均在’use strict’严格模式下开发
extend
包含四个对象对应的文件,以及一个helper工具类
1.代码格式
‘use strict’
module.exports = {
/**
-
方法说明
-
@param {参数类型} 参数名 参数说明
-
@return {返回值类型} 返回值名 返回值说明
*/
方法名(参数) {
// 处理逻辑
return 返回值
},
get 属性名() {
// 属性相关逻辑
return 属性
},
set 属性名(值) {
this.set(键, 值)
},}
2.application.js
对应Application对象
访问方式:
-
ctx.app
-
Controller, Helper, Service中都能使用this.app访问,例如this.app.config访问配置对象
-
Middleware中使用 ctx.app 访问
-
将app对象作为函数的第一个参数注入 module.exports = app => {}
3.context.js
对应context对象
访问方式:
-
middleware中this就是 ctx
-
controller中使用this.ctx访问
-
helper,service中使用this.ctx访问
4.request.js
对应request.js对象
访问方式:
- ctx.request
相关方法:
-
ctx.request.body 获取客户端请求的body参数
-
ctx.request.headers 获取客户端请求的header
-
ctx.request.query/ctx.query 获取URL内的参数
-
ctx.request.params 获取路由配置的参数
5.response.js
对应response.js对象
访问方式:
- ctx.response
相关方法:
- ctx.response.body/ctx.body 响应给客户端的body参数
6.helper.js
工具类,将请求成功和请求失败返回封装的函数以及错误码的封装写到里面
访问方式:
-
ctx.helper
-
若要在非请求状态下,调用ctx,比如service中使用ctx.helper,则使用以下方法
const { app } = this.ctx;const ctx = app.createAnonymousContext();
ctx.helper.ROOTURL //此变量即可调用
封装状态码,将其解释写在helper里,方便调用
module.exports = {
errorCode: {
200: ‘请求成功。客户端向服务器请求数据,服务器返回相关数据’,
201: ‘资源创建成功。客户端向服务器提供数据,服务器创建资源’,
202: ‘请求被接收。但处理尚未完成’,
204: ‘客户端告知服务器删除一个资源,服务器移除它’,
206: ‘请求成功。但是只有部分回应’,
400: ‘请求无效。数据不正确,请重试’,
401: ‘请求没有权限。缺少API token,无效或者超时’,
403: ‘用户得到授权,但是访问是被禁止的。’,
404: ‘发出的请求针对的是不存在的记录,服务器没有进行操作。’,
406: ‘请求失败。请求头部不一致,请重试’,
410: ‘请求的资源被永久删除,且不会再得到的。’,
422: ‘请求失败。请验证参数’,
500: ‘服务器发生错误,请检查服务器。’,
502: ‘网关错误。’,
503: ‘服务不可用,服务器暂时过载或维护。’,
504: ‘网关超时。’,
}}
在Controller中响应客户端时,使用
this.ctx.body = {
code: 400,
message: this.ctx.helper.errorCode[400],
data:{
error:‘err’
}}
封装请求成功的方法
module.exports= {
success: ({ ctx, code=200, res=null }) => {
ctx.status = 200
ctx.body = {
code: code,
message: ctx.helper.errorCode[code],
data: res
}
}}
封装请求失败的方法
module.exports = {
fail: ({ ctx, code=500, res=null }) => {
ctx.status = 200
ctx.body = {
code: code,
message: ctx.helper.errorCode[code],
data: {
error: res
}
}
}}
请求封装使用例子
ctx.helper.success({ ctx, code:200, res:‘success’ })
ctx.helper.fail({ ctx, code:500, res:‘fail’ })
配置文件
1.plugin.js
引入第三方插件
代码格式:
exports.插件名 = {
enable: true,
package: ‘库名’}
例如:
exports.jwt = {
enable: true,
package: ‘egg-jwt’}
2.config.{{env}}.js
访问方式:
-
this.app.config
-
this.config
代码格式:
‘use strict’
module.exports = appInfo => {
const config = exports = {}
// 全局变量
config.变量名=‘’
// 插件名
config.插件名= {
// 相关配置
}}
例如:
‘use strict’
module.exports = appInfo => {
const config = exports = {}
// redis 配置
config.redis = {
client: {
port: process.env.RS_PORT || 6379,
host: process.env.RS_HOST || ‘0.0.0.0’,
password: process.env.RS_PASSWORD || ‘’,
db: 0,
}
}}
-
默认配置放置在config.default.js,所有环境都会加载
-
本地环境使用config.local.js
-
开发环境使用config.prod.js
Middleware
中间件。对于一些错误拦截,请求处理,需要使用中间件完成。
配置方法:
- 文件名命名使用下划线分割,在config.{{env}}.js文件中的middleware中配置,使用的是驼峰方式配置
例如:中间件文件名为demo-middleware 在config.{{env}}.js中的配置
config.middleware = [‘demoMiddleware’]
- 在路由中配置,同样使用中间件时名称使用驼峰方式
例如:
module.exports = app => {
const demo = app.middleware.demoMiddleware()
app.router.get(‘/url’, demo, app.controller.demo)}
代码格式:
‘use strict’
module.exports = () => {
return async function 方法名(ctx, next) {
await next()
// 相关逻辑
}}
例如:
‘use strict’
module.exports = () => {
return async function notFoundHandler(ctx, next) {
await next()
if (ctx.status === 404 && !ctx.body) {
ctx.body = { error: ‘Not Found’ }
}
}}
处理错误信息的中间件
‘use strict’
module.exports = (option, app) => {
return async function(ctx, next) {
try {
await next()
} catch (err) {
app.emit(‘error’, err, this)
const status = err.status || 500
// 生产环境下不将错误内容返回给客户端
const error = status === 500 && app.config.env === ‘prod’
-
? ‘服务器错误,请联系管理员!’
- err.message
ctx.helper.fail({ctx, code:status, res:error})
if(status === 422) {
ctx.helper.fail({ctx, code:status, res:err.errors})
}
}
}}
Service
保持Controller中逻辑简洁,以及业务逻辑的独立性,抽象出的Service可以被多个Controller调用。比如封装数据库操作的方法,API请求封装,第三方服务调用等。
访问方式:
- this.service
Service支持多级目录,访问的时候可以通过目录名级联访问
-
app/service/biz/user.js => ctx.service.biz.user
-
app/service/sync_user.js => ctx.service.syncUser
-
app/service/HackerNews.js => ctx.service.hackerNews
代码格式(类的方式):
-
类名使用首字母大写的驼峰命名法
-
获取ctx,app,service,config,logger等对象使用const {对象} = this的方式获取
‘use strict’
const Service = require(‘egg’).Service
class 类名 extends Service {
/**
-
方法说明
-
@param {参数类型} 参数名 参数说明
-
@return {返回值类型} 返回值名 返回值说明
*/
async 方法名(参数名) {
// 方法逻辑
return 返回值
}}
方法例子如下:
/**
-
添加礼物
-
@param {string} livecode 编号
-
@return {int} giftnum 礼物数量
*/async addGift(livecode) {
const { app } = this
const giftnum = await this.ctx.model.query(UPDATE live SET gift=gift+1 WHERE livecode='${livecode}'
)
return giftnum}
Controller
三种功能,处理restful接口用户传来的参数;模板渲染;请求代理
访问方式:
- 可以支持多级目录,访问的时候可以通过目录名级联访问
例如:
-
app.controller.post.create() // 代码放在 app/controller/post.js
-
app.controller.sub.post.create() // 代码放在 app/controller/sub/post.js
代码格式(类的方式):
-
命名使用文件名首字母大写+Controller
-
获取ctx,app,service,config,logger等对象使用const {对象} = this的方式获取
‘use strict’
const Controller = require(‘egg’).Controller
class 首字母大写的文件名+Controller extends Controller {
async 方法名() {
// 相关逻辑
ctx.body = {
// 返回给restful api接口的请求者
}
}}
例如:
‘use strict’
const Controller = require(‘egg’).Controller
class HomeController extends Controller {
async index() {
const {ctx} = this
if(ctx.isAuthenticated) {
ctx.body = {
user: ctx.user
}
} else {
ctx.body = {
user: ‘fail’
}
}
}}
module.exports = HomeController
router.js路由文件
描述请求的URL与controller建立的联系。将各个路由分离开来,分别放入router文件夹,并在router.js中引入
代码格式:
‘use strict’
/**
- @param {Egg.Application} app - egg application
*/
module.exports = app => {
const { router, controller } = app
router.操作(‘/URL路径’, 中间件1, …中间件n, controller.文件名.方法) }
例如:
‘use strict’
/**
- @param {Egg.Application} app - egg application
*/
module.exports = app => {
const { router, controller } = app
const roleCheck = app.middleware.roleCheck()
router.get(‘/user’, app.jwt, roleCheck, controller.user.getAllUser)}
带参路由,两种形式,以及获取参数的方式:
1.使用形如/uri/:id的uri,在Controller中使用ctx.request.params获取 例如:
// router.js
router.get(‘/user/:id’, controller.user.info)
// controllerconst { ctx } = thisconst { id } = ctx.request.params
1.使用形如/uri?id=1&age=1的uri,在Controller中使用ctx.query获取 例如:
// router.js
router.get(‘/user?id=1&age=1’, controller.user.msg)
// controllerconst { ctx } = thisconst { id, age } = ctx.query
开发的时候关闭csrf,防止无法请求接口
// csrf关闭
config.security = {
csrf: {
enable: false
}}
安装
$ npm i -s egg-sequelize mysql2
启用与配置
在plugin.js中启用Sequlize
exports.sequelize = {
enable: true,
package: ‘egg-sequelize’}
在config.{{env}}.js中配置数据库连接.账户相关的信息,开发状态下将信息填入config.local.js;部署环境下,将信息填入config.prod.js
config.sequelize = {
dialect: ‘mysql’,
database: process.env.DB_DATABASE || ‘数据库名’,
host: process.env.DB_HOST || ‘IP地址’,
port: process.env.DB_PORT || ‘数据库端口号’,
username: process.env.DB_USER || ‘数据库用户名’,
password: process.env.DB_PASSWORD || ‘数据库密码’,
timezone: ‘+08:00’}
在package.json中配置数据库迁移命令
“scripts”: {
…
“migrate:new”: “egg-sequelize migration:create”,
“migrate:up”: “egg-sequelize db:migrate”,
“migrate:down”: “egg-sequelize db:migrate:undo”}
开发过程中配置自动同步数据库(仅开发模式),在app.js中写入
module.exports = app => {
if(app.config.env === ‘local’) {
app.beforeStart(async () => {
await app.model.sync({force:true})
})
}}
model数据模型开发
文档参考:https://demopark.github.io/sequelize-docs-Zh-CN/models-definition.html
-
文件名为表名
-
在文件前面引入需要的字段类型const {类型} = Sequelize
代码格式:
‘use strict’
module.exports = app => {
小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数初中级前端工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Web前端开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注:前端)
JavaScript 和 ES6
在这个过程你会发现,有很多 JS 知识点你并不能更好的理解为什么这么设计,以及这样设计的好处是什么,这就逼着让你去学习这单个知识点的来龙去脉,去哪学?第一,书籍,我知道你不喜欢看,我最近通过刷大厂面试题整理了一份前端核心知识笔记,比较书籍更精简,一句废话都没有,这份笔记也让我通过跳槽从8k涨成20k。
库密码’,
timezone: ‘+08:00’}
在package.json中配置数据库迁移命令
“scripts”: {
…
“migrate:new”: “egg-sequelize migration:create”,
“migrate:up”: “egg-sequelize db:migrate”,
“migrate:down”: “egg-sequelize db:migrate:undo”}
开发过程中配置自动同步数据库(仅开发模式),在app.js中写入
module.exports = app => {
if(app.config.env === ‘local’) {
app.beforeStart(async () => {
await app.model.sync({force:true})
})
}}
model数据模型开发
文档参考:https://demopark.github.io/sequelize-docs-Zh-CN/models-definition.html
-
文件名为表名
-
在文件前面引入需要的字段类型const {类型} = Sequelize
代码格式:
‘use strict’
module.exports = app => {
小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数初中级前端工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Web前端开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
[外链图片转存中…(img-XpE56nMQ-1710593077778)]
[外链图片转存中…(img-1zfI00Ri-1710593077779)]
[外链图片转存中…(img-zXtqY0qn-1710593077779)]
[外链图片转存中…(img-zZ86zsoL-1710593077779)]
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注:前端)
[外链图片转存中…(img-n5t8XVM3-1710593077780)]
JavaScript 和 ES6
在这个过程你会发现,有很多 JS 知识点你并不能更好的理解为什么这么设计,以及这样设计的好处是什么,这就逼着让你去学习这单个知识点的来龙去脉,去哪学?第一,书籍,我知道你不喜欢看,我最近通过刷大厂面试题整理了一份前端核心知识笔记,比较书籍更精简,一句废话都没有,这份笔记也让我通过跳槽从8k涨成20k。